{"version":3,"file":"static/js/index.2e8227be.js","sources":["webpack://gvirantd/./src/common/casl/ability.js","webpack://gvirantd/./src/common/components/advanced-search/AdvancedSearchTitle.js","webpack://gvirantd/./src/common/components/advanced-search/ModalUploadAdvancedFile.js","webpack://gvirantd/./src/common/components/ag-grid/components/renderers/LinkRender.js","webpack://gvirantd/./src/common/components/ag-grid/components/renderers/DragRender.js","webpack://gvirantd/./src/common/components/ag-grid/components/renderers/CheckboxSelectionRender.js","webpack://gvirantd/./src/common/components/ag-grid/context/gridContext.js","webpack://gvirantd/./src/common/components/ag-grid/components/renderers/HeaderCheckboxRender.js","webpack://gvirantd/./src/common/components/ag-grid/components/renderers/HeaderNullRender.js","webpack://gvirantd/./src/common/components/ag-grid/components/renderers/CheckboxRender.js","webpack://gvirantd/./src/common/components/ag-grid/components/ApplyFilter.js","webpack://gvirantd/./src/common/components/ag-grid/hooks/getColumnDefsHook.js","webpack://gvirantd/./src/common/components/ag-grid/hooks/SelectionHook.js","webpack://gvirantd/./src/common/components/ag-grid/components/selection/SelectionLog.js","webpack://gvirantd/./src/common/components/ag-grid/AgGrid.js","webpack://gvirantd/./src/common/components/ag-grid/LicenseManagerAgGrid.js","webpack://gvirantd/./src/common/components/apl-grid/AplGrid.js","webpack://gvirantd/./src/common/components/button/ButtonLargeIcon.js","webpack://gvirantd/./src/common/components/button/ButtonSmallIcon.js","webpack://gvirantd/./src/common/components/button/ContainerButton.js","webpack://gvirantd/./src/common/components/button/ItemButton.js","webpack://gvirantd/./src/common/components/button/RibbonButton.js","webpack://gvirantd/./src/common/components/button/ShowMoreOrLess.js","webpack://gvirantd/./src/common/components/contact-action/ActionsRibbonBar.js","webpack://gvirantd/./src/common/components/dialog-function/DialogFunction.js","webpack://gvirantd/./src/common/components/dialog-function/ErrorIcon.js","webpack://gvirantd/./src/common/components/dialog-function/InfoIcon.js","webpack://gvirantd/./src/common/components/dialog-function/SuccessIcon.js","webpack://gvirantd/./src/common/components/dialog-function/WarnIcon.js","webpack://gvirantd/./src/common/components/digital-right-icon/DigitalRightIcon.js","webpack://gvirantd/./src/common/components/drapDropWrap/drap-and-drop/DropWrap.js","webpack://gvirantd/./src/common/components/folder/FolderTree.js","webpack://gvirantd/./src/common/components/folder/hooks.js","webpack://gvirantd/./src/common/components/folder/FolderBreadcrumb.js","webpack://gvirantd/./src/common/components/folder/FolderItem.js","webpack://gvirantd/./src/common/components/folder/FolderList.js","webpack://gvirantd/./src/common/components/folder/FolderSelector.js","webpack://gvirantd/./src/common/components/folder/utils.js","webpack://gvirantd/./src/common/components/form/basic-form/BasicFormItem.js","webpack://gvirantd/./src/common/components/form/basic-form/BasicFormItemList.js","webpack://gvirantd/./src/common/components/grid-view/DisplayTotalItem.js","webpack://gvirantd/./src/common/components/grid-view/components/abandon-dialog/AbandonDialog.js","webpack://gvirantd/./src/common/components/grid-view/components/add-to-folder/AddToFolderActions.js","webpack://gvirantd/./src/common/components/grid-view/components/content-pane/ContentPane.js","webpack://gvirantd/./src/common/components/grid-view/components/content-pane/advancedFilter/PropertyAdvancedFilter.js","webpack://gvirantd/./src/common/components/grid-view/components/content-pane/advancedFilter/QueryConditions.js","webpack://gvirantd/./src/common/components/grid-view/components/content-pane/advancedFilter/utils.js","webpack://gvirantd/./src/common/components/grid-view/components/list-grid/ListGrid.js","webpack://gvirantd/./src/common/components/grid-view/components/tile-grid/TileGrid.js","webpack://gvirantd/./src/common/components/grid-view/components/add-to-folder/AddToFolder.js","webpack://gvirantd/./src/common/components/grid-view/components/search-categories/SearchCategories.js","webpack://gvirantd/./src/common/components/grid-view/controllers/actions.js","webpack://gvirantd/./src/common/components/grid-view/controllers/constants.js","webpack://gvirantd/./src/common/components/grid-view/controllers/reducer.js","webpack://gvirantd/./src/common/components/grid-view/controllers/saga.js","webpack://gvirantd/./src/common/components/grid-view/controllers/selectors.js","webpack://gvirantd/./src/common/components/grid-view/utils.js","webpack://gvirantd/./src/common/components/icon-list/IconItem.js","webpack://gvirantd/./src/common/components/icon-list/IconList.js","webpack://gvirantd/./src/assets/classifications/automotive_icon.svg","webpack://gvirantd/./src/assets/classifications/camping_icon.svg","webpack://gvirantd/./src/assets/classifications/crops_icon.svg","webpack://gvirantd/./src/assets/classifications/food_beverage_tobacco.svg","webpack://gvirantd/./src/assets/classifications/footwear_icon.svg","webpack://gvirantd/./src/assets/classifications/home_appliances.svg","webpack://gvirantd/./src/assets/classifications/horticulture_plants.svg","webpack://gvirantd/./src/assets/classifications/lawn_garden_supplies.svg","webpack://gvirantd/./src/assets/classifications/live_animals.svg","webpack://gvirantd/./src/assets/classifications/personal_accessories.svg","webpack://gvirantd/./src/assets/classifications/pet-food.svg","webpack://gvirantd/./src/assets/classifications/power_equipment.svg","webpack://gvirantd/./src/assets/classifications/services_icon.svg","webpack://gvirantd/./src/assets/classifications/workshop_aids.svg","webpack://gvirantd/./src/assets/classifications/toy_icon.svg","webpack://gvirantd/./src/common/components/icon-list/assets.js","webpack://gvirantd/./src/assets/classifications/arts_crafts_needlework.svg","webpack://gvirantd/./src/assets/classifications/audio_visual_photography.svg","webpack://gvirantd/./src/assets/classifications/beauty_personal_care_hygiene.svg","webpack://gvirantd/./src/assets/classifications/building_products.svg","webpack://gvirantd/./src/assets/classifications/cleaning_hygiene_products.svg","webpack://gvirantd/./src/assets/classifications/clothing_icon.svg","webpack://gvirantd/./src/assets/classifications/communication_icon.svg","webpack://gvirantd/./src/assets/classifications/computing_icon.svg","webpack://gvirantd/./src/assets/classifications/cross_segment.svg","webpack://gvirantd/./src/assets/classifications/electrical_supplies.svg","webpack://gvirantd/./src/assets/classifications/fuels_gases.svg","webpack://gvirantd/./src/assets/classifications/healthcare_icon.svg","webpack://gvirantd/./src/assets/classifications/household_office_furniture_furnishings.svg","webpack://gvirantd/./src/assets/classifications/kitchenware_and_tableware.svg","webpack://gvirantd/./src/assets/classifications/lubricant_icon.svg","webpack://gvirantd/./src/assets/classifications/monetary_assets.svg","webpack://gvirantd/./src/assets/classifications/music_icon.svg","webpack://gvirantd/./src/assets/classifications/heating_icon.svg","webpack://gvirantd/./src/assets/classifications/safety_protection.svg","webpack://gvirantd/./src/assets/classifications/safety_security.svg","webpack://gvirantd/./src/assets/classifications/sports_equipment.svg","webpack://gvirantd/./src/assets/classifications/office_machinery.svg","webpack://gvirantd/./src/assets/classifications/storage_icon.svg","webpack://gvirantd/./src/assets/classifications/textual_print_material.svg","webpack://gvirantd/./src/assets/classifications/hand_equipment.svg","webpack://gvirantd/./src/common/components/icon-renderer/IconRenderer.js","webpack://gvirantd/./src/common/components/icon-renderer/IconRendererMapping.js","webpack://gvirantd/./src/assets/locations/hq.svg","webpack://gvirantd/./src/assets/locations/billing.svg","webpack://gvirantd/./src/assets/locations/office.svg","webpack://gvirantd/./src/assets/locations/factory.svg","webpack://gvirantd/./src/assets/locations/store.svg","webpack://gvirantd/./src/assets/locations/shipping.svg","webpack://gvirantd/./src/assets/locations/warehouse.svg","webpack://gvirantd/./src/common/components/image/Image.js","webpack://gvirantd/./src/common/components/arrangeable-layout/ArrangeableLayout.js","webpack://gvirantd/./src/common/components/message/components/chat-thread/ChatThread.js","webpack://gvirantd/./src/common/components/message/components/chat-header/ChatSearchMessages.js","webpack://gvirantd/./src/common/components/mail/components/search/EmailSearchMessage.js","webpack://gvirantd/./src/common/components/mail/components/thread/EmailThreadInfo.js","webpack://gvirantd/./src/common/components/email-editor/index.js","webpack://gvirantd/./src/common/components/message/Chat.js","webpack://gvirantd/./src/common/components/mail/Email.js","webpack://gvirantd/./src/common/components/dropdown/SelectLocale.js","webpack://gvirantd/./src/common/components/layout/Footer.js","webpack://gvirantd/./src/common/components/layout/Header.js","webpack://gvirantd/./src/common/components/text/Counter.js","webpack://gvirantd/./src/common/components/empty-view/EmptyList.js","webpack://gvirantd/./src/common/components/wrapper/WithAbility.js","webpack://gvirantd/./src/common/components/wrapper/WithHelmet.js","webpack://gvirantd/./src/common/components/wrapper/WithAbsoluteContainer.js","webpack://gvirantd/./src/common/components/wrapper/WithReloadInternalData.js","webpack://gvirantd/./src/common/components/button/VerticalButton.js","webpack://gvirantd/./src/common/components/button/delete-button/DeleteButton.js","webpack://gvirantd/./src/common/components/button/FormSaveButton.js","webpack://gvirantd/./src/common/components/button/FormAddButton.js","webpack://gvirantd/./src/common/components/button/FormEditButton.js","webpack://gvirantd/./src/common/components/button/FormCancelButton.js","webpack://gvirantd/./src/common/components/button/FormCreateButton.js","webpack://gvirantd/./src/common/components/button/FormDeleteButton.js","webpack://gvirantd/./src/common/components/button/FormButton.js","webpack://gvirantd/./src/common/components/button/EditButton.js","webpack://gvirantd/./src/common/components/button/SwitchButton.js","webpack://gvirantd/./src/common/components/button/CopyButton.js","webpack://gvirantd/./src/common/components/button/ReGenerateButton.js","webpack://gvirantd/./src/common/components/button/ShowHideButton.js","webpack://gvirantd/./src/common/components/button/BoldTextButton.js","webpack://gvirantd/./src/common/components/button/GeneralButton.js","webpack://gvirantd/./src/common/components/button/BorderButton.js","webpack://gvirantd/./src/hooks/useUploadModal.js","webpack://gvirantd/./src/common/components/uploadFile/UploadFileModal.js","webpack://gvirantd/./src/common/components/grid-view/mappers/mapToDragColumndef.js","webpack://gvirantd/./src/common/components/grid-view/components/content-pane/advancedFilter/RenderAdvancedFilter.js","webpack://gvirantd/./src/common/components/grid-view/components/content-pane/advancedFilter/AdvanceFilterPanel.js","webpack://gvirantd/./src/common/components/grid-view/GridView.js","webpack://gvirantd/./src/common/components/ag-grid/AgGridClient.js","webpack://gvirantd/./src/common/components/ag-grid/AgGridThumbnail.js","webpack://gvirantd/./src/common/components/ag-grid/components/AgGridIcons.js","webpack://gvirantd/./src/common/components/textarea/Textarea.js","webpack://gvirantd/./src/common/components/slickslider/text-slick-slider/TextSlickSlider.js","webpack://gvirantd/./src/common/components/ag-grid/components/WithAggridHeaderEdit.js","webpack://gvirantd/./src/i18n/messages/message-ag-grid.js","webpack://gvirantd/./src/common/components/ag-grid/components/AgGridDownloadOptions.js","webpack://gvirantd/./src/i18n/messages/logoAsset.js","webpack://gvirantd/./src/common/components/modal-edit-logo/LogoAssetGrid.js","webpack://gvirantd/./src/common/components/modal-edit-logo/EditLogoModal.js","webpack://gvirantd/./src/common/components/image/ProfileImage.js","webpack://gvirantd/./src/common/components/profile-address/ProfileAddress.js","webpack://gvirantd/./src/common/components/contact-action/ContactActions.js","webpack://gvirantd/./src/common/components/info-with-label/InfoWithLabel.js","webpack://gvirantd/./src/common/components/textarea-grid/TextAreaGrid.js","webpack://gvirantd/./src/common/components/tab-layout/TabLayout.js","webpack://gvirantd/./src/common/components/badge/Action.js","webpack://gvirantd/./src/common/components/badge/Chat.js","webpack://gvirantd/./src/common/components/badge/Task.js","webpack://gvirantd/./src/common/components/badge/constants.js","webpack://gvirantd/./src/common/components/badge/Email.js","webpack://gvirantd/./src/common/components/cropImage/CropImage.js","webpack://gvirantd/./src/common/components/history/HistorySection.js","webpack://gvirantd/./src/common/components/history/ProfileContactHistory.js","webpack://gvirantd/./src/common/components/tooltip/TooltipParagraph.js","webpack://gvirantd/./src/common/components/member-grid/MemberGlnList.js","webpack://gvirantd/./src/common/components/tooltip/GlnTooltip.js","webpack://gvirantd/./src/static/DownloadMethod.js","webpack://gvirantd/./src/common/components/type-picker/TypePicker.js","webpack://gvirantd/./src/common/components/service-type/ServiceTypeMapping.js","webpack://gvirantd/./src/common/components/service-type/ServiceType.js","webpack://gvirantd/./src/common/components/label-value-wrapper/LabelValueWrapper.js","webpack://gvirantd/./src/common/components/iframe-preview/IframePreview.js","webpack://gvirantd/./src/common/components/color-picker/ColorPicker.js","webpack://gvirantd/./src/common/components/dialog-function/DialogOkFunction.js","webpack://gvirantd/./src/common/components/dialog-function/DialogModal.js","webpack://gvirantd/./src/common/components/markdown/markdownRenderers/TextRender.js","webpack://gvirantd/./src/common/components/markdown/markdownRenderers/TableRender.js","webpack://gvirantd/./src/common/components/markdown/mdMedia/MdImage.js","webpack://gvirantd/./src/common/components/markdown/mdMedia/MdVideo.js","webpack://gvirantd/./src/common/components/markdown/mdMedia/MdYoutube.js","webpack://gvirantd/./src/common/components/markdown/markdownRenderers/ImageRender.js","webpack://gvirantd/./src/common/components/markdown/markdownRenderers/ParagraphRender.js","webpack://gvirantd/./src/common/components/markdown/markdownRenderers/HeadingRender.js","webpack://gvirantd/./src/common/components/markdown/EnhancedMarkdown.js","webpack://gvirantd/./src/services/templateMarkdown/index.js","webpack://gvirantd/./src/services/templateMarkdown/endpoints.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/entity/MdEntityTool.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/entity/MdEditInterEntity.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/entity/MdInterEntityTool.js","webpack://gvirantd/./src/common/components/markdown/EnhancedMarkdownEditor.js","webpack://gvirantd/./src/common/components/markdown/uploadMedia/components/mdCustomMediaModal/MarkdownGroupInput.js","webpack://gvirantd/./src/common/components/markdown/uploadMedia/components/mdCustomMediaModal/MarkdownMediaCustomModal.js","webpack://gvirantd/./src/common/components/markdown/uploadMedia/components/mdUploadIMediaItem/MarkdownUploadItem.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/text/MdTextFont.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/text/MdToolTextColor.js","webpack://gvirantd/./src/common/components/markdown/uploadMedia/components/mdMediaCustomPreview/MarkdownAddParagraph.js","webpack://gvirantd/./src/common/components/markdown/uploadMedia/components/mdMediaCustomPreview/ParagraphConfigTag.js","webpack://gvirantd/./src/common/components/markdown/uploadMedia/components/mdMediaCustomPreview/MarkdownMediaCustomPreview.js","webpack://gvirantd/./src/common/components/markdown/uploadMedia/MarkdownUploadMedia.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/text/MdTextSize.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/text/MdToolTypeAndFont.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/text/MdToolTextSampleSyntax.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/text/MdToolTextGuideAndResult.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/text/MdToolText.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/table/MdTableEditToolbar.js","webpack://gvirantd/./src/utils/input.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/table/MdTableEdit.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/table/MdToolbarTable.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/table/MdTableList.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/table/MdToolTable.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/components/shortcode/MdCCEula.js","webpack://gvirantd/./src/common/components/markdown/customToolbar/MdEditorCustomToolbar.js","webpack://gvirantd/./src/common/components/modal-add-to-folder/ModalAddToFolder.js","webpack://gvirantd/./src/common/components/modal-share/ShareModal.js","webpack://gvirantd/./src/common/components/modal-share/ShareMappingModal.js","webpack://gvirantd/./src/common/components/contact-card/ContactCardUserInfo.js","webpack://gvirantd/./src/common/components/contact-card/ContactCardContactItem.js","webpack://gvirantd/./src/common/components/contact-card/ContactCardContactInfo.js","webpack://gvirantd/./src/common/components/contact-card/ContactCard.js","webpack://gvirantd/./src/common/components/modal-contact-card/ContactCardModal.js","webpack://gvirantd/./src/common/components/anonymous-view/AnonLogin.js","webpack://gvirantd/./src/common/components/anonymous-view/AnonViewWrap.js","webpack://gvirantd/./src/common/components/notification/CustomNotification.js","webpack://gvirantd/./src/common/components/modal-logo-assets/LogoAssetModal.js","webpack://gvirantd/./src/common/components/email-selection/EmailSelection.js","webpack://gvirantd/./src/common/components/backgroundEdit/BackgroundImageEdit.js","webpack://gvirantd/./src/common/components/form/Form.js","webpack://gvirantd/./src/common/components/form/tagInput/TagInput.js","webpack://gvirantd/./src/common/components/form/saveCancelGroup/SaveCancelGroup.js","webpack://gvirantd/./src/common/components/form/slider-number/SliderNumber.js","webpack://gvirantd/./src/common/components/form/avatar-tag-autocomplete/components/AvatarTagItem.js","webpack://gvirantd/./src/common/components/form/avatar-tag-autocomplete/components/InputAutoHintList.js","webpack://gvirantd/./src/common/components/form/avatar-tag-autocomplete/index.js","webpack://gvirantd/./src/common/components/form/step-form/index.js","webpack://gvirantd/./src/common/components/form/use-form/useFormHook.js","webpack://gvirantd/./src/common/components/form/form-input-html/FormInputHtml.js","webpack://gvirantd/./src/common/components/form/member-select-input/MemberSelectInput.js","webpack://gvirantd/./src/common/components/form/containers/vertical-split-form-row/index.js","webpack://gvirantd/./src/common/components/form/three-state-checkbox-field-input/ThreeStateCheckboxFieldInput.js","webpack://gvirantd/./src/common/components/form/flag-country-selection-field-input/FlagCountrySelectionFieldInput.js","webpack://gvirantd/./src/common/components/input/NumberTextInput.js","webpack://gvirantd/./src/common/components/form/NewPasswordFormItem.js","webpack://gvirantd/./src/common/components/tag/squareTag/SquareTag.js","webpack://gvirantd/./src/common/components/tag/helpCenterTag/HelpCenterTagItem.js","webpack://gvirantd/./src/common/components/tag/helpCenterTag/HelpCenterTag.js","webpack://gvirantd/./src/common/components/button/modal/CloseModalBtn.js","webpack://gvirantd/./src/common/components/drapDropWrap/drap-and-drop/DrapWrap.js","webpack://gvirantd/./src/common/components/drapDropWrap/drap-and-drop/utils/mapGridViewDataToDragData.js","webpack://gvirantd/./src/common/components/drapDropWrap/drag-drop-pos/context/DragContext.js","webpack://gvirantd/./src/common/components/drapDropWrap/drag-drop-pos/hooks/useDrapDropHooks.js","webpack://gvirantd/./src/common/components/drapDropWrap/drag-drop-pos/hooks/useClickOuterDrag.js","webpack://gvirantd/./src/common/components/drapDropWrap/drag-drop-pos/index.js","webpack://gvirantd/./src/common/components/message/components/searchInput/ChatSearchInput.js","webpack://gvirantd/./src/common/components/message/controller/selectors.js","webpack://gvirantd/./src/common/components/mail/controller/mapToReducerState/index.js","webpack://gvirantd/./src/common/components/mail/controller/reducer.js","webpack://gvirantd/./src/common/components/mail/controller/selectors.js","webpack://gvirantd/./src/common/components/message/components/fields/SwitchAccount.js","webpack://gvirantd/./src/hooks/useClickEntity.js","webpack://gvirantd/./src/services/email/index.js","webpack://gvirantd/./src/services/email/endpoints.js","webpack://gvirantd/./src/common/components/message/components/fields/utils.js","webpack://gvirantd/./src/common/components/message/components/fields/hooks.js","webpack://gvirantd/./src/common/components/message/mapper/mapInnerHtmlToText.js","webpack://gvirantd/./src/common/components/message/components/fields/ChatInputBar.js","webpack://gvirantd/./src/common/components/message/mapper/mapFileTypeToPreviewFile.js","webpack://gvirantd/./src/common/components/message/components/attachList/AttachFile.js","webpack://gvirantd/./src/common/components/message/components/attachList/AttachList.js","webpack://gvirantd/./src/hooks/useCheckSenderAccount.js","webpack://gvirantd/./src/common/components/contact-card/messages/ContactCardMessageItem.js","webpack://gvirantd/./src/common/components/contact-card/messages/ContactCardMessageInfo.js","webpack://gvirantd/./src/common/components/contact-card/messages/ContactCardMessageActions.js","webpack://gvirantd/./src/common/components/mail/mapper/mapEmailsWithAttachUrl.js","webpack://gvirantd/./src/common/components/mail/controller/saga.js","webpack://gvirantd/./src/hooks/useSendMessageOrEmail.js","webpack://gvirantd/./src/common/components/contact-card/messages/ContactCardMessages.js","webpack://gvirantd/./src/common/components/message/components/chat-thread/ChatImageFile.js","webpack://gvirantd/./src/common/components/message/components/chat-thread/ChatFile.js","webpack://gvirantd/./src/common/components/message/components/chat-thread/ChatMessage.js","webpack://gvirantd/./src/common/components/message/components/chat-thread/VideoMessage.js","webpack://gvirantd/./src/common/components/message/components/chat-thread/ChatSpeech.js","webpack://gvirantd/./src/common/components/message/components/chat-thread/ChatMail.js","webpack://gvirantd/./src/common/components/message/components/chat-thread/ChatTurnItem.js","webpack://gvirantd/./src/common/components/message/components/chat-thread/ChatTurnList.js","webpack://gvirantd/./src/common/components/message/components/chat-header/HeaderFilter.js","webpack://gvirantd/./src/i18n/messages/chat.js","webpack://gvirantd/./src/common/components/message/components/chat-header/UpdateAvatarModal.js","webpack://gvirantd/./src/common/components/message/components/chat-header/UpdateThreadNameForm.js","webpack://gvirantd/./src/common/components/message/components/chat-header/SearchResultItem.js","webpack://gvirantd/./src/common/components/message/components/button/SearchMessageButton.js","webpack://gvirantd/./src/common/components/message/ui/MaximizeChatView/GroupCompanyDelete.js","webpack://gvirantd/./src/common/components/message/ui/MaximizeChatView/GroupPeopleDelete.js","webpack://gvirantd/./src/common/components/message/components/modal/ThreadUserList.js","webpack://gvirantd/./src/common/components/message/components/modal/ThreadInfoModal.js","webpack://gvirantd/./src/common/components/message/components/chat-header/ChatHeader.js","webpack://gvirantd/./src/common/components/message/components/chat-minimized/ChatMinimizeItem.js","webpack://gvirantd/./src/common/components/message/components/chat-minimized/ChatMinimizeList.js","webpack://gvirantd/./src/common/components/message/components/newChatModal/NewChatSearchBar.js","webpack://gvirantd/./src/common/components/message/components/msg/NewMsgReceive.js","webpack://gvirantd/./src/common/components/message/components/chat-content-header/ChatContentHeader.js","webpack://gvirantd/./src/common/components/message/components/button/ScrollButton.js","webpack://gvirantd/./src/common/components/message/controller/hooks.js","webpack://gvirantd/./src/common/components/message/ui/communication/Thread.js","webpack://gvirantd/./src/common/components/message/ui/MaximizeChatView/GroupPeopleCreate.js","webpack://gvirantd/./src/common/components/message/ui/MaximizeChatView/GroupCompanyCreate.js","webpack://gvirantd/./src/common/components/message/ui/MaximizeChatView/CreateNewThreadModal.js","webpack://gvirantd/./src/common/components/message/ui/MaximizeChatView/CreateNewThreadPrivate.js","webpack://gvirantd/./src/common/components/message/ui/MaximizeChatView/AddRemoveThreadModal.js","webpack://gvirantd/./src/common/components/videoCall/loading/VideoLoading.js","webpack://gvirantd/./src/common/components/videoCall/jitsi-frame/JitsiFrame.js","webpack://gvirantd/./src/common/components/videoCall/jitsi-frame/DisableFrame.js","webpack://gvirantd/./src/common/components/videoCall/branding/VideoCallBranding.js","webpack://gvirantd/./src/common/components/videoCall/button/VideoToolBtnWrap.js","webpack://gvirantd/./src/common/components/icon/ShareScreen.svg","webpack://gvirantd/./src/common/components/videoCall/toolbox/VideoCallToolbox.js","webpack://gvirantd/./src/common/components/videoCall/dial/CallerRington.js","webpack://gvirantd/./src/common/components/videoCall/branding/VideoCallRecommend.js","webpack://gvirantd/./src/common/components/videoCall/chat-video/index.js","webpack://gvirantd/./src/services/ext-video-call/index.js","webpack://gvirantd/./src/services/ext-video-call/endpoints.js","webpack://gvirantd/./src/utils/common/jitsiScriptLoader.js","webpack://gvirantd/./src/common/components/message/hooks/useChatDesctruction.js","webpack://gvirantd/./src/common/components/videoCall/VideoCall.js","webpack://gvirantd/./src/common/components/videoCall/button/DialBtnWrap.js","webpack://gvirantd/./src/common/components/videoCall/dial/ReceiverRington.js","webpack://gvirantd/./src/common/components/mail/components/search/EmailSearch.js","webpack://gvirantd/./src/common/components/mail/components/search/SearchEmailResultItem.js","webpack://gvirantd/./src/common/components/mail/components/search/SearchEmailButton.js","webpack://gvirantd/./src/common/components/mail/components/header/EmailFilter.js","webpack://gvirantd/./src/common/components/mail/components/header/EmailHeader.js","webpack://gvirantd/./src/common/components/mail/components/thread/EmailFileList.js","webpack://gvirantd/./src/common/components/mail/components/thread/EmailMessage.js","webpack://gvirantd/./src/common/components/mail/components/thread/EmailTurnItem.js","webpack://gvirantd/./src/common/components/mail/components/thread/EmailTurnList.js","webpack://gvirantd/./src/common/components/mail/controller/hooks.js","webpack://gvirantd/./src/common/components/mail/components/thread/EmailThreadList.js","webpack://gvirantd/./src/common/components/mail/components/input/utils.js","webpack://gvirantd/./src/common/components/mail/mapper/mapInnerHtmlToText.js","webpack://gvirantd/./src/common/components/mail/components/input/EmailInputBar.js","webpack://gvirantd/./src/common/components/mail/components/button/EmailScrollButton.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorInlineText.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorContentElement.js","webpack://gvirantd/./src/common/components/email-editor/components/settings/EmailEditorSectionSetting.js","webpack://gvirantd/./src/common/components/email-editor/components/input/EmailEditorColorInput.js","webpack://gvirantd/./src/common/components/email-editor/components/settings/EmailEditorFontSetting.js","webpack://gvirantd/./src/common/components/email-editor/controllers/context.js","webpack://gvirantd/./src/i18n/messages/email-editor.js","webpack://gvirantd/./src/common/components/email-editor/components/settings/EmailEditorShowHideSettings.js","webpack://gvirantd/./src/common/components/email-editor/components/settings/EmailEditorSenderInfoSettings.js","webpack://gvirantd/./src/common/components/email-editor/components/settings/EmailEditorGreetingSettings.js","webpack://gvirantd/./src/common/components/email-editor/components/settings/EmailEditorContentSettings.js","webpack://gvirantd/./src/common/components/email-editor/components/settings/EmailEditorProductRequestSettings.js","webpack://gvirantd/./src/common/components/email-editor/components/settings/EmailEditorShippingInfoSettings.js","webpack://gvirantd/./src/common/components/email-editor/components/settings/EmailEditorSigningOffSettings.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorProductRequested.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorNoContentShowMessage.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorSenderInfo.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorPlaceholder.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorTag.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorShippingTo.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorSigningOff.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorAdditionalInfo.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorContent.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorSectionMenu.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorSectionAction.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorSection.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorGreeting.js","webpack://gvirantd/./src/common/components/email-editor/components/frame/EmailEditorFrame.js","webpack://gvirantd/./src/common/components/email-editor/components/toolbar/EmailEditorToolbar.js","webpack://gvirantd/./src/common/components/email-editor/components/get-html/EmailEditorGetHtml.js","webpack://gvirantd/./src/common/components/favorite-star/FavoriteStarIconRender.js","webpack://gvirantd/./src/common/components/asset-type-edit/constants.js","webpack://gvirantd/./src/common/components/asset-type-edit/AssetTypeEdit.js","webpack://gvirantd/./src/common/components/video-preview/VideoPreview.js","webpack://gvirantd/./src/common/components/advanced-search/EntityDraggable.js","webpack://gvirantd/./src/common/components/advanced-search/EntitiesAndAttributes.js","webpack://gvirantd/./src/common/components/advanced-search/QueryDraggable.js","webpack://gvirantd/./src/common/components/advanced-search/QueryConditions.js","webpack://gvirantd/./src/common/components/advanced-search/AdvancedSearch.js","webpack://gvirantd/./src/common/components/btn-save-cancel/EditButtonsSection.js","webpack://gvirantd/./src/common/components/space/FullWidthSpace.js","webpack://gvirantd/./src/common/components/text/TextTooltip.js","webpack://gvirantd/./src/common/components/workflow-maintain/CreateWorkFlowModal.js","webpack://gvirantd/./src/common/components/countdownTrack/index.js","webpack://gvirantd/./src/common/components/chart/gauge/GaugeChart.js","webpack://gvirantd/./src/common/components/signal-handler/meeting-view/index.js","webpack://gvirantd/./src/common/components/signal-handler/index.js","webpack://gvirantd/./src/common/components/page-editor/mappers/index.js","webpack://gvirantd/./src/common/components/page-editor/hooks/index.js","webpack://gvirantd/./src/common/components/page-editor/components/drag-text-component/PageEditorDragText.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/PageEditorToolHeader.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/PageEditorSectionHeader.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/PageEditorInput.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/PageEditorMedia.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool__add-new/PageEditorAddNew.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool__add-new/PageEditorToolAddNewImage.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool__add-new/PageEditorToolAddNewText.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool__add-new/PageEditorToolAddNewYoutube.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/PageEditorDragTextEdit.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/PageEditorDragImageEdit.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/PageEditorDragYoutubeEdit.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/KeyboardHint.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/PageEditorBackgroundEdit.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/PageEditorForm.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/pageEditorToolBtn.js","webpack://gvirantd/./src/common/components/page-editor/hooks/pageEditorToolHooks.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-tool/PageEditorTool.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-background/PageEditorBackground.js","webpack://gvirantd/./src/common/components/page-editor/components/drag-image-component/PageEditorDragImage.js","webpack://gvirantd/./src/common/components/page-editor/components/drag-youtube-component/PageEditorDragYoutube.js","webpack://gvirantd/./src/common/components/page-editor/components/page-editor-inner/index.js","webpack://gvirantd/./src/common/components/page-editor/hooks/pageEditorHooks.js","webpack://gvirantd/./src/common/components/page-editor/PageEditor.js","webpack://gvirantd/./src/common/components/page-editor/PageEditorPreview.js","webpack://gvirantd/./src/common/components/fieldset/Fieldset.js","webpack://gvirantd/./src/common/components/rivir-alert/Action.js","webpack://gvirantd/./src/common/components/rivir-alert/WorkflowAlertItem.js","webpack://gvirantd/./src/common/components/rivir-alert/CreditCardAlert.js","webpack://gvirantd/./src/services/rivirAlert/index.js","webpack://gvirantd/./src/services/rivirAlert/endpoints.js","webpack://gvirantd/./src/hooks/useRivirAlert.js","webpack://gvirantd/./src/common/components/rivir-alert/index.js","webpack://gvirantd/./src/common/components/validate-field-name/ValidateFieldName.js","webpack://gvirantd/./src/common/components/input-time-outlook/InputTimeOutLook.js","webpack://gvirantd/./src/common/components/custom-transfer/CustomTransfer.js","webpack://gvirantd/./src/common/components/ribbon/RibbonDivider.js","webpack://gvirantd/./src/utils/dom.js","webpack://gvirantd/./src/hooks/useShowMoreRibbonButtons.js","webpack://gvirantd/./src/common/components/ribbon/RibbonBar.js","webpack://gvirantd/./src/hooks/ribbonBarHooks.js","webpack://gvirantd/./src/common/components/ribbon/RibbonPortal.js","webpack://gvirantd/./src/common/components/preview-requirements/PreviewRequirementsModal.js","webpack://gvirantd/./src/common/components/ribbon/button/MinimumRequirementsValidate.js","webpack://gvirantd/./src/common/components/preview-requirements/MinimumRequirementPropertiesInput.js","webpack://gvirantd/./src/common/components/download-new-form-item/LockFormItemInput.js","webpack://gvirantd/./src/common/components/download-new-form-item/ToggleLockAllFormItemInput.js","webpack://gvirantd/./src/common/components/download-new-form-item/hooks.js","webpack://gvirantd/./src/common/components/download-new-form-item/ValueFormItemInput.js","webpack://gvirantd/./src/common/components/download-new-form-item/ManualFieldNoLoop.js","webpack://gvirantd/./src/common/components/download-new-form-item/ManualFieldFilling.js","webpack://gvirantd/./src/common/components/download-new-form-item/utils.js","webpack://gvirantd/./src/common/components/download-new-form-item/ModalFormItem.js","webpack://gvirantd/./src/common/components/download-new-form-item/DownloadFormItem.js","webpack://gvirantd/./src/common/components/product-nested-detail-grid/NestedGrid.js","webpack://gvirantd/./src/common/components/product-nested-detail-grid/NestedArrayTypeAttribute.js","webpack://gvirantd/./src/common/components/product-nested-detail-grid/NestedDetailCellRenderer.js","webpack://gvirantd/./src/common/components/product-nested-detail-grid/NestedDetailFramework.js","webpack://gvirantd/./src/common/components/section-wrapper/SectionWrapper.js","webpack://gvirantd/./src/common/components/section-header/SectionHeader.js","webpack://gvirantd/./src/common/components/product-category-tree/useProductCategoryTree.js","webpack://gvirantd/./src/common/components/product-category-tree/ProductCategoryTree.js","webpack://gvirantd/./src/common/components/product-subscription/ProductSubscriptionMappingModal.js","webpack://gvirantd/./src/common/components/form/form-item/FormItem.js","webpack://gvirantd/./src/common/components/carousel-section/index.js","webpack://gvirantd/./src/common/components/index.js","webpack://gvirantd/./src/common/components/indicator/Indicator.js","webpack://gvirantd/./src/common/components/indicator/SuspendIndicator.js","webpack://gvirantd/./src/common/components/input/CheckboxGroup.js","webpack://gvirantd/./src/common/components/layout/Content.js","webpack://gvirantd/./src/common/components/layout/GridStyleLayout.js","webpack://gvirantd/./src/common/components/list/DataDisplay.js","webpack://gvirantd/./src/common/components/list/EntityList.js","webpack://gvirantd/./src/common/components/mail/controller/actions.js","webpack://gvirantd/./src/common/components/mail/controller/constants.js","webpack://gvirantd/./src/common/components/mapping-properties/CustomizeGrid.js","webpack://gvirantd/./src/common/components/mapping-properties/MappingSourceProperties.js","webpack://gvirantd/./src/common/components/mapping-properties/hooks.js","webpack://gvirantd/./src/common/components/mapping-properties/utils.js","webpack://gvirantd/./src/common/components/member-preview/UserContactInfo.js","webpack://gvirantd/./src/common/components/member-preview/MemberTagLine.js","webpack://gvirantd/./src/common/components/member-preview/queries.js","webpack://gvirantd/./src/common/components/member-preview/MemberPanelGdsnList.js","webpack://gvirantd/./src/common/components/google-map-modal/ItemMap.js","webpack://gvirantd/./src/common/components/google-map-modal/InfoWindow.js","webpack://gvirantd/./src/common/components/google-map-modal/MarkerMap.js","webpack://gvirantd/./src/common/components/google-map-modal/GoogleMapViewModal.js","webpack://gvirantd/./src/common/components/member-preview/MemberPanel.js","webpack://gvirantd/./src/common/components/message/controller/actions.js","webpack://gvirantd/./src/common/components/message/controller/constants.js","webpack://gvirantd/./src/common/components/message/controller/mapToReducerState/index.js","webpack://gvirantd/./src/common/components/message/controller/reducer.js","webpack://gvirantd/./src/common/components/message/mapper/mapMesssagesWithAttachUrl.js","webpack://gvirantd/./src/common/components/minimum-requirements/MinimumRequirementsRow.js","webpack://gvirantd/./src/common/components/minimum-requirements/MinimumRequirementsText.js","webpack://gvirantd/./src/common/components/minimum-requirements/MinimumRequirementsTitle.js","webpack://gvirantd/./src/common/components/minimum-requirements/MinimumRequirementsWrapperContent.js","webpack://gvirantd/./src/common/components/modal-download-folder/DownloadFolderMetadata.js","webpack://gvirantd/./src/common/components/modal-download-folder/DownloadFolderLayout.js","webpack://gvirantd/./src/common/components/modal-download-folder/DownloadFolderStep.js","webpack://gvirantd/./src/common/components/modal-download-folder/DownloadFolderModalFooter.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/DownloadFolderBasicSetting.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/product/DownloadFolderProductMapping.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/product/DownloadFolderSettingCollapse.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/product/DownloadFolderHierarchySetting.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/product/DownloadFolderProductSetting.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/asset/DownloadFolderAssetSetting.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/member/DownloadFolderMemberSetting.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/query/DownloadFolderQuerySetting.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/reporting/DownloadFolderReportingSetting.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/DownloadFolderItemsSetting.js","webpack://gvirantd/./src/common/components/modal-download-folder/settings/DownloadFolderSettings.js","webpack://gvirantd/./src/common/components/modal-download-folder/schedule/DownloadFolderMonthSetting.js","webpack://gvirantd/./src/common/components/modal-download-folder/schedule/DownloadFolderWeekSetting.js","webpack://gvirantd/./src/common/components/modal-download-folder/schedule/DownloadFolderSchedule.js","webpack://gvirantd/./src/hooks/folders/useDownloadFolder.js","webpack://gvirantd/./src/common/components/modal-download-folder/DownloadFolderModal.js","webpack://gvirantd/./src/common/components/modal-download-folder/constants.js","webpack://gvirantd/./src/common/components/modal-share/utils.js","webpack://gvirantd/./src/common/components/modal/StyledModal.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-asset-to-member/SelectedMemberList.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-asset-to-member/FormMove.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-asset-to-member/SelectedAssetsList.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/mapper/mapToSearchParams.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-asset-to-member/index.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-product-to-member/SelectedMemberList.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-product-to-member/ProductFormMove.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-product-to-member/SelectedProductList.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-product-to-member/ModalMoveProductResult.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-product-to-member/index.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-gln-to-member/SelectedMemberList.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-gln-to-member/GLNFormMove.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/reassign-gln-to-member/index.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/move-user-to-member/SelectedMemberList.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/move-user-to-member/TargetMemberList.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/move-user-to-member/SelectedUserInfo.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/hooks.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/move-user-to-member/index.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/move-all-entities-to-member/MoveAllOptionsCheckboxs.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/move-all-entities-to-member/MemberMapping.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/move-all-entities-to-member/MoveResults.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/move-all-entities-to-member/queries.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/move-all-entities-to-member/index.js","webpack://gvirantd/./src/hooks/useCheckDisableInitialWorkflowSpec.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/search-entity-all-type-modal/SearchGridItemModal.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/search-entity-all-type-modal/SearchEntityBtn.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/components/SearchGrid.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/components/SearchGridItemPagination.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/components/SearchItemSelectList.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/components/SearchGridItemButton.js","webpack://gvirantd/./src/common/components/modal/search-entity-modal/components/Container.js","webpack://gvirantd/./src/common/components/nested-advance-Search/hook/reducer.js","webpack://gvirantd/./src/common/components/nested-advance-Search/hook/hook.js","webpack://gvirantd/./src/common/components/nested-advance-Search/hook/utils.js","webpack://gvirantd/./src/common/components/openItem/OpenItemFullView.js","webpack://gvirantd/./src/common/components/openItem/OpenItemContentPane.js","webpack://gvirantd/./src/common/components/openItem/OpenItemAntdTab.js","webpack://gvirantd/./src/common/components/antd-otp/utils.js","webpack://gvirantd/./src/common/components/antd-otp/index.js","webpack://gvirantd/./src/common/components/otp/components/shared/PhoneSection.js","webpack://gvirantd/./src/common/components/otp/components/shared/EmailSection.js","webpack://gvirantd/./src/common/components/otp/constants/index.js","webpack://gvirantd/./src/common/components/otp/utils/utils.js","webpack://gvirantd/./src/common/components/otp/queries/index.js","webpack://gvirantd/./src/common/components/otp/hooks/useOtpCheck.js","webpack://gvirantd/./src/common/components/otp/components/otp-check/OtpCheck.js","webpack://gvirantd/./src/common/components/otp/components/shared/OtpHintImage.js","webpack://gvirantd/./src/common/components/otp/hooks/useOtpTrigger.js","webpack://gvirantd/./src/common/components/otp/components/otp-trigger/OtpTrigger.js","webpack://gvirantd/./src/common/components/otp/components/otp-verify-login/OtpVerifyLogin.js","webpack://gvirantd/./src/common/components/otp/components/shared/SessionEnded.js","webpack://gvirantd/./src/common/components/otp/components/otp-verify-change-mfa-phone/OtpVerifyChangeMfaPhone.js","webpack://gvirantd/./src/common/components/otp/components/otp-verify-unlock-account/OtpTriggerUnlockAccount.js","webpack://gvirantd/./src/common/components/otp/components/otp-verify-unlock-account/OtpCheckUnlockAccount.js","webpack://gvirantd/./src/common/components/otp/components/otp-verify-unlock-account/OtpVerifyUnlockAccount.js","webpack://gvirantd/./src/common/components/otp/hooks/useOtpVerify.js","webpack://gvirantd/./src/common/components/page-editor/constants/index.js","webpack://gvirantd/./src/common/components/preview-requirements/UpdateMinimumRequirementProductField.js","webpack://gvirantd/./src/utils/productGallery.js","webpack://gvirantd/./src/hooks/useProductGallery.js","webpack://gvirantd/./src/common/components/preview-requirements/UpdateMinimumRequirementProductGalleryModal.js","webpack://gvirantd/./src/common/components/preview-requirements/UpdateMinimumRequirementProductDocumentModal.js","webpack://gvirantd/./src/common/components/preview-requirements/OpenUpdateMinimumRequirementButton.js","webpack://gvirantd/./src/common/components/preview-requirements/constants.js","webpack://gvirantd/./src/common/components/previewable-modal/items/PreviewableModalHeader.js","webpack://gvirantd/./src/common/components/file-viewer/index.js","webpack://gvirantd/./src/common/components/previewable-modal/items/PreviewableModalBody.js","webpack://gvirantd/./src/common/components/previewable-modal/PreviewableModal.js","webpack://gvirantd/./src/common/components/product-add/ProductBrickCodeModal.js","webpack://gvirantd/./src/common/components/product-add/BrickCodeInput.js","webpack://gvirantd/./src/common/components/product-add/CreateProductForm.js","webpack://gvirantd/./src/common/components/product-add/CreateProductModalFooter.js","webpack://gvirantd/./src/common/components/product-add/CreateProductViaFormModal.js","webpack://gvirantd/./src/common/components/product-add/IXONEConstants.js","webpack://gvirantd/./src/common/components/product-add/utils.js","webpack://gvirantd/./src/common/components/product-add/IXONECertificationWrapper.js","webpack://gvirantd/./src/common/components/product-add/ProductCategory.js","webpack://gvirantd/./src/common/components/product-add/hooks.js","webpack://gvirantd/./src/common/components/product-add/make-product-active/utils.js","webpack://gvirantd/./src/common/components/product-add/useUpdateIXONEShield.js","webpack://gvirantd/./src/common/components/product-category-tree/utils.js","webpack://gvirantd/./src/common/components/product-header-image/ProductHeaderImage.js","webpack://gvirantd/./src/common/components/product-nested-detail-grid/utils.js","webpack://gvirantd/./src/common/components/product-publication-setup/ErrorModal.js","webpack://gvirantd/./src/common/components/product-publication-setup/GDSNPublication.js","webpack://gvirantd/./src/common/components/product-publication-setup/PostToWalmart.js","webpack://gvirantd/./src/common/components/product-publication-setup/PublishProductComponent.js","webpack://gvirantd/./src/common/components/product-publication-setup/Recipient.js","webpack://gvirantd/./src/common/components/product-publication-setup/PartyItem.js","webpack://gvirantd/./src/common/components/product-publication-setup/PartyDataList.js","webpack://gvirantd/./src/i18n/messages/payment.js","webpack://gvirantd/./src/hooks/useCreditCardChargeWarning.js","webpack://gvirantd/./src/common/components/product-publication-setup/PublicationSetupModal.js","webpack://gvirantd/./src/common/components/product-publication-setup/utils.js","webpack://gvirantd/./src/common/components/product-subscription/ProductSubscriptionModal.js","webpack://gvirantd/./src/common/components/product-subscription/utils.js","webpack://gvirantd/./src/common/components/reporting/entity-and-attributes/hook.js","webpack://gvirantd/./src/common/components/reporting/entity-and-attributes/DropZone.js","webpack://gvirantd/./src/common/components/reporting/entity-and-attributes/ModuleDisplayName.js","webpack://gvirantd/./src/common/components/reporting/entity-and-attributes/EntityProperty.js","webpack://gvirantd/./src/common/components/reporting/entity-and-attributes/RowDragging.js","webpack://gvirantd/./src/common/components/reporting/entity-and-attributes/EntitiesAndAttributes.js","webpack://gvirantd/./src/pages/reporting/components/DataSwitchButton.js","webpack://gvirantd/./src/pages/reporting/components/SearchProperties.js","webpack://gvirantd/./src/common/components/reporting/entity-and-attributes/HeaderEntityAttributes.js","webpack://gvirantd/./src/common/components/reporting/entity-and-attributes/utils.js","webpack://gvirantd/./src/common/components/select/WrapperSelect.js","webpack://gvirantd/./src/common/components/select/index.js","webpack://gvirantd/./src/common/components/slot/Slot.js","webpack://gvirantd/./src/common/components/social-link/AddSocialLinkModal.js","webpack://gvirantd/./src/common/components/social-link/SocialIcon.js","webpack://gvirantd/./src/common/components/social-link/SocialLink.js","webpack://gvirantd/./src/common/components/tag/entity-status-tag/EntityStatusTag.js","webpack://gvirantd/./src/common/components/thumb/PreviewableThumb.js","webpack://gvirantd/./src/common/components/thumb/product/ProductThumbFooter.js","webpack://gvirantd/./src/common/components/thumb/ThumbnailItem.js","webpack://gvirantd/./src/common/components/thumb/product/EditableIcon.js","webpack://gvirantd/./src/common/components/thumb/product/GdsnShieldIcon.js","webpack://gvirantd/./src/assets/svg-icons/private-label.svg","webpack://gvirantd/./src/common/components/thumb/product/PrivateLabelcon.js","webpack://gvirantd/./src/common/components/thumb/product/ProductPackLevel.js","webpack://gvirantd/./src/common/components/thumb/product/ProductSubscription.js","webpack://gvirantd/./src/common/components/thumb/share/SharedIcon.js","webpack://gvirantd/./src/common/components/uploadFile/Constants.js","webpack://gvirantd/./src/common/components/uploadFile/UploadFile.js","webpack://gvirantd/./src/common/components/wrapper/WithIndicator.js","webpack://gvirantd/./src/common/components/wrapper/WithLoading.js","webpack://gvirantd/./src/common/components/wrapper/WrapperCalculatorSize.js","webpack://gvirantd/./src/common/components/wrapper/show-condition/isShowForSupplierMember.js","webpack://gvirantd/./src/common/components/wrapper/show-condition/isShowForSharedOnlyMember.js","webpack://gvirantd/./src/common/components/wrapper/show-condition/index.js","webpack://gvirantd/./src/common/queries/member-module.js","webpack://gvirantd/./src/common/queries/product-module.js","webpack://gvirantd/./src/config/assets.js","webpack://gvirantd/./src/config/axios.js","webpack://gvirantd/./src/common/components/page-editor/constants/mock.js","webpack://gvirantd/./src/config/FakeData.js","webpack://gvirantd/./src/utils/processReponse.js","webpack://gvirantd/./src/static/StatusCodes.js","webpack://gvirantd/./src/services/todoList/index.js","webpack://gvirantd/./src/services/todoList/endpoints.js","webpack://gvirantd/./src/redux/global/saga.js","webpack://gvirantd/./src/services/preload/index.js","webpack://gvirantd/./src/services/preload/endpoints.js","webpack://gvirantd/./src/redux/branding/saga.js","webpack://gvirantd/./src/redux/ribbon/saga.js","webpack://gvirantd/./src/redux/user/saga.js","webpack://gvirantd/./src/common/components/message/controller/saga.js","webpack://gvirantd/./src/pages/sso-product/controllers/saga.js","webpack://gvirantd/./src/configureStore.js","webpack://gvirantd/./src/context/Can.js","webpack://gvirantd/./src/context/Locale.js","webpack://gvirantd/./src/context/MemberFullContext.js","webpack://gvirantd/./src/context/Theme.js","webpack://gvirantd/./src/context/Timezone.js","webpack://gvirantd/./src/hooks/apl/useGetAPLGrid.js","webpack://gvirantd/./src/hooks/configGridHooks.js","webpack://gvirantd/./src/hooks/createProductHooks.js","webpack://gvirantd/./src/hooks/documentAttachEventHook.js","webpack://gvirantd/./src/hooks/entityHooks.js","webpack://gvirantd/./src/hooks/folders/queries.js","webpack://gvirantd/./src/hooks/folders/useCancelScheduleDownload.js","webpack://gvirantd/./src/hooks/home/creditCardSlice.js","webpack://gvirantd/./src/hooks/useDeepCompareEffect.js","webpack://gvirantd/./src/hooks/useGetBasicUomEnum.js","webpack://gvirantd/./src/hooks/useCheckIsSuperUser.js","webpack://gvirantd/./src/hooks/useRibbon.js","webpack://gvirantd/./src/hooks/useImageLoaded.js","webpack://gvirantd/./src/hooks/useGetBranding.js","webpack://gvirantd/./src/hooks/useVisibleModal.js","webpack://gvirantd/./src/hooks/useCheckMemberType.js","webpack://gvirantd/./src/hooks/useProductSchema.js","webpack://gvirantd/./src/hooks/ticketing-system/useGetTicketTags.js","webpack://gvirantd/./src/hooks/ticketing-system/useDeleteTicket.js","webpack://gvirantd/./src/hooks/useFormatMessage.js","webpack://gvirantd/./src/hooks/useProductHierarchies.js","webpack://gvirantd/./src/hooks/folders/useDownloadProductSetting.js","webpack://gvirantd/./src/hooks/useCheckPermissionManageGroup.js","webpack://gvirantd/./src/hooks/permissions/useCheckDisableWithdrawPublicationModal.js","webpack://gvirantd/./src/hooks/localStorage.js","webpack://gvirantd/./src/hooks/product-full/hooks.js","webpack://gvirantd/./src/pages/qa-spec-workflow/hook.js","webpack://gvirantd/./src/hooks/qa-spec/useRefetchQaSpecData.js","webpack://gvirantd/./src/hooks/qas-require-field/useQasRequireField.js","webpack://gvirantd/./src/hooks/router/block-routing/utils.js","webpack://gvirantd/./src/hooks/router/block-routing/event.js","webpack://gvirantd/./src/hooks/router/block-routing/useRoutingConfirm.js","webpack://gvirantd/./src/hooks/ticketing-system/useGetTicketAssignTo.js","webpack://gvirantd/./src/hooks/ticketing-system/useTicketFullView.js","webpack://gvirantd/./src/common/components/grid-view/components/add-to-folder/AddToFolderConfirm.js","webpack://gvirantd/./src/hooks/useAddToFolder.js","webpack://gvirantd/./src/hooks/useAsync.js","webpack://gvirantd/./src/hooks/useCallbackRef.js","webpack://gvirantd/./src/hooks/useCheckAllowHooks.js","webpack://gvirantd/./src/hooks/useCheckCreditCardPermission.js","webpack://gvirantd/./src/hooks/useCheckFavoriteRoute.js","webpack://gvirantd/./src/hooks/useCheckIXOneCapture.js","webpack://gvirantd/./src/hooks/useCheckIsFolderOwner.js","webpack://gvirantd/./src/hooks/useCheckPermissionEditBrand.js","webpack://gvirantd/./src/hooks/useCheckPermissions.js","webpack://gvirantd/./src/hooks/useCheckPrivateMember.js","webpack://gvirantd/./src/hooks/useClearSearchText.js","webpack://gvirantd/./src/hooks/useClickOuter.js","webpack://gvirantd/./src/hooks/useClickOuterMultiple.js","webpack://gvirantd/./src/utils/closeDetail.js","webpack://gvirantd/./src/hooks/useCloseDetail.js","webpack://gvirantd/./src/hooks/useControllableState.js","webpack://gvirantd/./src/hooks/useCreditCardEula.js","webpack://gvirantd/./src/hooks/useCustomScroll.js","webpack://gvirantd/./src/hooks/useDisplayFilterButton.js","webpack://gvirantd/./src/hooks/useDoubleClick.js","webpack://gvirantd/./src/hooks/useExitDelay.js","webpack://gvirantd/./src/hooks/useFavorite.js","webpack://gvirantd/./src/hooks/useFilterGrid.js","webpack://gvirantd/./src/hooks/useFolderByLevel.js","webpack://gvirantd/./src/hooks/useFullScreen.js","webpack://gvirantd/./src/hooks/useGetColumns.js","webpack://gvirantd/./src/hooks/useGetDataIdQuery.js","webpack://gvirantd/./src/hooks/useGetDataQueryConditions.js","webpack://gvirantd/./src/hooks/useGetMemberId.js","webpack://gvirantd/./src/hooks/useGetMemberInfo.js","webpack://gvirantd/./src/hooks/useGlobalModal.js","webpack://gvirantd/./src/hooks/useGridView.js","webpack://gvirantd/./src/hooks/useHubFilter.js","webpack://gvirantd/./src/hooks/useKeyDown.js","webpack://gvirantd/./src/hooks/useMdInstance.js","webpack://gvirantd/./src/hooks/useMutation.js","webpack://gvirantd/./src/pages/reporting/controllers/reducer.js","webpack://gvirantd/./src/pages/reporting/controllers/selectors.js","webpack://gvirantd/./src/hooks/useOpenReportingResult.js","webpack://gvirantd/./src/hooks/usePrevious.js","webpack://gvirantd/./src/hooks/useProductEnums.js","webpack://gvirantd/./src/hooks/useProductFullView.js","webpack://gvirantd/./src/hooks/useQuery.js","webpack://gvirantd/./src/pages/transition-page/controllers/saga.js","webpack://gvirantd/./src/pages/qa-spec/controllers/saga.js","webpack://gvirantd/./src/hooks/useRedux.js","webpack://gvirantd/./src/pages/ticketing-system/controllers/saga.js","webpack://gvirantd/./src/hooks/useReloadDocumentCertificateTab.js","webpack://gvirantd/./src/hooks/useReloadPage.js","webpack://gvirantd/./src/hooks/useRemoveFolder.js","webpack://gvirantd/./src/hooks/useResize.js","webpack://gvirantd/./src/hooks/useSso.js","webpack://gvirantd/./src/hooks/useTabExpandProduct.js","webpack://gvirantd/./src/hooks/useUpdateContactCard.js","webpack://gvirantd/./src/hooks/useUpdateMemberAdditionalRequirements.js","webpack://gvirantd/./src/hooks/useGetMinimumRequirementFieldSchema.js","webpack://gvirantd/./src/hooks/useValidateMinimumRequirement.js","webpack://gvirantd/./src/hooks/useValidateStatusField.js","webpack://gvirantd/./src/hooks/useWindowUnload.js","webpack://gvirantd/./src/hooks/userInfoHook.js","webpack://gvirantd/./src/hooks/windowSize.js","webpack://gvirantd/./src/i18n/messages/apl.js","webpack://gvirantd/./src/i18n/messages/asset-full-view.js","webpack://gvirantd/./src/i18n/messages/assetDetail.js","webpack://gvirantd/./src/i18n/messages/assetPreview.js","webpack://gvirantd/./src/i18n/messages/brandedProduct.js","webpack://gvirantd/./src/i18n/messages/common.js","webpack://gvirantd/./src/i18n/messages/favorite.js","webpack://gvirantd/./src/i18n/messages/folder.js","webpack://gvirantd/./src/i18n/messages/gridView.js","webpack://gvirantd/./src/i18n/messages/home.js","webpack://gvirantd/./src/i18n/messages/login.js","webpack://gvirantd/./src/i18n/messages/maintenance.js","webpack://gvirantd/./src/i18n/messages/mapping.js","webpack://gvirantd/./src/i18n/messages/member-profile.js","webpack://gvirantd/./src/i18n/messages/message-my-company.js","webpack://gvirantd/./src/i18n/messages/messageAssetUpload.js","webpack://gvirantd/./src/i18n/messages/messages.js","webpack://gvirantd/./src/i18n/messages/minimum-requirement.js","webpack://gvirantd/./src/i18n/messages/product.js","webpack://gvirantd/./src/i18n/messages/qa-spec.js","webpack://gvirantd/./src/i18n/messages/share.js","webpack://gvirantd/./src/i18n/messages/ticket-system.js","webpack://gvirantd/./src/i18n/messages/timeout.js","webpack://gvirantd/./src/i18n/messages/user-profile.js","webpack://gvirantd/./src/i18n/messages/user.js","webpack://gvirantd/./src/i18n/messages/workflow.js","webpack://gvirantd/./src/i18n/index.js","webpack://gvirantd/./src/static/Localization.js","webpack://gvirantd/./src/common/provider/Language.js","webpack://gvirantd/./src/utils/common/checkEnviroment.js","webpack://gvirantd/./src/utils/common/init.js","webpack://gvirantd/./src/hooks/useInitApp.js","webpack://gvirantd/./src/routes/PrivateRoute.js","webpack://gvirantd/./src/routes/AnonymousRoute.js","webpack://gvirantd/./src/common/components/errorboundary/ErrorBoundary.js","webpack://gvirantd/./src/assets/svg-icons/error-svgrepo-com.svg","webpack://gvirantd/./src/assets/svg-icons/success-svgrepo-com.svg","webpack://gvirantd/./src/pages/interop-callback/ResultPage.js","webpack://gvirantd/./src/pages/interop-callback/InteropCallbackAuthentication.js","webpack://gvirantd/./src/routes/Routes.js","webpack://gvirantd/./src/App.js","webpack://gvirantd/./src/serviceWorker.js","webpack://gvirantd/./src/index.js","webpack://gvirantd/./src/config/env.js","webpack://gvirantd/./src/pages/articles/controllers/actions.js","webpack://gvirantd/./src/pages/articles/controllers/constants.js","webpack://gvirantd/./src/pages/articles/controllers/reducer.js","webpack://gvirantd/./src/pages/articles/controllers/selectors.js","webpack://gvirantd/./src/pages/asset-full-view/mapper/mapToAssetGs1EditOption.js","webpack://gvirantd/./src/pages/asset-full-view/components/add-link-product/AssetGS1Edit.js","webpack://gvirantd/./src/pages/asset-full-view/components/asset-preview/AssetPreviewDownloadBtn.js","webpack://gvirantd/./src/pages/asset-full-view/components/asset-preview/AssetPreviewTools.js","webpack://gvirantd/./src/pages/asset-full-view/components/asset-preview/AssetPreviewVideo.js","webpack://gvirantd/./src/pages/asset-full-view/components/asset-preview/AssetPreview.js","webpack://gvirantd/./src/pages/asset-full-view/components/iframe-asset/IframeAsset.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/shared/components.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/shared/utils.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/shared/hooks.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/AssetUpload.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/AssetUploadSelect.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/AssetFtpList.js","webpack://gvirantd/./src/pages/asset-full-view/components/asset-edit/AssetEdit.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/dropbox-upload/utils.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/dropbox-upload/DropboxFiles.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/dropbox-upload/DropboxActions.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/dropbox-upload/hooks.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/dropbox-upload/AssetDropboxUpload.js","webpack://gvirantd/./src/pages/asset-full-view/components/metadata-panel/AssociationIconRenderedBound.js","webpack://gvirantd/./src/pages/asset-full-view/components/metadata-panel/AssociationIconRendered.js","webpack://gvirantd/./src/pages/asset-full-view/components/confirmContent/ConfirmResult.js","webpack://gvirantd/./src/pages/asset-full-view/components/confirmContent/ConfirmContent.js","webpack://gvirantd/./src/pages/asset-full-view/components/confirmContent/ConfirmContentAsEdit.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/asset-to-folder/AssetToFolderTool.js","webpack://gvirantd/./src/pages/asset-full-view/components/form/asset-upload/asset-to-folder/AssetToFolder.js","webpack://gvirantd/./src/pages/asset-full-view/components/metadata-panel/AssetAssociations.js","webpack://gvirantd/./src/pages/asset-full-view/components/metadata-panel/AssetCreator.js","webpack://gvirantd/./src/pages/asset-full-view/components/metadata-panel/AssetDownload.js","webpack://gvirantd/./src/common/components/asset-type-edit/AssetType.js","webpack://gvirantd/./src/common/components/asset-type-edit/AssetEdit.js","webpack://gvirantd/./src/common/components/asset-type-edit/index.js","webpack://gvirantd/./src/pages/asset-full-view/components/metadata-panel/MemberDefinedPropertiesPanel.js","webpack://gvirantd/./src/pages/asset-full-view/components/add-link-product/SearchProductForm.js","webpack://gvirantd/./src/pages/asset-full-view/components/add-link-product/LinkAssetToPimModal.js","webpack://gvirantd/./src/pages/asset-full-view/components/add-link-product/AssetGS1Preview.js","webpack://gvirantd/./src/pages/asset-full-view/components/metadata-panel/AddDRMForm.js","webpack://gvirantd/./src/static/Metadata.js","webpack://gvirantd/./src/pages/asset-full-view/components/metadata-panel/AssetOverview.js","webpack://gvirantd/./src/pages/asset-full-view/controllers/actions.js","webpack://gvirantd/./src/pages/asset-full-view/controllers/constants.js","webpack://gvirantd/./src/pages/asset-full-view/controllers/reducer.js","webpack://gvirantd/./src/pages/asset-full-view/controllers/saga.js","webpack://gvirantd/./src/pages/asset-full-view/controllers/selectors.js","webpack://gvirantd/./src/pages/branded-assets/components/view/AssetTileView.js","webpack://gvirantd/./src/pages/branded-assets/components/view/AssetThumbView.js","webpack://gvirantd/./src/pages/branded-assets/components/view/AssetDetailView.js","webpack://gvirantd/./src/pages/branded-assets/components/card/AssetThumbnailCard.js","webpack://gvirantd/./src/pages/branded-assets/components/card/AssetTileCard.js","webpack://gvirantd/./src/pages/branded-assets/components/card/AssetItemCard.js","webpack://gvirantd/./src/pages/branded-assets/components/card/AssetItemCardTop.js","webpack://gvirantd/./src/pages/branded-assets/components/card/AssetItemCardBottom.js","webpack://gvirantd/./src/pages/branded-assets/components/tile/AssetTileBody.js","webpack://gvirantd/./src/pages/branded-assets/components/tile/AssetTileHeader.js","webpack://gvirantd/./src/pages/branded-assets/components/tile/AssetTileFooter.js","webpack://gvirantd/./src/pages/branded-assets/components/tile/AssetTile.js","webpack://gvirantd/./src/pages/branded-assets/components/thumbnail/AssetThumbnail.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/AssetPanel.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/AssetPanelAssociation.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/AssetPanelDownload.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/AssetPanelThumbnailInfo.js","webpack://gvirantd/./src/i18n/messages/branded-assets-products.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/link-assets/controller/selectors.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/link-assets/GridLinkAssets.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/link-assets/ItemLinkAsset.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/link-assets/Helper.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/link-assets/utils.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/link-assets/LinkAssets.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/link-assets/controller/actions.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/link-assets/controller/constants.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/link-assets/controller/reducers.js","webpack://gvirantd/./src/pages/branded-assets/components/panel/link-assets/controller/saga.js","webpack://gvirantd/./src/pages/branded-assets/controllers/actions.js","webpack://gvirantd/./src/pages/branded-assets/controllers/constants.js","webpack://gvirantd/./src/pages/branded-assets/controllers/reducer.js","webpack://gvirantd/./src/pages/branded-assets/controllers/saga.js","webpack://gvirantd/./src/pages/branded-assets/controllers/selectors.js","webpack://gvirantd/./src/pages/branded-members/components/card/MemberThumbnailCard.js","webpack://gvirantd/./src/common/components/thumb/member/MemberType.js","webpack://gvirantd/./src/pages/branded-members/components/tile-grid/items-new/MemberTileBody.js","webpack://gvirantd/./src/i18n/messages/branded-members.js","webpack://gvirantd/./src/pages/branded-members/components/tile-grid/items-new/MemberTileFooter.js","webpack://gvirantd/./src/pages/branded-members/components/tile-grid/items-new/MemberTileHeader.js","webpack://gvirantd/./src/pages/branded-members/components/tile-grid/MemberTileCard.js","webpack://gvirantd/./src/pages/branded-members/components/ban-list-modal/BanListModal.js","webpack://gvirantd/./src/pages/branded-members/components/member-logo/MemberLogo.js","webpack://gvirantd/./src/pages/branded-members/components/assets-for-member/hooks.js","webpack://gvirantd/./src/pages/branded-members/components/assets-for-member/utils.js","webpack://gvirantd/./src/pages/branded-members/components/assets-for-member/index.js","webpack://gvirantd/./src/pages/branded-members/components/products-for-member/hooks.js","webpack://gvirantd/./src/pages/branded-members/components/products-for-member/index.js","webpack://gvirantd/./src/pages/branded-members/controllers/actions.js","webpack://gvirantd/./src/pages/branded-members/controllers/constants.js","webpack://gvirantd/./src/pages/branded-members/controllers/reducer.js","webpack://gvirantd/./src/pages/branded-members/controllers/saga.js","webpack://gvirantd/./src/pages/branded-members/controllers/selectors.js","webpack://gvirantd/./src/pages/branded-products-apl/controllers/actions.js","webpack://gvirantd/./src/pages/branded-products-apl/controllers/constants.js","webpack://gvirantd/./src/pages/branded-products-apl/controllers/reducer.js","webpack://gvirantd/./src/pages/branded-products-apl/controllers/saga.js","webpack://gvirantd/./src/pages/branded-products-apl/controllers/selectors.js","webpack://gvirantd/./src/pages/branded-products/components/card/thumbnail/ProductThumbnail.js","webpack://gvirantd/./src/pages/branded-products/components/content-pane/SharedComponents.js","webpack://gvirantd/./src/pages/branded-products/components/content-pane/index.js","webpack://gvirantd/./src/pages/branded-products/components/custom-cell-components/customCellComponents.js","webpack://gvirantd/./src/pages/branded-products/components/card/tile/ProductTileHeader.js","webpack://gvirantd/./src/pages/branded-products/components/card/tile/ProductTileBody.js","webpack://gvirantd/./src/pages/branded-products/components/card/tile/ProductTileFooter.js","webpack://gvirantd/./src/pages/branded-products/components/card/tile/ProductTile.js","webpack://gvirantd/./src/pages/branded-products/components/card/ProductListItem.js","webpack://gvirantd/./src/pages/branded-products/components/detail/info/header/ProductCategory.js","webpack://gvirantd/./src/pages/branded-products/components/detail/info/header/ProductData.js","webpack://gvirantd/./src/pages/branded-products/components/detail/info/header/ProductDescription.js","webpack://gvirantd/./src/pages/branded-products/components/detail/info/header/ProductIdentification.js","webpack://gvirantd/./src/pages/branded-products/components/detail/info/header/ProductLogo.js","webpack://gvirantd/./src/pages/branded-products/components/detail/info/header/ProductRightData.js","webpack://gvirantd/./src/pages/branded-products/components/detail/info/ProductInfo.js","webpack://gvirantd/./src/pages/branded-products/components/detail/package-level/info/ProductPackageLevelInfo.js","webpack://gvirantd/./src/pages/branded-products/components/detail/package-level/ProductPackageLevel.js","webpack://gvirantd/./src/pages/branded-products/components/detail/product-ingredient/ProductIngredient.js","webpack://gvirantd/./src/common/components/slickslider/SlickSlider.js","webpack://gvirantd/./src/pages/branded-products/components/detail/assets/ProductAssets.js","webpack://gvirantd/./src/pages/branded-products/components/drawer/ProductDrawer.js","webpack://gvirantd/./src/pages/branded-products/components/detail/ProductDetail.js","webpack://gvirantd/./src/pages/branded-products/components/brick-code/ProductBrickCode.js","webpack://gvirantd/./src/pages/branded-products/components/primarySizeUOM/PrimarySizeUOM.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/hooks.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/ProductItemSearchDrawer.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/PublicationErrorProductDetail.js","webpack://gvirantd/./src/pages/branded-products/mapper/mapToPublishErrorAlert.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/PublicationErrorDetailModal.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/InstantFixForm.js","webpack://gvirantd/./src/common/components/product-add/ProductEditFormItem.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/InstantFixFormRivirField.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/PublicationErrorItem.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/PubliccationCommonErrorList.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/PackageItemInfo.js","webpack://gvirantd/./src/pages/branded-products/mapper/mapToFormValuePublicationInstantFix.js","webpack://gvirantd/./src/pages/branded-products/hooks/useFetchDataForErrorList.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/PublicationErrorChecker.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-error-check/index.js","webpack://gvirantd/./src/pages/branded-products/mapper/mapToPublishProductRequestParams.js","webpack://gvirantd/./src/pages/branded-products/components/publication-validation-view/PublicationValidationView.js","webpack://gvirantd/./src/pages/branded-products/utils/index.js","webpack://gvirantd/./src/pages/branded-products/controllers/actions.js","webpack://gvirantd/./src/pages/branded-products/controllers/constants.js","webpack://gvirantd/./src/pages/branded-products/controllers/reducer.js","webpack://gvirantd/./src/pages/branded-products/controllers/saga.js","webpack://gvirantd/./src/pages/branded-products/controllers/selectors.js","webpack://gvirantd/./src/pages/branded-products/hooks/useGetDefaultConfig.js","webpack://gvirantd/./src/pages/branded-reporting/components/thumbnail/ReportingThumbnail.js","webpack://gvirantd/./src/pages/branded-reporting/components/tile/ReportingTileBody.js","webpack://gvirantd/./src/pages/branded-reporting/components/tile/ReportingTileFooter.js","webpack://gvirantd/./src/pages/branded-reporting/components/tile/ReportingTileHeader.js","webpack://gvirantd/./src/pages/branded-reporting/components/tile/ReportingTile.js","webpack://gvirantd/./src/pages/branded-reporting/components/panel/ReportingPanel.js","webpack://gvirantd/./src/pages/check-credit-card-info/queries.js","webpack://gvirantd/./src/pages/communication-template/controllers/actions.js","webpack://gvirantd/./src/pages/communication-template/controllers/constants.js","webpack://gvirantd/./src/pages/communication-template/controllers/reducer.js","webpack://gvirantd/./src/pages/communication-template/controllers/selectors.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/contacts/companyLocation/CompanyLocationForm.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/overview/editDetailSchema.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/system/category-management/components/ProductCategoryForm.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/system/category-management/constant.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/system/category-management/hooks/useProductCategoryManagement.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/system/category-management/utils.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/system/interoperability/hooks.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/system/interoperability/utils.js","webpack://gvirantd/./src/pages/company-profile/controllers/actions.js","webpack://gvirantd/./src/pages/company-profile/controllers/constants.js","webpack://gvirantd/./src/pages/company-profile/controllers/reducers/memberProfileReducer.js","webpack://gvirantd/./src/pages/company-profile/controllers/reducers/memberOverviewReducer.js","webpack://gvirantd/./src/pages/company-profile/controllers/reducers/memberContactHistoryReducer.js","webpack://gvirantd/./src/pages/company-profile/controllers/reducers/memberColumnGridReducer.js","webpack://gvirantd/./src/pages/company-profile/controllers/reducers/memberTagLineReducer.js","webpack://gvirantd/./src/pages/company-profile/controllers/reducers/memberPreviewReducer.js","webpack://gvirantd/./src/pages/company-profile/controllers/reducer.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/crm/activity/IconRenderer.js","webpack://gvirantd/./src/pages/company-profile/controllers/filterService.js","webpack://gvirantd/./src/pages/company-profile/controllers/saga.js","webpack://gvirantd/./src/pages/home/ribbon/member-full/controllers/constants.js","webpack://gvirantd/./src/pages/company-profile/controllers/selectors.js","webpack://gvirantd/./src/pages/company/controllers/constants.js","webpack://gvirantd/./src/pages/company/controllers/reducer.js","webpack://gvirantd/./src/pages/company/controllers/selectors.js","webpack://gvirantd/./src/pages/dashboard/controllers/actions.js","webpack://gvirantd/./src/pages/dashboard/controllers/constants.js","webpack://gvirantd/./src/pages/dashboard/controllers/reducer.js","webpack://gvirantd/./src/pages/dashboard/controllers/selectors.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/eula/BackToEula.js","webpack://gvirantd/./src/pages/eula-maintenance/components/form/EulaRibbon.js","webpack://gvirantd/./src/pages/eula-maintenance/controllers/actions.js","webpack://gvirantd/./src/pages/eula-maintenance/controllers/constants.js","webpack://gvirantd/./src/pages/eula-maintenance/controllers/reducer.js","webpack://gvirantd/./src/pages/eula-maintenance/controllers/selectors.js","webpack://gvirantd/./src/pages/favorite-queries/components/thumbnail/QueryThumbnail.js","webpack://gvirantd/./src/pages/favorite-queries/components/tile/QueryTileBody.js","webpack://gvirantd/./src/pages/favorite-queries/components/tile/QueryTileFooter.js","webpack://gvirantd/./src/pages/favorite-queries/components/tile/QueryTileHeader.js","webpack://gvirantd/./src/pages/favorite-queries/components/tile/QueryTile.js","webpack://gvirantd/./src/pages/favorite-queries/components/panel/QueryPanel.js","webpack://gvirantd/./src/pages/folders/components/custom-cell-components/index.js","webpack://gvirantd/./src/pages/folders/components/icons/FolderDownloadScheduledIcon.js","webpack://gvirantd/./src/pages/folders/components/thumbnail/FolderThumbnail.js","webpack://gvirantd/./src/pages/folders/components/tile/FolderTile.js","webpack://gvirantd/./src/pages/folders/components/tile/FolderTileHeader.js","webpack://gvirantd/./src/pages/folders/components/tile/FolderTileBody.js","webpack://gvirantd/./src/pages/folders/components/tile/FolderTileFooter.js","webpack://gvirantd/./src/pages/folders/components/panel-edit/FolderPanelEditContent.js","webpack://gvirantd/./src/pages/folders/components/panel-edit/FolderPanelEditHeader.js","webpack://gvirantd/./src/pages/folders/components/panel/FolderPanelContent.old.js","webpack://gvirantd/./src/pages/folders/components/panel-edit/FolderPanelEdit.js","webpack://gvirantd/./src/pages/folders/components/panel/utils.js","webpack://gvirantd/./src/pages/folders/components/panel/FolderPanelActions.js","webpack://gvirantd/./src/pages/folders/components/panel/FolderPanelContent.js","webpack://gvirantd/./src/pages/folders/components/panel/FolderPanelHeader.js","webpack://gvirantd/./src/pages/folders/components/download-panel/DownloadInformation.js","webpack://gvirantd/./src/pages/folders/components/download-panel/utils.js","webpack://gvirantd/./src/pages/folders/components/download-panel/ConfigDownload.js","webpack://gvirantd/./src/pages/folders/components/download-panel/DownloadConfiguration.js","webpack://gvirantd/./src/pages/folders/components/download-panel/index.js","webpack://gvirantd/./src/pages/folders/components/schedule-panel/ScheduleInformation.js","webpack://gvirantd/./src/pages/folders/components/schedule-panel/ScheduleConfiguration.js","webpack://gvirantd/./src/pages/folders/components/schedule-panel/index.js","webpack://gvirantd/./src/pages/folders/components/panel/FolderPanelDownload.js","webpack://gvirantd/./src/pages/folders/components/panel/FolderPanel.js","webpack://gvirantd/./src/hooks/useMemberPublicContact.js","webpack://gvirantd/./src/pages/folders/components/FolderContentPane.js","webpack://gvirantd/./src/pages/folders/components/view/ModalAddFolderToAPL.js","webpack://gvirantd/./src/pages/folders/components/view/FolderGridView.js","webpack://gvirantd/./src/pages/folders/folder-details/FolderEditDetailContent.js","webpack://gvirantd/./src/pages/folders/components/modal/FolderEditModal.js","webpack://gvirantd/./src/pages/folders/components/utils.js","webpack://gvirantd/./src/pages/folders/controllers/actions.js","webpack://gvirantd/./src/pages/folders/controllers/constants.js","webpack://gvirantd/./src/pages/folders/controllers/reducer.js","webpack://gvirantd/./src/pages/folders/controllers/selectors.js","webpack://gvirantd/./src/hooks/useDownloadFolderSetting.js","webpack://gvirantd/./src/pages/folders/folder-details/utils.js","webpack://gvirantd/./src/pages/folders/hooks/useFolderContentPane.js","webpack://gvirantd/./src/pages/folders/hooks/useAgGridFolder.js","webpack://gvirantd/./src/pages/folders/shared/hooks.js","webpack://gvirantd/./src/pages/folders/shared/components.js","webpack://gvirantd/./src/pages/folders/shared/grid-detail/GridDetailView.js","webpack://gvirantd/./src/pages/folders/shared/utils.js","webpack://gvirantd/./src/pages/home/components/navigation/FilterIndicator.js","webpack://gvirantd/./src/pages/home/components/navigation/HomeNavActionGroup.js","webpack://gvirantd/./src/pages/home/components/navigation/HomeNavSubMenuTitle.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/EditFolderDetail.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/DeleteFolderDetail.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/CreateFolderDetail.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/folder/FolderDetailSection.js","webpack://gvirantd/./src/pages/home/ribbon/FolderDetailRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/Home.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/ProductHierarchy.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/Subscription.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/ProductDetailView.js","webpack://gvirantd/./src/pages/qa-spec/utils/index.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-packaging/CertificateFormList.js","webpack://gvirantd/./src/pages/qa-spec/hooks/useCheckAssignProductToSupplier.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-packaging/utils.js","webpack://gvirantd/./src/pages/qa-spec/components/edit-tab-checker/EditTabCheckerContext.js","webpack://gvirantd/./src/pages/qa-spec/components/edit-tab-checker/EditTabSectionCheckerWrapper.js","webpack://gvirantd/./src/pages/qa-spec/components/edit-tab-checker/EditTabConfirmModal.js","webpack://gvirantd/./src/pages/qa-spec/components/edit-tab-checker/constants.js","webpack://gvirantd/./src/hooks/useComponent.js","webpack://gvirantd/./src/pages/qa-spec/hooks/useCheckQaSpecLocked.js","webpack://gvirantd/./src/pages/qa-spec/components/container/EditContainer.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-spec-header-form/utils.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-product-contain/queries.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-spec-header-form/RequiredFieldsError.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-spec-tab/QaSpecTab.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-ingredient/requiredFieldsQaIngredient.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-ingredient/utils.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/TextRender.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/SnapshotCellWrapper.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/TextRenderSnapshot.js","webpack://gvirantd/./src/pages/qa-spec/utils/gridColumnUtils.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-ingredient/IngredientForm.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-allergen/CustomAllergenAddition.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-prod-spec/snapshot/RetailerSnapshot.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-ingredient/QaSpecIngredient.js","webpack://gvirantd/./src/pages/qa-spec/components/form/FormLabel.js","webpack://gvirantd/./src/pages/qa-spec/components/form/SnapshotWrapper.js","webpack://gvirantd/./src/pages/qa-spec/components/form/hooks.js","webpack://gvirantd/./src/common/components/form/edit-input-country/EditInputCountry.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-spec-header-property/QaSpecHeaderProperty.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/CheckboxRender.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/StringTooltipRender.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/StatusRender.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/DefaultCellRender.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/CountryEditorRender.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/CountryEditorRenderSnapshot.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/FileUploadEditor.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/FileUploadRender.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/FileUploadRenderSnapshot.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/CheckboxRenderSnapshot.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/SelectionEditor.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/CountryEditor.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/NumericEditor.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/CheckboxEditor.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/FreeTextSelector.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/CountryEditorSingle.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/TextEditor.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/SelectionFreeText.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-edit/QaGridEdit.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-contact/QaSpecContacts.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-doc-certificate/ModalUpdateDocsAndCertificates.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-doc-certificate/hooks.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/CellActionRenderSnapshotWrapper.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-doc-certificate/utils.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-doc-certificate/queries.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-doc-certificate/QaSpecDocsAndCertificates.js","webpack://gvirantd/./src/pages/product-full-view/components/modal/add-document-msds/CreateMSDSDocumentForm.js","webpack://gvirantd/./src/pages/product-full-view/components/modal/add-document-msds/CreateMSDSDocumentModal.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-prod-spec/QaSpecProductInfo.js","webpack://gvirantd/./src/pages/qa-spec/hooks/useQaSpecGrid.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-prod-spec/constants.js","webpack://gvirantd/./src/pages/qa-spec/hooks/useQaSpecComponents.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-component/queries.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-component/QaSpecComponent.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-nutrition-data/qa-spec-fact-panel/component/DrugFactHeading.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-nutrition-data/qa-spec-fact-panel/component/DrugFactText.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-fresh-meat/hook.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-fresh-meat/QaFreshMeat.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-edit/WithQaGridHeader.js","webpack://gvirantd/./src/pages/qa-spec/views/qa-spec-detail/utils.js","webpack://gvirantd/./src/pages/qa-spec/hooks/useGetQaSpecRequiredFields.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-packaging/hooks.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-packaging/ProductPackagingModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/ProductPackaging.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-hierarchy/AddHierarchyModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/AddHierarchy.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/EditHierarchy.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/CopyHierarchy.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/DeleteHierarchy.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/HierarchyActions.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/ProductClone.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/SyndicationHistorySection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/MappingInitSyncSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/ProductFullAction.js","webpack://gvirantd/./src/pages/home/ribbon/ProductFullViewRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/advanced-search/RunQueryControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/advanced-search/QuerySection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/advanced-search/LayoutSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/advanced-search/SaveQueryControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/advanced-search/CancelQueryControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/advanced-search/EditQueryControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/advanced-search/CloneQueryControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/advanced-search/SaveSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/advanced-search/OpenResultControl.js","webpack://gvirantd/./src/pages/home/ribbon/ReportingFullViewRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/asset-full/controllers/actions.js","webpack://gvirantd/./src/pages/home/ribbon/asset-full/controllers/constants.js","webpack://gvirantd/./src/pages/home/ribbon/asset-full/controllers/reducer.js","webpack://gvirantd/./src/pages/home/ribbon/asset-full/controllers/selectors.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/Control.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/advanced-search/ClearColumnsControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/advanced-search/ClearQueryControl.js","webpack://gvirantd/./src/pages/reporting/hook/useScheduleDownload.js","webpack://gvirantd/./src/pages/reporting/components/DownloadSchedule/ReportingDownloadScheduleMonthSetting.js","webpack://gvirantd/./src/pages/reporting/components/DownloadSchedule/ReportingDownloadScheduleWeekSetting.js","webpack://gvirantd/./src/pages/reporting/components/DownloadSchedule/ReportingDownloadScheduleForm.js","webpack://gvirantd/./src/pages/reporting/components/DownloadSchedule/ReportingScheduleFooter.js","webpack://gvirantd/./src/pages/reporting/components/ReportingScheduleModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/advanced-search/OpenSchedule.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/DeletePreview.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/GeneratePreview.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/OpenAsset.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/common/AddOpenItemBtn.js","webpack://gvirantd/./src/common/components/button/svg-icons/copy.svg","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/CopyFolder.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/CopyFolderModal.js","webpack://gvirantd/./src/common/components/modal-action/ModalAction.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/CreateFolderModal.js","webpack://gvirantd/./src/common/components/modal-manage-schedule-download/ManageScheduleDownloadLayout.js","webpack://gvirantd/./src/hooks/folders/useDeleteScheduleDownload.js","webpack://gvirantd/./src/hooks/folders/useUpdateScheduleDownload.js","webpack://gvirantd/./src/common/components/modal-manage-schedule-download/ManageScheduleDownloadToolbar.js","webpack://gvirantd/./src/common/components/modal-manage-schedule-download/utils.js","webpack://gvirantd/./src/common/components/modal-manage-schedule-download/ManageScheduleDownloadGrid.js","webpack://gvirantd/./src/common/components/modal-manage-schedule-download/ManageScheduleDownloadModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/ManageScheduleDownload.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/MoveFolder.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/MoveFolderModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/OpenFolder.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/AddFolder.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/FavoriteControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/UnfavoriteControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/AddFolderToNewAPL.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/AddProductToNewApl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/AddSearchProductToNewApl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/Addition.js","webpack://gvirantd/./src/common/components/nested-advance-Search/OpenAdvanceFilter.js","webpack://gvirantd/./src/common/components/nested-advance-Search/NestedAdvanceSearch.js","webpack://gvirantd/./src/common/components/nested-advance-Search/NestedAdvanceFilter.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/AdvanceStack.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/Back.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/DeleteFolder.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/DetailView.js","webpack://gvirantd/./src/common/components/modal/grid-view-modal/components/GridItem.js","webpack://gvirantd/./src/common/components/modal/grid-view-modal/components/Grid.js","webpack://gvirantd/./src/common/components/modal/grid-view-modal/find-in-all-folder-modal/FindEntityInFolderResultToolbar.js","webpack://gvirantd/./src/common/components/modal/grid-view-modal/find-in-all-folder-modal/FindEntityInFolderResultFooter.js","webpack://gvirantd/./src/common/components/modal/grid-view-modal/find-in-all-folder-modal/FindInAllFolderModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/SearchFolder.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/hooks.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/utils.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/ProductSheets.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/hook.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product/SelectedProductList.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product/AssignCategoryToProductModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product/BulkEditProduct.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/withdraw-publication/constants.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/withdraw-publication/utils.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/withdraw-publication/PublicationTable.js","webpack://gvirantd/./src/hooks/useWithdrawPublication.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/withdraw-publication/WithdrawPublicationModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product/WithdrawPublicationButton.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/recipients-fields/utils.js","webpack://gvirantd/./src/common/components/button/svg-icons/ICO_10.13.svg","webpack://gvirantd/./src/pages/home/ribbon/components/controls/shared/EmailControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/shared/SendToFTP.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/shared/SendToMessage.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/home-grid/Favorite.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/home-grid/Folder.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-full/MemberAddOpenItemSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/home-grid/OtherLayout.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/InlineControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/QuickView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/Search.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/AdvanceSearch.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/GridColumns.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/SaveGrid.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/AddCuratedQueryConfig.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/AddCuratedQuery.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/SavedConfigurations.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/ClearQuery.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-full/EditControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-full/SaveControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-full/CancelEdit.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/ToggleUploadMediaBtn.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/post-full/ToggleHelpUploadMediaSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/generate-preview/GeneratePreviewModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/generate-confirm/GenerateConfirmModal.js","webpack://gvirantd/./src/utils/browser.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/generate-preview/GeneratePreviewItem.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/manage-share/ManageShareModal.js","webpack://gvirantd/./src/hooks/useGetDataAdvanceFilter.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/AddProductFromMember.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/DownloadProductTemplateFromMember.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/UploadProductTemplateFromMember.js","webpack://gvirantd/./src/pages/home/ribbon/components/ribbbonSectionDivider/RibbonSectionDivider.js","webpack://gvirantd/./src/pages/home/ribbon/components/index.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/ManageGridQuery.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/bulk-edit-product/CopyProductToolbar.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/bulk-edit-product/CopyProductResult.js","webpack://gvirantd/./src/hooks/copyProductPropertiesHooks.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/bulk-edit-product/CopyProductPropertiesModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/bulk-edit-product/ExportProductToolbar.js","webpack://gvirantd/./src/hooks/exportProductPropertiesHooks.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/bulk-edit-product/ExportProductPropertiesModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/bulk-edit-product/ExportPropertiesTree.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/bulk-edit-product/ImportProductBulkEditModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-hierarchy/HierarchyProductList.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-hierarchy/AddProductHierarchy.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-hierarchy/HierarchyLevelProductItem.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-hierarchy/HierarchyPackageLevel.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-hierarchy/HierarchyChangeProductMessage.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-hierarchy/HierarchyAddProductButton.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-hierarchy/HierarchyLevelList.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/CreateAsset.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/ReplaceAsset.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/DeleteAssets.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/EditMultipleAsset.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/UpdateMultipleAsset.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/MoveAssetsToMember.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/hook.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/asset/AssetActionsSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/asset/grid/OpenAssetSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/ReplacePreviewGrid.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/asset/grid/PreviewSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/DownloadAsset.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/asset/DownloadSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/LinkAssets.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/asset/LinkSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/EditAsset.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/SaveAsset.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/CancelAsset.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/ReplacePreview.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/asset/full/PreviewSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/asset/full/FilterSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/asset/VersionAsset.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/asset/VersionsSection.js","webpack://gvirantd/./src/common/components/mapping-properties/ShowGridConfig.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/customize-grid/hooks.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/customize-grid/GridConfiguration.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/customize-grid/ClearApplyGridConfig .js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/customize-grid/CustomizeGrid.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/customize-grid/index.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/customize-grid/utils.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/CreateFolder.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/pathname.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/DeleteFolders.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/folders/EditFolder.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/folder/FolderSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/home-grid/AdditionSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-grid/CategoriesControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/home-grid/Categories.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/home-grid/DetailSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/home-grid/Execute.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/MutationGridConfig.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/CreateQueryModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/ModalFormEdit.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/GridQueryTable.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/ShareQueryModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/GridQueryAction.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/home/grid-query/ManageQueriesModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/home-grid/GridConfig.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/home-grid/ViewLayout.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-grid/DownloadInformation.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-grid/Download.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/constants.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/hooks.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/AssignCategoryToProduct.js","webpack://gvirantd/./src/services/nif/index.js","webpack://gvirantd/./src/services/nif/endpoints.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/download-nif-form-section/hooks.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/download-nif-form-section/SearchNifFormModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/DownloadNifFormSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/FilterPackageSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/ProductCategoryHierarchy.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/ProductBrickCodeHierarchy.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/FilterProductCategoryModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/FilterMyAplsModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/FilterMyAPLs.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/FilterProductSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product/HistoryControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/HistorySection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/OpenProduct.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product/MoveProductsToMember.js","webpack://gvirantd/./src/pages/product-full-view/components/product-hierarchy/IXOneHierarchyTree.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-credit-card/constants.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-credit-card/IXOneHierarchy.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-credit-card/IXOneContext.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-section/utils.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-section/IXOneHierarchyModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-section/IXOneHierarchyAction.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/billing-new/queries.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/make-product-active/hooks.js","webpack://gvirantd/./src/common/components/product-add/make-product-active/RequiredPropertyElement.js","webpack://gvirantd/./src/hooks/home/useCreditCardAlert.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/billing-new/hooks.js","webpack://gvirantd/./src/pages/company-profile/components/tabs/billing-new/MemberCardInformation.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/cod-payment/CODPayment.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-section/hooks.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/cod-payment/utils.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/cod-payment/hooks.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/cod-payment/constants.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/cod-payment/PaymentChargeValidating.js","webpack://gvirantd/./src/common/components/product-add/make-product-active/RequiredActiveProduct.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/make-product-active/MissingRequirementProduct.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/make-product-active/ProductsActiveProcessing.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-credit-card/hooks.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-credit-card/IXOneCreditCard.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-section/IXOneNewProductForm.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/components/ixone-section/IXOneCapture.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/IXOneSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/ProductGridAction.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/SelectCategory.js","webpack://gvirantd/./src/assets/shared-ribbon/ManageShared.svg","webpack://gvirantd/./src/pages/home/ribbon/components/controls/shared/ManageSharing.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/shared/ManageSharingSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/shared/MoveAllToMember.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/shared/utils.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/shared/ShareControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/shared/ShareSection.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-history-grid/HistoryEntity.js","webpack://gvirantd/./src/assets/security-request/create-request.svg","webpack://gvirantd/./src/pages/home/ribbon/security-request/NewRequest.js","webpack://gvirantd/./src/pages/home/ribbon/security-request/hooks.js","webpack://gvirantd/./src/pages/home/utils.js","webpack://gvirantd/./src/pages/login/introduction/index.js","webpack://gvirantd/./src/pages/maintenance-form/controllers/actions.js","webpack://gvirantd/./src/pages/maintenance-form/controllers/constants.js","webpack://gvirantd/./src/pages/maintenance-form/controllers/reducer.js","webpack://gvirantd/./src/pages/maintenance-form/controllers/selectors.js","webpack://gvirantd/./src/pages/maintenance-form/mappers/index.js","webpack://gvirantd/./src/pages/maintenance/components/help/category/HelpCategoryGridViewIcon.js","webpack://gvirantd/./src/pages/maintenance/components/help/category/HelpCategoryIconFilter.js","webpack://gvirantd/./src/pages/maintenance/controllers/actions.js","webpack://gvirantd/./src/pages/maintenance/controllers/constants.js","webpack://gvirantd/./src/pages/maintenance/controllers/reducer.js","webpack://gvirantd/./src/pages/maintenance/components/help/post/icon/PostTypeIcon.js","webpack://gvirantd/./src/pages/maintenance/controllers/saga.js","webpack://gvirantd/./src/utils/agGridUtils.js","webpack://gvirantd/./src/pages/maintenance/controllers/selectors.js","webpack://gvirantd/./src/pages/mapping/controllers/actions.js","webpack://gvirantd/./src/pages/mapping/controllers/constants.js","webpack://gvirantd/./src/pages/mapping/controllers/reducer.js","webpack://gvirantd/./src/pages/mapping/controllers/saga.js","webpack://gvirantd/./src/pages/mapping/controllers/selectors.js","webpack://gvirantd/./src/pages/markup-maintenance/controllers/actions.js","webpack://gvirantd/./src/pages/markup-maintenance/controllers/constants.js","webpack://gvirantd/./src/pages/markup-maintenance/controllers/reducer.js","webpack://gvirantd/./src/pages/markup-maintenance/controllers/saga.js","webpack://gvirantd/./src/pages/markup-maintenance/controllers/selectors.js","webpack://gvirantd/./src/pages/member-maintenance/controllers/actions.js","webpack://gvirantd/./src/pages/member-maintenance/controllers/constants.js","webpack://gvirantd/./src/pages/member-maintenance/controllers/reducer.js","webpack://gvirantd/./src/pages/member-maintenance/controllers/selectors.js","webpack://gvirantd/./src/pages/minimum-requirements/components/modal/utils.js","webpack://gvirantd/./src/pages/minimum-requirements/constants.js","webpack://gvirantd/./src/pages/new-main-page/controllers/actions.js","webpack://gvirantd/./src/pages/new-main-page/controllers/constants.js","webpack://gvirantd/./src/pages/product-apl-detail/controllers/actions.js","webpack://gvirantd/./src/pages/product-apl-detail/controllers/constants.js","webpack://gvirantd/./src/pages/product-apl-detail/controllers/reducer.js","webpack://gvirantd/./src/pages/product-apl-detail/controllers/selectors.js","webpack://gvirantd/./src/pages/product-full-view/components/product-primary-info/ProductOverviewSubscriptionShield.js","webpack://gvirantd/./src/pages/product-full-view/components/product-primary-info/ProductOverviewTitle.js","webpack://gvirantd/./src/pages/product-full-view/components/product-primary-info/ProductOverviewStatusInfo.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/GdsnShield.js","webpack://gvirantd/./src/pages/product-full-view/components/product-primary-info/ProductPrimaryInfo.js","webpack://gvirantd/./src/pages/product-full-view/components/product-overview/ProductOverviewBricCode.js","webpack://gvirantd/./src/pages/product-full-view/components/product-overview/ProductOverviewDimension.js","webpack://gvirantd/./src/pages/product-full-view/components/product-overview/ProductOverviewQuestionButton.js","webpack://gvirantd/./src/pages/product-full-view/components/certifications/CertificationImages.js","webpack://gvirantd/./src/pages/product-full-view/components/certifications/CertificationItem.js","webpack://gvirantd/./src/pages/product-full-view/components/certifications/CertificationModal.js","webpack://gvirantd/./src/static/ProductCertifications.js","webpack://gvirantd/./src/pages/product-full-view/components/certifications/ProductOverviewCertification.js","webpack://gvirantd/./src/pages/product-full-view/components/product-overview/Contants.js","webpack://gvirantd/./src/pages/product-full-view/components/product-overview/CalculatedPropertiesModal.js","webpack://gvirantd/./src/pages/product-full-view/components/product-overview/ProductOverviewMetadata.js","webpack://gvirantd/./src/pages/product-full-view/components/product-overview/ProductOverviewContent.js","webpack://gvirantd/./src/pages/product-full-view/components/product-overview/ProductOverview.js","webpack://gvirantd/./src/pages/product-full-view/components/package-level/PackageHeaderDrawer.js","webpack://gvirantd/./src/pages/product-full-view/components/package-level/ImageUnit.js","webpack://gvirantd/./src/pages/product-full-view/components/package-level/PackageContentDrawer.js","webpack://gvirantd/./src/pages/product-full-view/components/product-hierarchy/ProductHierarchyDetail.js","webpack://gvirantd/./src/pages/product-full-view/components/product-hierarchy/ProductHierarchyEndpointInfo.js","webpack://gvirantd/./src/pages/product-full-view/components/product-detail-view/FormEditCustomProductProperties.js","webpack://gvirantd/./src/pages/product-full-view/components/product-detail-view/index.js","webpack://gvirantd/./src/pages/product-full-view/components/product-syndication-history-panel/ProductSyndicationHistoryStatus.js","webpack://gvirantd/./src/pages/product-full-view/components/product-syndication-history-panel/ProductSyndicationHistoryMessage.js","webpack://gvirantd/./src/pages/product-full-view/components/product-syndication-history-panel/ProductSyndicationHistoryPanel.js","webpack://gvirantd/./src/pages/product-full-view/mappers/mapTypeToAssetSubType.js","webpack://gvirantd/./src/pages/product-full-view/components/modal/add-asset-pim-modal/UploadPimAsset.js","webpack://gvirantd/./src/pages/product-full-view/components/modal/add-asset-pim-modal/index.js","webpack://gvirantd/./src/pages/product-full-view/components/modal/link-to-asset-modal/LinkToAssetModal.js","webpack://gvirantd/./src/pages/product-full-view/components/preview-modal/DownloadModal.js","webpack://gvirantd/./src/pages/product-full-view/components/preview-modal/ImageArea.js","webpack://gvirantd/./src/pages/product-full-view/components/preview-modal/ImagePreviewArea.js","webpack://gvirantd/./src/pages/product-full-view/components/preview-modal/ImageDownloadOption.js","webpack://gvirantd/./src/pages/product-full-view/components/preview-modal/PreviewGalleryModal.js","webpack://gvirantd/./src/pages/product-full-view/components/preview-modal/linked-asset-edit/LinkedAssetEditModal.js","webpack://gvirantd/./src/pages/product-full-view/components/product-detail-view/FormContext.js","webpack://gvirantd/./src/pages/product-full-view/components/product-detail-view/FormEditProperties.js","webpack://gvirantd/./src/pages/product-full-view/components/product-detail-view/ShareComponents.js","webpack://gvirantd/./src/pages/product-full-view/components/product-detail-view/hooks.js","webpack://gvirantd/./src/pages/product-full-view/components/product-detail-view/utils.js","webpack://gvirantd/./src/pages/product-full-view/components/product-edit-brand/ProductBrandEditForm.js","webpack://gvirantd/./src/pages/product-full-view/components/product-edit-brand/ProductEditBrandModal.js","webpack://gvirantd/./src/pages/product-full-view/components/product-hierarchy/ProductHierarchyTree.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/header-action/HeaderEditActions.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/header-component/ProductHeaderSocial.js","webpack://gvirantd/./src/common/queries/utils.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/header-component/queries.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/header-component/ProductHeaderContactInfoEditModal.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/header-component/ProductHeaderContactInfo.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/header-component/ProductHeaderProfileImage.js","webpack://gvirantd/./src/pages/product-full-view/mappers/mapToProductContact.js","webpack://gvirantd/./src/pages/product-full-view/queries/index.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/ProductHeader.js","webpack://gvirantd/./src/pages/product-full-view/components/ProductImageSlider.js","webpack://gvirantd/./src/pages/product-full-view/components/ProductGallery.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/ProductDocument.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/ProductMarketingAll.js","webpack://gvirantd/./src/pages/product-full-view/components/preview-modal/MarketingPreviewArea.js","webpack://gvirantd/./src/pages/product-full-view/components/preview-modal/PreviewMarketingModal.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/ProductMarketingVideo.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-allergens/FormAllergens.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-allergens/AllergenElement.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-allergens/TabAllergens.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-allergens/index.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-ingredients/RenderIngredients.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-ingredients/IngredientsForm.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/TabIngredients.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/facts-panel/MultipleFactsPanel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/MultiplePanel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/index.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/ProductMediaContent.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/ProductMediaArea.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactHeading.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactSection.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactText.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactActiveIngredient.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactBullet.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactCase.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactDetailList.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactUses.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactWarningItem.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactWarnings.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactDirections.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactOtherInformation.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/component/DrugFactInactiveIngredients.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/index.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/drug-label/DrugStandardLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/Carousel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/facts-panel/useMutationDeleteFactsPanel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/TabFactPanels.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/components/GroupLayoutProvider.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/components/GroupPart.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/components/hooks.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/components/GroupActions.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/components/GroupLayout.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/components/GroupModification.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/components/GroupAssign.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/components/GroupPreview.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/components/PanelContextContainer.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/supplement-label/index.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/components/utils.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/constants.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/facts-panel/LinearLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/facts-panel/VerticalLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/facts-panel/VerticalLabelWithMicronutrient.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/facts-panel/useQueryFactsPanel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-allergens/constants.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-allergens/queries.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-allergens/utils.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-ingredients/useProductIngredients.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/multiple-panel/tab-ingredients/utils.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/DailyValueConstants.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/hook/useNutritionLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/NutrientForm.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/supplement-label/SupplementFormButton.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/NutrientList.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/hook/useAddNutritionLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/AddNutritionLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/supplement-label/SupplementForm.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/hook/useGetSupplementPartOf.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/supplement-label/SupplementNutrientForm.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/supplement-label/SupplementIngredientForm.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/supplement-label/SupplementNutrientItemView.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/supplement-label/SupplementDeleteConfirmation.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/supplement-label/SupplementNutrientItem.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/supplement-label/SupplementNutrientList.js","webpack://gvirantd/./src/hooks/useScrollTo.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/supplement-label/SupplementNutrient.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/hook/useAddSupplementLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/supplement-label/AddSupplementLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/drug-facts-label/components/DrugFactsButton.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/drug-facts-label/components/Directions.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/drug-facts-label/components/Uses.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/drug-facts-label/components/OtherInformation.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/drug-facts-label/components/ActiveIngredients.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/drug-facts-label/components/InactiveIngredients.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/drug-facts-label/components/Warning.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/drug-facts-label/hook.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/drug-facts-label/AddDrugFactsLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/pet-nutrition-label/components/Nutrients.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/pet-nutrition-label/hook.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/pet-nutrition-label/PetNutritionLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/index.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/pet-nutrition-label/PetNutritionFacts.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/pet-nutrition-label/constants.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/add-label/pet-nutrition-label/utils.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/components/LinearVitaminLabel.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-nutrition-data/Constant.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/components/NutrientRow.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/components/NutrientSideBySide.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/components/SeparatorBar.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/components/utils/NutritionBreakdown.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/constants/index.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/nutrition-label/context/nutritionContext.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/shared/GroupAssignParts.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/shared/GroupPreviewParts.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/shared/hooks.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/shared/utils.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/supplement-label/Calories.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/supplement-label/SupplementList.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/supplement-label/SupplementStandardLabel.js","webpack://gvirantd/./src/pages/product-full-view/components/product-media-area/supplement-label/utils.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/ProductDetailContext.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/FormMultipleNestedValue.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/FormSingleNestedValue.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/ProductDetailEdit.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/QueryProperties.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-allergen/constants.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/allergenUtils.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/filterModuleUtils.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/hooks.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/ProductPropertyItem.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/DisplayProductInfo.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/ProductBaseModules.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/ProductAdvancedModules.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/PackageContent.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/ShareComponents.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/FormEditCustomProductProperties.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/ProductCustomProperties.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/layout/ProductDetailGridItemContainer.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/layout/WithProductDetailExpandBtn.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/ProductDetailView.js","webpack://gvirantd/./src/pages/product-full-view/components/product-new-detail-view/utils.js","webpack://gvirantd/./src/pages/product-full-view/components/subscription/Subscription.js","webpack://gvirantd/./src/pages/product-full-view/constants.js","webpack://gvirantd/./src/pages/product-full-view/controllers/actions.js","webpack://gvirantd/./src/pages/product-full-view/controllers/constants.js","webpack://gvirantd/./src/pages/product-full-view/controllers/mapper/mapToReducerState/index.js","webpack://gvirantd/./src/pages/product-full-view/controllers/reducer.js","webpack://gvirantd/./src/pages/product-full-view/controllers/mapper/mapToGridColumn/index.js","webpack://gvirantd/./src/pages/product-full-view/controllers/saga.js","webpack://gvirantd/./src/pages/product-full-view/controllers/selectors.js","webpack://gvirantd/./src/pages/product-full-view/mappers/mapToEnums.js","webpack://gvirantd/./src/pages/product-full-view/shared/components.js","webpack://gvirantd/./src/pages/product-full-view/shared/hooks.js","webpack://gvirantd/./src/pages/product-full-view/shared/utils.js","webpack://gvirantd/./src/pages/product-history/constant.js","webpack://gvirantd/./src/pages/product-history/hook.js","webpack://gvirantd/./src/pages/product-history/utils.js","webpack://gvirantd/./src/pages/qa-spec/components/group-data/hooks.js","webpack://gvirantd/./src/pages/qa-spec/components/group-data/utils.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-allergen/FormAllergen.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-allergen/hooks.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-claims/queries.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-formula/queries.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-fresh-meat/queries.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-fresh-produce/hooks.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-fresh-seafood/queries.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-grid-cell/LinkAssetToQaSpec.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-ingredient/hook.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-nutrition-data/WrapperNutrient.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-nutrition-data/hook.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-packaging/queries.js","webpack://gvirantd/./src/pages/qa-spec/components/qa-spec-tab/SnapshotFormItem.js","webpack://gvirantd/./src/pages/qa-spec/constant/index.js","webpack://gvirantd/./src/pages/qa-spec/controllers/actions.js","webpack://gvirantd/./src/pages/qa-spec/controllers/constants.js","webpack://gvirantd/./src/pages/qa-spec/controllers/reducer.js","webpack://gvirantd/./src/pages/qa-spec/controllers/selectors.js","webpack://gvirantd/./src/pages/qa-spec/hooks/index.js","webpack://gvirantd/./src/pages/qa-spec/hooks/useCheckSnapshotForRetailer.js","webpack://gvirantd/./src/pages/qa-spec/hooks/useProductSpecInfo.js","webpack://gvirantd/./src/pages/qa-spec/query/useGetQaSpecComponentQuery.js","webpack://gvirantd/./src/pages/qa-spec/query/useGetQaSpecDataHeader.js","webpack://gvirantd/./src/pages/recipients-fields/controllers/actions.js","webpack://gvirantd/./src/pages/recipients-fields/controllers/constants.js","webpack://gvirantd/./src/pages/reporting/components/ColumnDraggable.js","webpack://gvirantd/./src/pages/reporting/components/DataColumns.js","webpack://gvirantd/./src/pages/reporting/components/EmptyAttribute.js","webpack://gvirantd/./src/pages/reporting/components/PropertiesItems.js","webpack://gvirantd/./src/pages/reporting/components/QueryConditions.js","webpack://gvirantd/./src/pages/reporting/components/RenderValue.js","webpack://gvirantd/./src/pages/reporting/components/RenderValueIn.js","webpack://gvirantd/./src/pages/reporting/components/RenderValueBetween.js","webpack://gvirantd/./src/pages/reporting/components/SwitchConjunction.js","webpack://gvirantd/./src/pages/reporting/components/SelectFieldsChanged.js","webpack://gvirantd/./src/pages/reporting/components/RenderBtnUploadFile.js","webpack://gvirantd/./src/pages/reporting/components/QueryDraggable.js","webpack://gvirantd/./src/pages/reporting/components/RenderRootTitle.js","webpack://gvirantd/./src/pages/reporting/components/TitleSection.js","webpack://gvirantd/./src/pages/reporting/controllers/actions.js","webpack://gvirantd/./src/pages/reporting/controllers/constants.js","webpack://gvirantd/./src/pages/reporting/hook/renderTree.js","webpack://gvirantd/./src/pages/reporting/hook/useGetFieldsChange.js","webpack://gvirantd/./src/pages/reporting/hook/useGetProperties.js","webpack://gvirantd/./src/pages/reporting/utils/constants.js","webpack://gvirantd/./src/pages/reporting/utils/index.js","webpack://gvirantd/./src/pages/role/components/role-list/index.js","webpack://gvirantd/./src/pages/role/components/section-wrapper/index.js","webpack://gvirantd/./src/assets/svg-icons/pencil.svg","webpack://gvirantd/./src/pages/role/components/section-wrapper/SectionHeader.js","webpack://gvirantd/./src/pages/role/components/role-description/index.js","webpack://gvirantd/./src/pages/role/components/empty-section/index.js","webpack://gvirantd/./src/pages/role/components/role-user-list/NewUserModal.js","webpack://gvirantd/./src/pages/role/components/role-user-list/index.js","webpack://gvirantd/./src/assets/svg-icons/style-circle-left.svg","webpack://gvirantd/./src/assets/svg-icons/style-circle-right.svg","webpack://gvirantd/./src/assets/svg-icons/style-circle-add.svg","webpack://gvirantd/./src/assets/svg-icons/style-circle-remove.svg","webpack://gvirantd/./src/assets/svg-icons/style-checked.svg","webpack://gvirantd/./src/pages/role/components/role-permission-list/PermissionTypeIcon.js","webpack://gvirantd/./src/pages/role/components/role-permission-list/RolePermissionGroup.js","webpack://gvirantd/./src/pages/role/mappers/mapToCategoriesAndSearchPermisison.js","webpack://gvirantd/./src/pages/role/components/role-permission-list/index.js","webpack://gvirantd/./src/pages/role/components/edit-control/index.js","webpack://gvirantd/./src/pages/role/components/role-name/index.js","webpack://gvirantd/./src/pages/role/components/member-role-list/index.js","webpack://gvirantd/./src/pages/role/mappers/mapMemerRoleFormToSubmitValue.js","webpack://gvirantd/./src/pages/role/components/member-role-control/index.js","webpack://gvirantd/./src/pages/role-member/mappers/index.js","webpack://gvirantd/./src/pages/role/components/member-role-section-wrapper/index.js","webpack://gvirantd/./src/pages/role/components/member-role-description/MemberRoleDescriptionFormItem.js","webpack://gvirantd/./src/pages/role/components/member-role-description/index.js","webpack://gvirantd/./src/pages/role/components/member-role-permission-list/MemberRolePermissionGroup.js","webpack://gvirantd/./src/pages/role/mappers/mapToMemberPermissionList.js","webpack://gvirantd/./src/pages/role/components/member-role-permission-list/index.js","webpack://gvirantd/./src/pages/role/components/member-role-member-list/NewMemberModal.js","webpack://gvirantd/./src/pages/role/components/member-role-member-list/index.js","webpack://gvirantd/./src/pages/role/components/member-role-need-permission/index.js","webpack://gvirantd/./src/pages/role/controllers/actions.js","webpack://gvirantd/./src/pages/role/controllers/constants.js","webpack://gvirantd/./src/pages/role/controllers/mapper/mapToReducerState.js","webpack://gvirantd/./src/pages/role/controllers/reducer.js","webpack://gvirantd/./src/pages/role/controllers/selectors.js","webpack://gvirantd/./src/pages/role/mappers/validateRoleFormFields.js","webpack://gvirantd/./src/pages/sso-approval/controllers/constants.js","webpack://gvirantd/./src/pages/sso-product/controllers/actions.js","webpack://gvirantd/./src/pages/sso-product/controllers/constants.js","webpack://gvirantd/./src/pages/sso-product/controllers/reducer.js","webpack://gvirantd/./src/pages/sso-product/controllers/selectors.js","webpack://gvirantd/./src/pages/ticket-full-view/constants.js","webpack://gvirantd/./src/pages/ticketing-system/controllers/actions.js","webpack://gvirantd/./src/pages/ticketing-system/controllers/constants.js","webpack://gvirantd/./src/pages/ticketing-system/controllers/reducer.js","webpack://gvirantd/./src/pages/ticketing-system/controllers/selectors.js","webpack://gvirantd/./src/pages/transition-page/controllers/actions.js","webpack://gvirantd/./src/pages/transition-page/controllers/constants.js","webpack://gvirantd/./src/pages/transition-page/controllers/mapper/mapToReducerState.js","webpack://gvirantd/./src/pages/transition-page/controllers/reducer.js","webpack://gvirantd/./src/pages/transition-page/controllers/selectors.js","webpack://gvirantd/./src/pages/user-profile/components/hook/useFetchUserProfile.js","webpack://gvirantd/./src/pages/user-profile/components/bottom-content/UserBottomContent.js","webpack://gvirantd/./src/pages/user-profile/components/top-content/UserTopContent.js","webpack://gvirantd/./src/pages/user-profile/components/top-content/UserPrimaryInfo.js","webpack://gvirantd/./src/pages/user-profile/components/top-content/UserSocialLink.js","webpack://gvirantd/./src/pages/user-profile/components/top-content-edit/EditUserName.js","webpack://gvirantd/./src/pages/user-profile/components/top-content-edit/EditUserEmail.js","webpack://gvirantd/./src/pages/user-profile/components/top-content/UserName.js","webpack://gvirantd/./src/pages/user-profile/components/top-content/UserContactInfo.js","webpack://gvirantd/./src/pages/user-profile/components/top-content/UserContactHistory.js","webpack://gvirantd/./src/pages/user-profile/components/UserProfileError.js","webpack://gvirantd/./src/pages/user-profile/components/activity-log/UserActivityLogTab.js","webpack://gvirantd/./src/pages/user-profile/components/activity-log/UserActivitySummary.js","webpack://gvirantd/./src/pages/user-profile/components/activity-log/UserActivityDetailGrid.js","webpack://gvirantd/./src/pages/user-profile/components/activity-log/UserActivityIcon.js","webpack://gvirantd/./src/pages/user-profile/components/overview/UserProfileOverview.js","webpack://gvirantd/./src/pages/user-profile/components/bio/OverviewBio.js","webpack://gvirantd/./src/pages/user-profile/components/hook/useUpdateUserInfo.js","webpack://gvirantd/./src/pages/user-profile/components/form/utils.js","webpack://gvirantd/./src/pages/user-profile/components/form/AssetDownloadPreferencesForm.js","webpack://gvirantd/./src/pages/user-profile/components/overview/info/ViewOverviewInfo.js","webpack://gvirantd/./src/pages/user-profile/components/overview/info/EditOverviewInfo.js","webpack://gvirantd/./src/common/components/google-map-user-location/InfoWindow.js","webpack://gvirantd/./src/common/components/google-map-user-location/MarkerMap.js","webpack://gvirantd/./src/common/components/google-map-user-location/GoogleMapViewUserLocation.js","webpack://gvirantd/./src/pages/user-profile/components/overview/info/OverviewInfo.js","webpack://gvirantd/./src/pages/user-profile/components/overview/location/OverviewLocationsForm.js","webpack://gvirantd/./src/pages/user-profile/components/overview/location/OverviewLocations.js","webpack://gvirantd/./src/pages/user-profile/components/overview/location/OverviewLocationsIcon.js","webpack://gvirantd/./src/pages/user-profile/components/form/ChangePasswordForm.js","webpack://gvirantd/./src/pages/user-profile/components/bio/EditOverviewBio.js","webpack://gvirantd/./src/pages/user-profile/components/user-security/ChangePasswordModal.js","webpack://gvirantd/./src/pages/user-profile/components/user-security/SecurityLabel.js","webpack://gvirantd/./src/pages/user-profile/components/user-security/ChangePassword.js","webpack://gvirantd/./src/pages/user-profile/components/user-security/Multifactor.js","webpack://gvirantd/./src/hooks/user-profile/useEditOktaEmail.js","webpack://gvirantd/./src/pages/user-profile/components/user-security/OktaSsoModal.js","webpack://gvirantd/./src/pages/user-profile/components/user-security/OktaSso.js","webpack://gvirantd/./src/pages/user-profile/components/user-security/UserSecurityTab.js","webpack://gvirantd/./src/pages/workflow-template-full/controllers/actions.js","webpack://gvirantd/./src/pages/workflow-template-full/controllers/constants.js","webpack://gvirantd/./src/pages/workflow-template-full/controllers/reducer.js","webpack://gvirantd/./src/pages/workflow-template-full/controllers/selectors.js","webpack://gvirantd/./src/pages/workflow-template/controllers/actions.js","webpack://gvirantd/./src/pages/workflow-template/controllers/constants.js","webpack://gvirantd/./src/pages/workflow-template/controllers/reducer.js","webpack://gvirantd/./src/pages/workflow-template/controllers/selectors.js","webpack://gvirantd/./src/pages/workflow/controllers/actions.js","webpack://gvirantd/./src/pages/workflow/controllers/constants.js","webpack://gvirantd/./src/pages/workflow/controllers/mapToReducerState/index.js","webpack://gvirantd/./src/pages/workflow/controllers/reducer.js","webpack://gvirantd/./src/pages/workflow/controllers/selectors.js","webpack://gvirantd/./src/polyfills.js","webpack://gvirantd/./src/reducers.js","webpack://gvirantd/./src/redux/branding/actions.js","webpack://gvirantd/./src/redux/branding/constants.js","webpack://gvirantd/./src/redux/branding/reducer.js","webpack://gvirantd/./src/redux/branding/selectors.js","webpack://gvirantd/./src/redux/global/actions.js","webpack://gvirantd/./src/redux/global/constants.js","webpack://gvirantd/./src/utils/sesionStorage.js","webpack://gvirantd/./src/redux/global/reducer.js","webpack://gvirantd/./src/redux/global/selectors.js","webpack://gvirantd/./src/redux/ribbon/actions.js","webpack://gvirantd/./src/redux/ribbon/constants.js","webpack://gvirantd/./src/redux/ribbon/reducer.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/add-to-apl/AddProductToAPLModalFooter.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/add-to-apl/ExistedProductApl.js","webpack://gvirantd/./src/hooks/apl/useAddProductToApl.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/add-to-apl/AddProductToAPLModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/add-to-apl/AddToNewAPLModal.js","webpack://gvirantd/./src/pages/home/ribbon/Products.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-grid/OpenMember.js","webpack://gvirantd/./src/common/components/button/svg-icons/ICO_10.37.svg","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-grid/AddToBan.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-grid/ListBan.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-grid/BanMember.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-grid/FilterMemberSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-grid/SubscriptionControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-grid/SubscriptionMember.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-grid/MemAction.js","webpack://gvirantd/./src/pages/home/ribbon/MemberGrid.js","webpack://gvirantd/./src/pages/home/ribbon/AssetsGrid.js","webpack://gvirantd/./src/utils/ribbonRouter.js","webpack://gvirantd/./src/redux/ribbon/selectors.js","webpack://gvirantd/./src/redux/user/actions.js","webpack://gvirantd/./src/redux/user/constants.js","webpack://gvirantd/./src/redux/user/reducers.js","webpack://gvirantd/./src/redux/user/selectors.js","webpack://gvirantd/./src/services/aplDetail/endpoints.js","webpack://gvirantd/./src/services/aplDetail/index.js","webpack://gvirantd/./src/services/apl/endpoints.js","webpack://gvirantd/./src/services/apl/index.js","webpack://gvirantd/./src/services/assetProduct/endpoints.js","webpack://gvirantd/./src/services/assetProduct/index.js","webpack://gvirantd/./src/services/categoryManagement/endpoints.js","webpack://gvirantd/./src/services/categoryManagement/index.js","webpack://gvirantd/./src/services/chatServices/endpoints.js","webpack://gvirantd/./src/services/chatServices/index.js","webpack://gvirantd/./src/services/communicationTemplate/endpoints.js","webpack://gvirantd/./src/services/communicationTemplate/index.js","webpack://gvirantd/./src/services/creditCardEula/endpoints.js","webpack://gvirantd/./src/services/creditCardEula/index.js","webpack://gvirantd/./src/services/dashboard/index.js","webpack://gvirantd/./src/services/dashboard/endpoints.js","webpack://gvirantd/./src/services/digitalAsset/endpoints.js","webpack://gvirantd/./src/services/digitalAsset/index.js","webpack://gvirantd/./src/services/eulaMaintenance/endpoints.js","webpack://gvirantd/./src/services/eulaMaintenance/index.js","webpack://gvirantd/./src/services/ext-chat/index.js","webpack://gvirantd/./src/services/ext-chat/endpoints.js","webpack://gvirantd/./src/services/ext-meeting/index.js","webpack://gvirantd/./src/services/ext-meeting/endpoints.js","webpack://gvirantd/./src/services/favorite/index.js","webpack://gvirantd/./src/services/favorite/endpoints.js","webpack://gvirantd/./src/services/folder/endpoints.js","webpack://gvirantd/./src/services/folder/index.js","webpack://gvirantd/./src/services/grid/endpoints.js","webpack://gvirantd/./src/services/grid/index.js","webpack://gvirantd/./src/services/helpMaintenance/endpoints.js","webpack://gvirantd/./src/services/helpMaintenance/index.js","webpack://gvirantd/./src/services/help/index.js","webpack://gvirantd/./src/services/help/endpoints.js","webpack://gvirantd/./src/services/interoperability/index.js","webpack://gvirantd/./src/services/interoperability/endpoints.js","webpack://gvirantd/./src/services/login/endpoints.js","webpack://gvirantd/./src/services/login/index.js","webpack://gvirantd/./src/services/maintenanceForm/endpoints.js","webpack://gvirantd/./src/services/maintenanceForm/index.js","webpack://gvirantd/./src/services/manageSharing/endpoints.js","webpack://gvirantd/./src/services/manageSharing/index.js","webpack://gvirantd/./src/services/mapping/endpoints.js","webpack://gvirantd/./src/services/mapping/index.js","webpack://gvirantd/./src/services/markupMaintenance/endpoints.js","webpack://gvirantd/./src/services/markupMaintenance/index.js","webpack://gvirantd/./src/services/meetingNotification/index.js","webpack://gvirantd/./src/services/meetingNotification/endpoints.js","webpack://gvirantd/./src/services/memberMaintenance/endpoints.js","webpack://gvirantd/./src/services/memberMaintenance/index.js","webpack://gvirantd/./src/services/members/endpoints.js","webpack://gvirantd/./src/services/members/index.js","webpack://gvirantd/./src/services/minimumRequirements/endpoints.js","webpack://gvirantd/./src/services/minimumRequirements/index.js","webpack://gvirantd/./src/services/new-folder/index.js","webpack://gvirantd/./src/services/new-folder/endpoints.js","webpack://gvirantd/./src/services/payment/index.js","webpack://gvirantd/./src/services/payment/endpoints.js","webpack://gvirantd/./src/services/product/endpoints.js","webpack://gvirantd/./src/services/product/index.js","webpack://gvirantd/./src/services/qaSpec/index.js","webpack://gvirantd/./src/services/qaSpec/endpoints.js","webpack://gvirantd/./src/services/qas-require-field/index.js","webpack://gvirantd/./src/services/qas-require-field/endpoints.js","webpack://gvirantd/./src/services/query/endpoints.js","webpack://gvirantd/./src/services/query/index.js","webpack://gvirantd/./src/services/recipients-fields/endpoints.js","webpack://gvirantd/./src/services/recipients-fields/index.js","webpack://gvirantd/./src/services/reporting/endpoints.js","webpack://gvirantd/./src/services/reporting/index.js","webpack://gvirantd/./src/services/request-grid/endpoints.js","webpack://gvirantd/./src/services/request-grid/index.js","webpack://gvirantd/./src/services/roles-security/endpoints.js","webpack://gvirantd/./src/services/roles-security/index.js","webpack://gvirantd/./src/services/sso-approval/endpoints.js","webpack://gvirantd/./src/services/sso-approval/index.js","webpack://gvirantd/./src/services/sso-product/index.js","webpack://gvirantd/./src/services/sso-product/endpoints.js","webpack://gvirantd/./src/services/subscription/endpoints.js","webpack://gvirantd/./src/services/subscription/index.js","webpack://gvirantd/./src/services/tag-restrictions/index.js","webpack://gvirantd/./src/services/tag-restrictions/endpoints.js","webpack://gvirantd/./src/services/ticketingSystem/index.js","webpack://gvirantd/./src/services/ticketingSystem/endpoints.js","webpack://gvirantd/./src/services/transition-page/endpoints.js","webpack://gvirantd/./src/services/transition-page/index.js","webpack://gvirantd/./src/services/user/endpoints.js","webpack://gvirantd/./src/services/user/index.js","webpack://gvirantd/./src/services/videoCallServices/index.js","webpack://gvirantd/./src/services/videoCallServices/endpoints.js","webpack://gvirantd/./src/services/wfTemplate/endpoints.js","webpack://gvirantd/./src/services/wfTemplate/index.js","webpack://gvirantd/./src/services/workflow/endpoints.js","webpack://gvirantd/./src/services/workflow/index.js","webpack://gvirantd/./src/static/AllergenConstants.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/AplSampleRequestDynamicContentForm.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/AplSampleRequestEmailForm.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-full/MemberLayout.js","webpack://gvirantd/./src/common/components/button/svg-icons/ICO_10.30.svg","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-grid/ShowProducts.js","webpack://gvirantd/./src/common/components/button/svg-icons/ICO_10.31.svg","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-grid/ShowAssets.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-grid/ShowOverview.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-grid/ShowDetails.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-full/OfficeFacility.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-grid/ShowAll.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/member-full/EditMember.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-full/MemberFullAction.js","webpack://gvirantd/./src/common/components/button/svg-icons/ICO_10.26.svg","webpack://gvirantd/./src/pages/home/ribbon/components/controls/user-full/DateRange.js","webpack://gvirantd/./src/common/components/button/svg-icons/ICO_10.54.svg","webpack://gvirantd/./src/pages/home/ribbon/components/controls/user-full/DownloadTransaction.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/user-full/Transactions.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/workflow-grid/FilterSection.js","webpack://gvirantd/./src/pages/home/ribbon/AssetFull.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/EditCategory.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/CreateCategory.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/DeleteCategory.js","webpack://gvirantd/./src/pages/home/ribbon/Folders.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/EditPost.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/BackToPost.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/DeletePost.js","webpack://gvirantd/./src/pages/home/ribbon/HelpPostCreateView.js","webpack://gvirantd/./src/pages/home/ribbon/HelpPostFullView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/EditPostGridView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/CreatePost.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/DeletePosts.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/EditArticlesGridView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/CreateArticle.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/DeleteArticles.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/Backup.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/Restore.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/DeleteArticle.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/help/BackToArticle.js","webpack://gvirantd/./src/pages/home/ribbon/HelpArticleFullView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/eula/CloneEula.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/eula/CreateEula.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/eula/DeleteEulaGridView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/eula/ViewAcceptance.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/reporting/OpenReporting.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/reporting/CreateReporting.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/reporting/CloneReportingModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/reporting/CloneReporting.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/reporting/grid/OpenSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/reporting/ConfirmDeleteReporting.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/reporting/DeleteReporting.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/reporting/grid/DeleteReportSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/communication/grid-view/EditCommunicationTemplate.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/communication/grid-view/CreateCommunicationTemplate.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/communication/grid-view/DeleteCommunicationTemplate.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/communication/fullview/EditView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/communication/fullview/DeleteCommunicationTemplate.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/communication/fullview/BackToTemplate.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/member/Members.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/member/Users.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-maintenance-grid/MaintenanceInfoSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-maintenance-grid/MemberCommunicateSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/member-management/MemberManagementEditModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/member/MemberManagementEdit.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-maintenance-grid/MemberEditSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/member/ExportButton.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-maintenance-grid/MemberExportSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/member/NewUserControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/member/DeleteUserControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/member/ResetPasswordControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/member/EditUserControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/user-maintenance-grid/UserActionsSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-maintenance-grid/MemberTemplateSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-maintenance-grid/OpenMemberSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-maintenance-grid/AddRoleToMemberModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-maintenance-grid/MemberEditRoleSecuritySection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-maintenance-grid/member-action/MoveGlnToMember.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/member-maintenance-grid/member-action/index.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/user/UserReactive.js","webpack://gvirantd/./src/pages/home/ribbon/MemberMaintenanceGridView.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/user-maintenance-grid/MoveUserToMember.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/user-maintenance-grid/UnlockUser.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/user-management/AddUserRoleAction.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/user-management/AddRoleToUserModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/user-management/RemoveUserRoleAction.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/user-management/RemoveRoleFromUserModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/user-maintenance-grid/UserEditRoleSecuritySection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/user-maintenance-grid/FilterUsersSection.js","webpack://gvirantd/./src/pages/home/ribbon/UsersMaintenanceGridView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/query/OpenQuery.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/query/grid/OpenSection.js","webpack://gvirantd/./src/pages/home/ribbon/Queries.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/ixoneSection/ToggleSplashScreenSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/workflow-maintain/OpenWorkflow.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/workflow-maintain/CreateWorkflow.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/workflow-maintain/DeleteWorkflow.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/workflow-maintain/CloneWorkflow.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/wf-template-full/NewStepControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/wf-template-full/NewStepSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/wf-template-full/NewTaskControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/wf-template-full/NewTaskSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/wf-template-full/CloneTaskControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/wf-template-full/CloneTaskSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/wf-template-full/CloneStepControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/wf-template-full/CloneStepSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/OpenAPL.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/CreateMasterAplRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/RollbackToPreviousMasterAplRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/CreateApl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/EditAPLRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/DeleteAplControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/DownloadAplTemplate.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/components/APLModalFooter.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/components/CreateEditAplModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/components/APLConfirmUpdatePopup.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/components/UploadTemplateAPLModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/UpdateMasterAPLRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/AplGridActions.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/ExecuteMatchingGrid.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/DownloadAPL.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/OpenMapping.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/mapping/OpenSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/ShareControl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/mapping/ShareSection.js","webpack://gvirantd/./src/pages/mapping/components/mapping-details/SaveMappingConfigForm.js","webpack://gvirantd/./src/pages/mapping/components/mapping-details/SaveMappingConfig.js","webpack://gvirantd/./src/pages/mapping/components/mapping-details/CloneMappingConfigModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/CreateMapping.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/EditMapping.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/CloneMapping.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/DeleteMapping.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/FilterMapping.js","webpack://gvirantd/./src/pages/home/ribbon/ProductMapping.js","webpack://gvirantd/./src/pages/mapping/components/add-statement/utils.js","webpack://gvirantd/./src/pages/mapping/components/add-statement/hooks.js","webpack://gvirantd/./src/pages/mapping/components/add-statement/ShareComponents.js","webpack://gvirantd/./src/pages/mapping/components/add-statement/AddStatement.js","webpack://gvirantd/./src/pages/mapping/components/add-statement/MappingType.js","webpack://gvirantd/./src/pages/mapping/components/mapping-config/MappingConfig.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/config/CreateMappingConfig.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/config/EditMappingConfig.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/config/DeleteMappingConfig.js","webpack://gvirantd/./src/pages/mapping/components/mapping-config/CloneMappingConfigModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/mapping/config/CloneMappingConfig.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/EditInfoMetadata.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/ExecuteMatching.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/MatchPercent.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/send-invite/UpcProducts.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/utils.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/ModalCreateMeeting.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/send-invite/Invite.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/send-invite/SendMeetingInvite.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/SendQuestions.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/AddProductToApl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/DeleteProductApl.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/AplSendSomethingProductList.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/AplSendQuestion.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/utils.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/AplSendSomethingModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/RequestSample.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/SendAward.js","webpack://gvirantd/./src/pages/product-apl-detail/components/product-contact-modal/ProductContactModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/EditProductContact.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/Constants.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/utils.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/AplContactEmail.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/AplSendSampleRequestEditor.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/AplSendSampleRequestTemplateList.js","webpack://gvirantd/./src/pages/home/ribbon/components/modal/product-apl/AplSendSampleRequestModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/AplDetailActions.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/DownloadProductApl.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-apl/UploadProductApl.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product-apl/AplDetailTemplate.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/subscriiption/EditSubscription.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/subscriiption/Unsubscribe.js","webpack://gvirantd/./src/i18n/messages/subscription.js","webpack://gvirantd/./src/pages/subscription/components/new-gdsn-subscription/NewGdsnSubscriptionForm.js","webpack://gvirantd/./src/pages/subscription/components/new-gdsn-subscription/NewGdsnSubscriptionModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/subscriiption/NewGdsnSubscription.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/AcceptSubscription.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/RejectSubscription.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/product-full/RevokeSubscription.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/SubscriptionActionSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/markup/EditMarkupGridView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/markup/CreateMarkup.js","webpack://gvirantd/./src/common/queries/new-main-page-module.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/markup/DeleteMarkupGridView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/markup/BackToMarkup.js","webpack://gvirantd/./src/pages/home/ribbon/MaintenanceMarkupCreateView.js","webpack://gvirantd/./src/pages/home/ribbon/MaintenanceMarkupFullView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/curated-query/CreateCuratedQuery.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/curated-query/EditCuratedQuery.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/maintenance/curated-query/RevokeCuratedQuery.js","webpack://gvirantd/./src/i18n/messages/recipients-fields.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/recipients-fields/FormFieldItem.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/recipients-fields/FormFields.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/recipients-fields/ShareComponent.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/recipients-fields/CreateField.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/recipients-fields/EditField.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/recipients-fields/DeleteFields.js","webpack://gvirantd/./src/assets/dashboard/day.svg","webpack://gvirantd/./src/i18n/messages/dashboard.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/DayView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/WeekView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/MonthView.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/ScheduleView.js","webpack://gvirantd/./src/assets/dashboard/work-schedule.svg","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/NewMeeting.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/MeetingNow.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/DashboardLayout.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/CancelMeeting.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/EditMeeting.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/dashboard/ResetLayout.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/dashboard/LayoutSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/dashboard/ActionsMeeting.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/role-security-management/CreateNewRoleSection.js","webpack://gvirantd/./src/pages/home/ribbon/HomeBlank.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/publication/AcceptPublication.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/publication/utils.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/publication/RejectPublication.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/publication/ReviewPublication.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/product/PublicationSection.js","webpack://gvirantd/./src/assets/security-request/active-request.svg","webpack://gvirantd/./src/assets/security-request/created-by-me.svg","webpack://gvirantd/./src/assets/security-request/assign-to.svg","webpack://gvirantd/./src/pages/home/ribbon/security-request/FilterRequest.js","webpack://gvirantd/./src/pages/home/ribbon/transition-page/components/transition-page-grid/EditTransitionPageButton.js","webpack://gvirantd/./src/pages/home/ribbon/transition-page/components/transition-page-grid/CreateTransitionPageButton.js","webpack://gvirantd/./src/pages/home/ribbon/transition-page/components/transition-page-grid/ManipulateTransitionPageGridSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/transition-page/SaveEditTransitionPage.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-manange-grid/CloneFormBtn.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-manange-grid/DeleteFormBtn.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-manange-grid/UploadFormBtn.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-manange-grid/EditFormBtn.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-manange-grid/FormItemManipulationSection.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-manage-detail/DeleteFormBtn.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-manage-detail/ToggleFullScreenFormBtn.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-manage-detail/ToggleFloatModeFormBtn.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-manage-detail/SelectedDataPointInfo.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-manage-detail/FormDetailManipulationSection.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-excel/EditPreviewBtn.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/download-user-manual/SplashUserManual.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/download-user-manual/AcceptedFieldListing.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-history-grid/DownloadFormBtn.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/components/form-history-grid/FormHistoryDownloadSection.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/sso-approval/AcceptSsoApproval.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/sso-approval/RejectSsoApproval.js","webpack://gvirantd/./src/pages/home/ribbon/components/sections/sso-approval/SsoApprovalSection.js","webpack://gvirantd/./src/pages/sso-approval/button/FooterButton.js","webpack://gvirantd/./src/pages/sso-approval/modal/AssignMemberModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/sso-approval/AssignMemberSsoApproval.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/sso-approval/ToggleSsoApproval.js","webpack://gvirantd/./src/pages/sso-approval/modal/AssignUserModal.js","webpack://gvirantd/./src/pages/home/ribbon/components/controls/sso-approval/AssignUserSSoApproval.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-system/components/OpenTicketingSystem.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-system/components/CreateTicketModal.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-system/components/CreateTicketingSystem.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-system/components/DeleteTicketingSystem.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-system/components/FilterTicketingSystem.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-system/components/ExportTicketingSystem.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/ModalFormQasRequireField.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/CreateQasRequireField.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/DeleteQasRequireField.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/EditQasRequireField.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/ModalCopyQasRequireFields.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/CopyQasRequireFields.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/FormQasTargetMember.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/SectionQasRequireField.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/QasField.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/DraggableField.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/components/QasGroup.js","webpack://gvirantd/./src/pages/ticketing-group/hooks-query/useTicketingGroup.js","webpack://gvirantd/./src/pages/ticketing-group/controllers/actions.js","webpack://gvirantd/./src/pages/ticketing-group/controllers/constants.js","webpack://gvirantd/./src/pages/ticketing-group/controllers/reducer.js","webpack://gvirantd/./src/pages/ticketing-group/controllers/selectors.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-group/components/SaveTicketingGroupModal.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-group/components/CreateTicketingGroup.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-group/components/EditTicketingGroup.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-group/components/DeleteTicketingGroup.js","webpack://gvirantd/./src/static/Constants.js","webpack://gvirantd/./src/pages/home/ribbon/IxoneRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/MemberFull.js","webpack://gvirantd/./src/pages/home/ribbon/MemberCompanyFull.js","webpack://gvirantd/./src/pages/home/ribbon/UserFull.js","webpack://gvirantd/./src/pages/home/ribbon/WorkflowGrid.js","webpack://gvirantd/./src/pages/home/ribbon/transition-page/TransitionPage.js","webpack://gvirantd/./src/pages/home/ribbon/transition-page/TransitionPageDetail.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/FornManage.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/FormHistory.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/FormHistoryEntity.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/FormUpload.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/FormExcel.js","webpack://gvirantd/./src/pages/home/ribbon/form-manange/FormManangeDetail.js","webpack://gvirantd/./src/pages/home/ribbon/security-request/RequestGrid.js","webpack://gvirantd/./src/pages/home/ribbon/WorkflowAdministrationGridView.js","webpack://gvirantd/./src/pages/home/ribbon/WorkflowDetailRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/HelpMaintenanceCategory.js","webpack://gvirantd/./src/pages/home/ribbon/HelpPostGridView.js","webpack://gvirantd/./src/pages/home/ribbon/HelpArticlesGridView.js","webpack://gvirantd/./src/pages/home/ribbon/MaintenanceEulaGridView.js","webpack://gvirantd/./src/pages/home/ribbon/Reportings.js","webpack://gvirantd/./src/pages/home/ribbon/CommunicationTemplateGridView.js","webpack://gvirantd/./src/pages/home/ribbon/CommunicationTemplateFullView.js","webpack://gvirantd/./src/pages/home/ribbon/AssetForMember.js","webpack://gvirantd/./src/pages/home/ribbon/WorkflowMaintain.js","webpack://gvirantd/./src/pages/home/ribbon/WfTemplateFullView.js","webpack://gvirantd/./src/pages/home/ribbon/ProductForMemberRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/ProductSubScription.js","webpack://gvirantd/./src/pages/home/ribbon/OnlyCloseRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/ProductFullViewSheets.js","webpack://gvirantd/./src/pages/home/ribbon/ProductAPLGrid.js","webpack://gvirantd/./src/pages/home/ribbon/ProductMappingConfig.js","webpack://gvirantd/./src/pages/home/ribbon/ProductAPLDetail.js","webpack://gvirantd/./src/pages/home/ribbon/ProductSyndicationHistory.js","webpack://gvirantd/./src/pages/home/ribbon/MaintenanceMarkupGridView.js","webpack://gvirantd/./src/pages/home/ribbon/CuratedQueryGridView.js","webpack://gvirantd/./src/pages/home/ribbon/RecipientsFieldsGridView.js","webpack://gvirantd/./src/pages/home/ribbon/MySubscriptionGridView.js","webpack://gvirantd/./src/pages/home/ribbon/SubscriptionToGridView.js","webpack://gvirantd/./src/pages/home/ribbon/PublicationGridView.js","webpack://gvirantd/./src/pages/home/ribbon/RibbonRoleSecurityManage.js","webpack://gvirantd/./src/pages/home/ribbon/Dashboard.js","webpack://gvirantd/./src/pages/home/ribbon/sso-approval/SsoApprovalMemberRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/sso-approval/SsoApprovalUserRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-system/TicketingSystemRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/ticketing-group/TicketingGroupRibbon.js","webpack://gvirantd/./src/pages/home/ribbon/qas-require-field/QasRequireFieldRibbon.js","webpack://gvirantd/./src/static/CountryCode.js","webpack://gvirantd/./src/static/FileType.js","webpack://gvirantd/./src/static/HelpIcon.js","webpack://gvirantd/./src/assets/website.svg","webpack://gvirantd/./src/static/Icons.js","webpack://gvirantd/./src/assets/social-facebook.svg","webpack://gvirantd/./src/assets/twitter.svg","webpack://gvirantd/./src/assets/google.svg","webpack://gvirantd/./src/assets/LinkedIn.svg","webpack://gvirantd/./src/assets/instagram.svg","webpack://gvirantd/./src/static/MediaQuery.js","webpack://gvirantd/./src/static/Permission.js","webpack://gvirantd/./src/static/Theme.js","webpack://gvirantd/./src/static/TimeZones.js","webpack://gvirantd/./src/store/storeApp.js","webpack://gvirantd/./src/themes/index.js","webpack://gvirantd/./src/utils/SecureRoute.js","webpack://gvirantd/./src/utils/api.js","webpack://gvirantd/./src/utils/array.js","webpack://gvirantd/./src/utils/author.js","webpack://gvirantd/./src/utils/checkIsOwner.js","webpack://gvirantd/./src/utils/checkShowPdfPreview.js","webpack://gvirantd/./src/utils/common/checkStore.js","webpack://gvirantd/./src/utils/common/history.js","webpack://gvirantd/./src/utils/common/constants.js","webpack://gvirantd/./src/utils/common/sagaInjectors.js","webpack://gvirantd/./src/utils/common/injectSaga.js","webpack://gvirantd/./src/utils/common/injectedReducers.js","webpack://gvirantd/./src/utils/common/reducerInjectors.js","webpack://gvirantd/./src/utils/common/linkBuilder.js","webpack://gvirantd/./src/utils/common/route.js","webpack://gvirantd/./src/utils/common/session.js","webpack://gvirantd/./src/utils/contact.js","webpack://gvirantd/./src/utils/country.js","webpack://gvirantd/./src/utils/dataToMSoffice.js","webpack://gvirantd/./src/utils/delay.js","webpack://gvirantd/./src/utils/element.js","webpack://gvirantd/./src/utils/email-editor.js","webpack://gvirantd/./src/utils/entityTypeIcon.js","webpack://gvirantd/./src/utils/exportProductProperties.js","webpack://gvirantd/./src/utils/fileType.js","webpack://gvirantd/./src/utils/formatDate.js","webpack://gvirantd/./src/utils/formatSizeUnits.js","webpack://gvirantd/./src/utils/getGridName.js","webpack://gvirantd/./src/utils/image.js","webpack://gvirantd/./src/utils/index.js","webpack://gvirantd/./src/utils/jsonChecker.js","webpack://gvirantd/./src/utils/mfa.js","webpack://gvirantd/./src/utils/cookies.js","webpack://gvirantd/./src/static/minimumRequirementFieldsSchema.js","webpack://gvirantd/./src/utils/minimumRequirementUtils.js","webpack://gvirantd/./src/utils/parser.js","webpack://gvirantd/./src/utils/productHierarchy.js","webpack://gvirantd/./src/utils/queryCondition.js","webpack://gvirantd/./src/utils/saveFile.js","webpack://gvirantd/./src/utils/sortByKey.js","webpack://gvirantd/./src/utils/storage.js","webpack://gvirantd/./src/utils/string.js","webpack://gvirantd/./src/utils/timezone.js","webpack://gvirantd/./src/assets/product/case.svg","webpack://gvirantd/./src/assets/product/innerpack.svg","webpack://gvirantd/./src/assets/product/master-case.svg","webpack://gvirantd/./src/assets/product/pallet.svg","webpack://gvirantd/./src/assets/product/unit.svg","webpack://gvirantd/./src/assets/shared-ribbon/Share.svg","webpack://gvirantd/./src/common/components/button/svg-icons/ICO_10.28.svg","webpack://gvirantd/./src/common/components/button/svg-icons/ICO_10.46.svg","webpack://gvirantd/./src/common/components/button/svg-icons/add-folder.svg","webpack://gvirantd/./src/common/components/button/svg-icons/delete-folder.svg"],"sourcesContent":["import { Ability, AbilityBuilder } from '@casl/ability';\nimport {\n PERMISSION,\n WORKFLOW_ROLES,\n ABILITY_ACTION,\n ABILITY_SUBJECT,\n} from 'static/Permission';\n\nimport * as _ from 'lodash';\n\nimport {\n checkIsSharedOnlyMemberUser,\n checkIsSuperAdmin,\n checkIsSupplierMemberUser,\n} from 'utils';\n\nexport function defineRulesFor(userInfo, navData) {\n const { permissions, isSuperMember, roles } = userInfo;\n const isSuperAdmin = checkIsSuperAdmin(roles);\n\n const { can, rules, cannot } = new AbilityBuilder();\n\n _.toArray(ABILITY_ACTION).forEach(\n (action) =>\n action !== ABILITY_ACTION.MANAGE && can(action, ABILITY_SUBJECT.ALL_AUTH)\n );\n\n getRuleFromPermissionList({\n navData,\n permissions,\n can,\n cannot,\n isSuperMember,\n isSuperAdmin,\n userInfo,\n });\n\n return rules;\n}\n\nexport function defineRulesForWorkflow(userInfo, workflowRoles, navData) {\n const { can, rules, cannot } = new AbilityBuilder();\n const { canAccessWorkflow } = navData;\n\n const isSupplierMemberUser = checkIsSupplierMemberUser(userInfo);\n const isSharedOnLyMemberUser = checkIsSharedOnlyMemberUser(userInfo);\n\n const { roles, isSuperMember } = userInfo;\n const isSuperAdmin = checkIsSuperAdmin(roles);\n\n workflowRoles &&\n workflowRoles.length > 0 &&\n workflowRoles.forEach((workflowRole) => {\n switch (workflowRole.roleName) {\n case WORKFLOW_ROLES.APPROVER:\n can(ABILITY_ACTION.APPROVE, ABILITY_SUBJECT.WORKFLOW_STEP);\n break;\n case WORKFLOW_ROLES.PARTICIPANT:\n // TODO: Change ABILITY_ACTION later\n break;\n case WORKFLOW_ROLES.INITIATOR:\n // TODO: Change ABILITY_ACTION later\n break;\n case WORKFLOW_ROLES.CREATOR:\n canAccessWorkflow &&\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.WORKFLOW_MAINTENANCE);\n canAccessWorkflow &&\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.WORKFLOW_DEFINITION);\n break;\n case WORKFLOW_ROLES.ADMINISTRATOR:\n canAccessWorkflow &&\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.WORKFLOW);\n canAccessWorkflow &&\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.WORKFLOW_MAINTENANCE);\n canAccessWorkflow &&\n can(\n ABILITY_ACTION.MAINTAIN,\n ABILITY_SUBJECT.WORKFLOW_ADMINISTRATION\n );\n canAccessWorkflow &&\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.WORKFLOW_DEFINITION);\n break;\n\n default:\n break;\n }\n });\n\n if (\n (isSharedOnLyMemberUser && !isSuperMember && !isSuperAdmin) ||\n !canAccessWorkflow\n ) {\n cannot(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.WORKFLOW);\n cannot(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.WORKFLOW_MAINTENANCE);\n cannot(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.WORKFLOW_ADMINISTRATION);\n cannot(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.WORKFLOW_DEFINITION);\n }\n\n if (isSuperAdmin) {\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.WORKFLOW);\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.WORKFLOW_MAINTENANCE);\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.WORKFLOW_ADMINISTRATION);\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.WORKFLOW_DEFINITION);\n can(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.WORKFLOW);\n }\n\n return rules;\n}\n\n/**\n * ! get casl rule from permisison list\n * @param {*} navData\n * @param {*} permissions\n * @param {*} can\n * @param {*} isSuperMember\n * @param {*} userInfo\n */\nconst getRuleFromPermissionList = ({\n navData,\n permissions,\n can,\n cannot,\n isSuperMember,\n isSuperAdmin,\n userInfo,\n}) => {\n const {\n canAccessChat,\n canAccessDigitalAssets,\n canAccessFolders,\n canAccessMember,\n canAccessProducts,\n canAccessReporting,\n canManageHelpSystem,\n canAccessQaSpec,\n canAccessFTP,\n canAccessInterops,\n canAccessSyndication,\n canAccessGdsn,\n canAccessWorkflow,\n canAccessTicketSystem,\n // BP 11/19/2021: remove 3 options\n // 3 options do not have requirements\n /* canAccessThirdPartyAPI,\n canAccessVideoConf,\n canAccessVideoStreaming, */\n // end BP 11/19/2021: remove 3 options\n\n // canAccessWorkflowAdministration,\n // canAccessWorkflowDefinition,\n // canAccessWorkflowMaintenance,\n } = navData;\n\n const userMemberType = userInfo?.member?.memberType?.toLowerCase();\n\n //? default permission\n if (true) {\n can(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.SPLASH_DOWNLOAD_HISTORY);\n can(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.MY_QUERY);\n can(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.SHARED_QUERY);\n }\n\n const isSupplierMemberUser = checkIsSupplierMemberUser(userInfo);\n const isSharedOnLyMemberUser = checkIsSharedOnlyMemberUser(userInfo);\n\n permissions &&\n permissions.length > 0 &&\n permissions.forEach((permission) => {\n switch (permission) {\n case PERMISSION.VIEW_USERS:\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.USER);\n break;\n // DAM view\n case PERMISSION.VIEW_ASSETS:\n canAccessDigitalAssets &&\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.ASSET);\n break;\n case PERMISSION.CREATE_ASSETS:\n canAccessDigitalAssets &&\n can(ABILITY_ACTION.CREATE, ABILITY_SUBJECT.ASSET);\n break;\n\n case PERMISSION.EDIT_ASSET:\n if (canAccessDigitalAssets) {\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.ASSET);\n\n if (isSuperMember) {\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.SHARED_ASSET);\n }\n }\n break;\n\n case PERMISSION.DELETE_ASSETS:\n if (canAccessDigitalAssets) {\n can(ABILITY_ACTION.DELETE, ABILITY_SUBJECT.ASSET);\n\n if (isSuperMember) {\n can(ABILITY_ACTION.DELETE, ABILITY_SUBJECT.SHARED_ASSET);\n }\n }\n\n break;\n // end DAM view\n\n // PIM view\n case PERMISSION.VIEW_PRODUCTS:\n if (canAccessProducts) {\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.PRODUCT);\n if (!isSharedOnLyMemberUser) {\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.PRODUCT_APL);\n }\n }\n break;\n\n case PERMISSION.EDIT_PRODUCT:\n if (canAccessProducts) {\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.PRODUCT);\n\n if (isSuperMember) {\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.SHARED_PRODUCT);\n }\n\n if (isSupplierMemberUser) {\n can(\n ABILITY_ACTION.EDIT,\n ABILITY_SUBJECT.SUPPLIER_ASSIGNED_PRODUCT\n );\n }\n\n if (isSharedOnLyMemberUser) {\n can(\n ABILITY_ACTION.EDIT,\n ABILITY_SUBJECT.SHARED_ONLY_ASSIGNED_PRODUCT\n );\n }\n }\n break;\n\n case PERMISSION.CREATE_PRODUCT:\n canAccessProducts &&\n can(ABILITY_ACTION.CREATE, ABILITY_SUBJECT.PRODUCT);\n break;\n\n case PERMISSION.DELETE_PRODUCTS:\n if (canAccessProducts) {\n can(ABILITY_ACTION.DELETE, ABILITY_SUBJECT.PRODUCT);\n\n if (isSuperMember) {\n can(ABILITY_ACTION.DELETE, ABILITY_SUBJECT.SHARED_PRODUCT);\n }\n }\n break;\n // end PIM view\n\n // My company view\n case PERMISSION.VIEW_FULL_COMPANY_PROFILE:\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.COMPANY_PROFILE);\n break;\n // End my company view\n\n // Reporting view\n case PERMISSION.VIEW_REPORTING:\n canAccessReporting &&\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.REPORTING);\n break;\n case PERMISSION.CREATE_REPORTING:\n canAccessReporting &&\n can(ABILITY_ACTION.CREATE, ABILITY_SUBJECT.REPORTING);\n break;\n case PERMISSION.EDIT_REPORTING:\n canAccessReporting &&\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.REPORTING);\n break;\n case PERMISSION.DELETE_REPORTING:\n canAccessReporting &&\n can(ABILITY_ACTION.DELETE, ABILITY_SUBJECT.REPORTING);\n break;\n // end reporting view\n\n // Folder view\n case PERMISSION.VIEW_FOLDERS:\n canAccessFolders && can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.FOLDER);\n break;\n case PERMISSION.EDIT_FOLDER:\n canAccessFolders && can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.FOLDER);\n break;\n case PERMISSION.CREATE_FOLDER:\n canAccessFolders &&\n can(ABILITY_ACTION.CREATE, ABILITY_SUBJECT.FOLDER);\n canAccessFolders && can(ABILITY_ACTION.COPY, ABILITY_SUBJECT.FOLDER);\n break;\n case PERMISSION.DELETE_FOLDERS:\n canAccessFolders &&\n can(ABILITY_ACTION.DELETE, ABILITY_SUBJECT.FOLDER);\n break;\n // end folder view\n\n case PERMISSION.VIEW_SHARED_ENTITIES:\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.SHARED_ENTITY);\n break;\n case PERMISSION.MANAGE_SHARED_ENTITIES:\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.SHARED_ENTITY);\n break;\n\n // Help view\n case PERMISSION.VIEW_HELP_CATEGORIES:\n canManageHelpSystem &&\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.HELP_CATEGORY);\n break;\n case PERMISSION.MANAGE_HELP_CATEGORY:\n canManageHelpSystem &&\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.HELP_CATEGORY);\n break;\n case PERMISSION.VIEW_HELP_POSTS:\n canManageHelpSystem &&\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.HELP_POST);\n break;\n case PERMISSION.MANAGE_HELP_POST:\n canManageHelpSystem &&\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.HELP_POST);\n break;\n case PERMISSION.VIEW_ARTICLES:\n canManageHelpSystem &&\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.ARTICLE);\n break;\n case PERMISSION.MANAGE_ARTICLES:\n canManageHelpSystem &&\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.ARTICLE);\n break;\n // end Help view\n\n case PERMISSION.VIEW_EULAS:\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.EULA);\n break;\n case PERMISSION.MANAGE_EULAS:\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.EULA);\n break;\n case PERMISSION.VIEW_COMMUNICATION_TEMPLATE:\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.COMMUNICATION_TEMPLATE);\n break;\n case PERMISSION.MANAGE_COMMUNICATION_TEMPLATE:\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.COMMUNICATION_TEMPLATE);\n break;\n\n case PERMISSION.EDIT_COMPANY_PROFILE:\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.COMPANY_PROFILE);\n break;\n case PERMISSION.VIEW_MEMBER_DEFINED_PROPERTIES:\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.MEMBER_DEFINED_PROPERTIES);\n break;\n case PERMISSION.EDIT_MEMBER_DEFINED_PROPERTIES:\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.MEMBER_DEFINED_PROPERTIES);\n break;\n case PERMISSION.EDIT_USERS_PERMISSIONS:\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.USER_PERMISSIONS);\n break;\n\n // Members view\n case PERMISSION.VIEW_MEMBERS:\n canAccessMember && can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.MEMBER);\n break;\n case PERMISSION.CREATE_MEMBER:\n can(ABILITY_ACTION.CREATE, ABILITY_SUBJECT.MEMBER);\n break;\n case PERMISSION.EDIT_MEMBER:\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.MEMBER);\n break;\n // end Members view\n\n case PERMISSION.EXECUTE_COMMUNICATION_TEMPLATE:\n can(ABILITY_ACTION.EXECUTE, ABILITY_SUBJECT.COMMUNICATION_TEMPLATE);\n break;\n case PERMISSION.CREATE_USER:\n can(ABILITY_ACTION.CREATE, ABILITY_SUBJECT.USER);\n break;\n case PERMISSION.EDIT_USER:\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.USER);\n break;\n case PERMISSION.DELETE_USERS:\n can(ABILITY_ACTION.DELETE, ABILITY_SUBJECT.USER);\n break;\n case PERMISSION.SUPER_ADMIN:\n can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.ALL);\n break;\n case PERMISSION.VIEW_MANAGE_MEMBER:\n // bp 11/19/2021: comment VIEW MEMBER if user has VIEW_MANAGE_MEMBER\n // can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.MEMBER);\n // can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.COMPANY_PROFILE);\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.MANAGE_MEMBER);\n\n break;\n case PERMISSION.MANAGE_BAN_LIST:\n can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.BAN_LIST);\n break;\n case PERMISSION.CHAT_CALL_VIDEO_VIA_COMPANY_ACCOUNT:\n if (userInfo?.receiveCompanyCommunications)\n canAccessChat &&\n can(ABILITY_ACTION.CHAT, ABILITY_SUBJECT.CHAT_COMPANY);\n break;\n case PERMISSION.CHAT_CALL_VIDEO_VIA_PERSONAL_ACCOUNT:\n canAccessChat &&\n can(ABILITY_ACTION.CHAT, ABILITY_SUBJECT.CHAT_PERSONAL);\n break;\n\n case PERMISSION.MANAGE_CURATED_QUERY:\n can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.CURATED_QUERY);\n break;\n case PERMISSION.MANAGE_PIM_MAPPING:\n can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.PIM_MAPPING);\n break;\n\n case PERMISSION.VIEW_NEW_ITEM_FORMS:\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.NEW_ITEM_FORMS);\n break;\n case PERMISSION.IMPERSONATE_USER:\n can(ABILITY_ACTION.IMPERSONATE, ABILITY_SUBJECT.USER);\n break;\n case PERMISSION.IMPERSONATE_MEMBER:\n can(ABILITY_ACTION.IMPERSONATE, ABILITY_SUBJECT.MEMBER);\n break;\n case PERMISSION.VIEW_QA_SPECIFICATION:\n canAccessQaSpec &&\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.QA_SPECIFICATION);\n break;\n case PERMISSION.EDIT_QA_SPECIFICATION:\n canAccessQaSpec &&\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.QA_SPECIFICATION);\n break;\n\n case PERMISSION.VIEW_EVALUATION_FORM:\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.EVALUATION_FORM);\n break;\n case PERMISSION.EDIT_EVALUATION_FORM:\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.EVALUATION_FORM);\n break;\n\n // New CREDIT CARD\n // case PERMISSION.MANAGE_MEMBER_CREDIT_CARD:\n // can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.MEMBER_CREDIT_CARD);\n // break;\n // case PERMISSION.PAY_WITH_MEMBER_CREDIT_CARD:\n // can(ABILITY_ACTION.PAY, ABILITY_SUBJECT.MEMBER_CREDIT_CARD);\n // break;\n // END\n case PERMISSION.MANAGE_MEMBER_CREDIT_CARD:\n can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.CREDIT_CARD);\n break;\n case PERMISSION.PAY_WITH_MEMBER_CREDIT_CARD:\n can(ABILITY_ACTION.PAY, ABILITY_SUBJECT.CREDIT_CARD);\n break;\n case PERMISSION.MANAGE_BILLABLE_TRACKING:\n can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.BILLABLE_TRACKING);\n break;\n case PERMISSION.EDIT_BRAND:\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.BRAND);\n break;\n case PERMISSION.MANAGE_MEMBER_CATEGORIES:\n can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.MEMBER_CATEGORIES);\n break;\n case PERMISSION.ASSIGN_PRODUCT_CATEGORY:\n can(ABILITY_ACTION.ASSIGN, ABILITY_SUBJECT.PRODUCT_CATEGORY);\n break;\n // TICKET SYSTEM\n case PERMISSION.VIEW_TICKET:\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.TICKET_SYSTEM);\n break;\n case PERMISSION.CREATE_TICKET:\n can(ABILITY_ACTION.CREATE, ABILITY_SUBJECT.TICKET_SYSTEM);\n break;\n case PERMISSION.EDIT_TICKET:\n can(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.TICKET_SYSTEM);\n break;\n case PERMISSION.DELETE_TICKET:\n can(ABILITY_ACTION.DELETE, ABILITY_SUBJECT.TICKET_SYSTEM);\n break;\n case PERMISSION.MANAGE_TICKET_GROUP:\n can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.TICKET_SYSTEM_GROUP);\n break;\n case PERMISSION.MANAGE_QA_SPEC_WORKFLOW:\n canAccessWorkflow &&\n can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.QA_SPEC_WORKFLOW);\n break;\n case PERMISSION.MANAGE_SYNDICATION:\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.SYNDICATION);\n break;\n case PERMISSION.MEMBER_BILLING_MANAGEMENT:\n can(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.MEMBER_BILLING_MANAGEMENT);\n break;\n default:\n break;\n }\n });\n\n if (canAccessGdsn) {\n can(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.GDSN);\n can(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.RECIPIENTS_FIELDS);\n }\n\n if (userMemberType === 'retailer' || userMemberType === 'distributor') {\n can(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.GDSN_RECEIVED_PRODUCT);\n can(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.MY_SUBSCRIPTIONS);\n }\n\n if (canAccessSyndication) {\n can(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.SYNDICATION);\n }\n\n if (canAccessWorkflow) {\n can(ABILITY_ACTION.MAINTAIN, ABILITY_SUBJECT.WORKFLOW);\n can(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.WORKFLOW);\n }\n\n if (!canAccessTicketSystem && !isSuperMember && !isSuperAdmin) {\n cannot(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.TICKET_SYSTEM);\n cannot(ABILITY_ACTION.CREATE, ABILITY_SUBJECT.TICKET_SYSTEM);\n cannot(ABILITY_ACTION.EDIT, ABILITY_SUBJECT.TICKET_SYSTEM);\n cannot(ABILITY_ACTION.DELETE, ABILITY_SUBJECT.TICKET_SYSTEM);\n cannot(ABILITY_ACTION.MANAGE, ABILITY_SUBJECT.TICKET_SYSTEM_GROUP);\n }\n\n if (isSharedOnLyMemberUser && !isSuperMember && !isSuperAdmin) {\n cannot(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.RECIPIENTS_FIELDS);\n cannot(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.SPLASH_DOWNLOAD_HISTORY);\n cannot(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.GDSN);\n cannot(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.MY_QUERY);\n cannot(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.SHARED_QUERY);\n }\n\n // if (isSupplierMemberUser && !isSuperMember && !isSuperAdmin) {\n // // cannot(ABILITY_ACTION.VIEW, ABILITY_SUBJECT.RECIPIENTS_FIELDS);\n // // cannot(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.SPLASH_DOWNLOAD_HISTORY);\n // // cannot(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.GDSN);\n // // cannot(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.MY_QUERY);\n // // cannot(ABILITY_ACTION.ACCESS, ABILITY_SUBJECT.SHARED_QUERY);\n // }\n};\n\n/**\n * Defines how to detect object's type\n * @param {*} item\n */\nfunction subjectName(item) {\n if (!item || typeof item === 'string') {\n return item;\n }\n\n return item.__type;\n}\n\nconst ability = new Ability([], { subjectName });\n\nexport default ability;\n","import React from 'react';\nimport { Row, Typography } from 'antd';\nimport PropTypes from 'prop-types';\nimport './AdvancedSearchTitle.less';\n\nconst AdvancedSearchTitle = (props) => {\n const { title } = props;\n return (\n \n \n {title}\n \n \n );\n};\nAdvancedSearchTitle.propTypes = {\n title: PropTypes.string,\n};\nexport default React.memo(AdvancedSearchTitle);\n","import React, { useState, useEffect } from 'react';\n\nimport { Modal } from 'antd';\nimport { UploadFile } from 'common/components';\n\nimport ErrorModal from 'common/components/product-publication-setup/ErrorModal.js';\n\nimport * as services from 'services/reporting/endpoints';\n\nimport { UPLOAD_MAX_SIZE } from 'static/Constants';\n\nimport './ModalUploadAvancedFile.less';\n\nconst ModalUploadAdvancedFile = (props) => {\n const { visibleModal, setVisibleModal, handleUploadAdvancedFile } = props;\n\n const [errorList, setErrorList] = useState([]);\n\n useEffect(() => {\n if (visibleModal) setErrorList([]);\n }, [visibleModal]);\n\n const handleResponseUpload = (response) => {\n if (response?.data) {\n if (response?.data?.isSuccess) {\n setVisibleModal(false);\n handleUploadAdvancedFile(response?.data?.data);\n } else {\n if (response?.data?.errors) {\n setErrorList(response?.data?.errors);\n }\n }\n }\n };\n\n return (\n setVisibleModal(false)}\n closable={true}\n maskClosable={false}\n footer={null}\n destroyOnClose\n centered\n >\n
\n handleResponseUpload(response)}\n maxSize={UPLOAD_MAX_SIZE.GENERAL}\n supportTypes={['xlsx', 'xls', 'xlsm', 'txt']}\n />\n
\n
\n {errorList && errorList.length > 0 && (\n \n )}\n
\n \n );\n};\n\nexport default ModalUploadAdvancedFile;\n","import React from 'react';\n\nimport { Link } from 'react-router-dom';\n\nconst CellRenderLink = (params) => {\n const { colDef, data, value } = params;\n\n const href = createHref(colDef.linkTo, data);\n\n return (\n \n {value}\n \n );\n};\n\nconst createHref = (linkTo, data) => {\n if (!linkTo) return linkTo;\n\n let href = linkTo;\n const regex = new RegExp(/(?:\\{)([^{}]+)(?:\\})/gs); // match every character in {}\n\n const params = linkTo.match(regex);\n params?.length &&\n params.forEach((match) => {\n let removeCurly = match.replace(/[{}]/g, '');\n href = href.replace(match, data?.[removeCurly]);\n });\n\n return href;\n};\n\nexport default CellRenderLink;\n","import React from 'react';\nimport { useSelector } from 'react-redux';\nimport { Provider } from 'react-redux';\n\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\n\nimport { DragWrap, DragDropWrapUtils } from 'common/components';\n\nimport store from 'store/storeApp';\n\nconst DragRender = (props) => {\n const { data } = props;\n\n const detailCurrentItemsSelection = useSelector(\n selectorsGridView.makeSelectDetailCurrentITemsSelection()\n );\n\n return (\n \n \n \n \n \n );\n};\n\nexport default DragRender;\n","import React from 'react';\n\nimport { Checkbox } from 'antd';\n\nconst CheckboxSelectionRender = (props) => {\n const { value } = props;\n return (\n \n );\n};\n\nexport default CheckboxSelectionRender;\n","import React from 'react';\n\nexport const GridContext = React.createContext({});\n","import React, { useContext } from 'react';\nimport { GridContext } from '../../context/gridContext';\n\nconst HeaderCheckboxRender = (props) => {\n const gridContext = useContext(GridContext);\n\n const { urlGrid } = props;\n\n const handleClick = (e) => {\n const { onHeaderCheckboxClick } = gridContext;\n\n const firstRow = props.api.getDisplayedRowAtIndex(0);\n if (firstRow?.data === undefined) return;\n\n onHeaderCheckboxClick(e, props);\n };\n\n return (\n \n \n \n \n );\n};\n\nexport default HeaderCheckboxRender;\n","import React from 'react';\n\nconst HeaderNullRender = () => {\n return ;\n};\n\nexport default HeaderNullRender;\n","import React from 'react';\n\nimport { Checkbox } from 'antd';\n\nconst CheckboxRenderer = (params) => {\n return ;\n};\n\nexport default CheckboxRenderer;\n","import React from 'react';\n\nimport { Row, Button, Space } from 'antd';\n\nexport default function ApplyFilter(event) {\n const handleApply = () => {\n const key = event?.colDef?.field;\n // Get a reference to the 'name' filter instance\n const filter = event?.api?.getFilterInstance(key);\n\n // Apply the model to ensure any changes in the UI or via API methods are recognised\n filter?.applyModel();\n\n // Tell grid to run filter operation again\n event?.api?.onFilterChanged();\n event?.api?.hidePopupMenu();\n };\n const handleReset = () => {\n const key = event?.colDef?.field;\n // Get a reference to the 'name' filter instance\n const filter = event?.api?.getFilterInstance(key);\n filter?.setModel(undefined);\n // Apply the model to ensure any changes in the UI or via API methods are recognised\n filter?.applyModel();\n\n // Tell grid to run filter operation again\n event?.api?.onFilterChanged();\n event?.api?.hidePopupMenu();\n };\n return (\n \n \n \n \n \n \n );\n}\n","import { useMemo } from 'react';\n\nimport * as _ from 'lodash';\n\nimport ApplyFilter from '../components/ApplyFilter';\n\nimport {\n GET_FAVORITE_PRODUCT_DETAIL_CUSTOMIZED_GRID,\n GET_PRODUCT_DETAIL_CUSTOMIZED_GRID,\n} from 'services/product/endpoints';\n\nconst URL_LIST_TO_DISABLE_SORT_IS_OWNER = [\n GET_PRODUCT_DETAIL_CUSTOMIZED_GRID,\n GET_FAVORITE_PRODUCT_DETAIL_CUSTOMIZED_GRID,\n];\n\nconst useGetColumnDefs = ({\n urlGrid,\n columnDefs,\n notShowHeaderCheckbox,\n hideAgSetColumnFilter,\n}) => {\n const procColDef = useMemo(() => {\n if (!columnDefs) return [];\n let nextColDefs = [];\n\n columnDefs.forEach((colDef, index) => {\n if (colDef && colDef?.checkboxSelection) {\n nextColDefs.push({\n ...colDef,\n width: 60,\n field: 'checkboxSelection',\n filter: false,\n sortable: false,\n resizable: false,\n suppressMenu: true,\n cellRenderer: 'CheckboxSelectionRender',\n\n headerComponent: !notShowHeaderCheckbox\n ? 'HeaderCheckboxRender'\n : 'HeaderNullRender',\n headerComponentParams: {\n urlGrid,\n },\n checkboxSelection: false,\n header: true,\n });\n return;\n }\n\n if (colDef && colDef.field === 'dragColumn') {\n nextColDefs.push({\n ...colDef,\n width: 50,\n field: 'dragColumn',\n filter: false,\n sortable: false,\n resizable: false,\n suppressMenu: true,\n cellRenderer: 'DragRender',\n headerComponent: () => null,\n });\n return;\n }\n\n nextColDefs.push({\n headerName: colDef && colDef.headerName,\n headerClass: colDef && colDef.headerClass,\n field: (colDef && colDef.field) || colDef.fieldNameCamelCase,\n width: colDef && colDef.width,\n minWidth: colDef && colDef.minWidth,\n maxWidth: colDef && colDef.maxWidth,\n flex: colDef && colDef.flex,\n filter: getFilter(colDef),\n filterParams: getFilterParams(colDef, hideAgSetColumnFilter),\n\n filterFramework: colDef && colDef.filterFramework,\n hide: colDef && colDef.hide,\n pinned: colDef && colDef.pinned,\n lockPosition: colDef && colDef.lockPosition,\n lockVisible: colDef && colDef.lockVisible,\n lockPinned: colDef && colDef.lockPinned,\n sortable: getSortable(colDef),\n sort: colDef && colDef.sort,\n sortIndex: null,\n resizable: colDef && colDef.resizable,\n cellRendererFramework:\n colDef && colDef.dataType !== 'boolean'\n ? colDef.linkTo\n ? 'LinkRender'\n : colDef.cellRenderer\n : 'CheckboxRender',\n\n cellRenderer:\n colDef && colDef.dataType !== 'boolean'\n ? colDef.linkTo\n ? 'LinkRender'\n : colDef.cellRenderer\n : 'CheckboxRender',\n\n valueFormatter: colDef && colDef.valueFormatter,\n suppressMenu: colDef && colDef.suppressMenu,\n key: index,\n rowDrag: colDef && colDef.rowDrag,\n orgFieldName: colDef && colDef.orgFieldName,\n separateFieldName: colDef && colDef.separateFieldName,\n displayName: colDef && colDef.displayName,\n linkTo: colDef && colDef.linkTo,\n linkTarget: colDef && colDef.linkTarget,\n valueGetter: colDef && colDef.valueGetter,\n cellStyle: colDef && colDef.cellStyle,\n headerComponent: colDef?.headerComponent,\n });\n });\n\n nextColDefs = nextColDefs.map((colItem) => {\n if (URL_LIST_TO_DISABLE_SORT_IS_OWNER.includes(urlGrid)) {\n if (colItem?.field === 'isOwner') {\n return { ...colItem, sortable: false };\n }\n }\n\n return { ...colItem };\n });\n\n return nextColDefs;\n }, [columnDefs, hideAgSetColumnFilter, notShowHeaderCheckbox, urlGrid]);\n\n return procColDef;\n};\n\nconst getFilter = (colDef) => {\n const disabledFilterType = ['boolean', 'subscriptionshieldtype'];\n\n if (!colDef) return false;\n\n if (!colDef?.allowFilter) return false;\n\n if (colDef?.filter) return colDef.filter;\n\n if (colDef.isShowFilter === 'none') return false;\n\n if (disabledFilterType.indexOf(colDef.dataType) > -1) return false;\n\n return 'agMultiColumnFilter';\n};\n\nconst getSortable = (colDef) => {\n const disabledSortableType = ['boolean', 'subscriptionshieldtype'];\n\n if (!colDef) return false;\n\n if (disabledSortableType.indexOf(colDef?.dataType) > -1) return false;\n\n return colDef?.allowSort;\n};\n\nconst filterParamsButton = {\n buttons: ['apply', 'reset'],\n closeOnApply: true,\n};\n\nconst getFilterParams = (data, hideAgSetColumnFilter) => {\n let textFilter =\n data.dataType === 'string'\n ? 'agTextColumnFilter'\n : data.dataType === 'int' ||\n data.dataType === 'decimal' ||\n data.dataType === 'int32' ||\n data.dataType === 'int64'\n ? 'agNumberColumnFilter'\n : data.dataType === 'datetime'\n ? 'agDateColumnFilter'\n : true;\n let filter = !data.allowFilter ? false : textFilter;\n filter = data?.filter === 'agSetColumnFilter' ? data?.filter : filter;\n let filterParams = {};\n\n if (filter === 'agTextColumnFilter') {\n let isHideAgSetColumnFilter =\n typeof hideAgSetColumnFilter === 'string'\n ? data.fieldName === hideAgSetColumnFilter\n : _.isArray(hideAgSetColumnFilter)\n ? hideAgSetColumnFilter.includes(data.fieldName)\n : false;\n\n if (isHideAgSetColumnFilter) {\n filterParams = {\n filters: [\n {\n filter: 'agTextColumnFilter',\n filterParams: {\n filterOptions: [\n 'contains',\n 'equals',\n 'notEqual',\n 'blank',\n 'notBlank',\n ],\n suppressAndOrCondition: true,\n ...filterParamsButton,\n },\n },\n {\n filter: ApplyFilter,\n },\n ],\n };\n } else {\n filterParams = {\n filters: [\n {\n filter: 'agTextColumnFilter',\n filterParams: {\n filterOptions: [\n 'contains',\n 'equals',\n 'notEqual',\n 'blank',\n 'notBlank',\n ],\n suppressAndOrCondition: true,\n ...filterParamsButton,\n },\n },\n {\n filter: 'agSetColumnFilter',\n filterParams: {\n ...filterParamsButton,\n },\n },\n {\n filter: ApplyFilter,\n },\n ],\n };\n }\n }\n if (filter === 'agNumberColumnFilter') {\n filterParams = {\n filters: [\n {\n filter: 'agNumberColumnFilter',\n filterParams: {\n filterOptions: [\n 'equals',\n 'notEqual',\n 'lessThan',\n 'lessThanOrEqual',\n 'greaterThan',\n 'greaterThanOrEqual',\n ],\n ...filterParamsButton,\n suppressAndOrCondition: true,\n },\n },\n {\n filter: 'agSetColumnFilter',\n filterParams: {\n ...filterParamsButton,\n },\n },\n {\n filter: ApplyFilter,\n },\n ],\n };\n }\n if (filter === 'agDateColumnFilter') {\n filterParams = {\n filters: [\n {\n filter: 'agDateColumnFilter',\n filterParams: {\n filterOptions: [\n 'equals',\n 'lessThan',\n 'lessThanOrEqual',\n 'greaterThan',\n 'greaterThanOrEqual',\n ],\n ...filterParamsButton,\n suppressAndOrCondition: true,\n minValidYear: 0,\n maxValidYear: 9999,\n },\n },\n {\n filter: ApplyFilter,\n },\n // {\n // filter: 'agSetColumnFilter',\n // },\n ],\n };\n }\n\n if (filter === 'agSetColumnFilter') {\n filterParams = _.cloneDeep(data.filterParams) || {};\n filterParams = {\n filters: [\n {\n ...filterParams,\n ...filterParamsButton,\n },\n {\n filter: ApplyFilter,\n },\n // {\n // filter: 'agSetColumnFilter',\n // },\n ],\n };\n }\n\n if (data.dataType === 'boolean') {\n filterParams = {\n filters: [\n {\n filter: 'agSetColumnFilter',\n filterParams: {\n valueFormatter: (params) => {\n return params.value === true ||\n params.value?.toLowerCase() === 'true'\n ? 'True'\n : 'False';\n },\n ...filterParamsButton,\n },\n },\n {\n filter: ApplyFilter,\n },\n // {\n // filter: 'agSetColumnFilter',\n // },\n ],\n // filters:\n // filter: 'agSetColumnFilter',\n // filterParams: {\n // valueFormatter: (params) => {\n // return params.value === true || params.value?.toLowerCase() === 'true'\n // ? 'True'\n // : 'False';\n // },\n // ...filterParamsButton,\n // },\n\n // suppressAndOrCondition: true,\n };\n }\n\n Object.assign(filterParams, {\n values: (params) => {\n setTimeout(() => {\n params.success([]);\n }, 500);\n },\n });\n\n return filterParams;\n};\n\nexport { useGetColumnDefs };\n","import { useState, useEffect, useRef } from 'react';\n\nimport { useDispatch } from 'react-redux';\n\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\n\nimport * as _ from 'lodash';\n\nexport const useAggridSelection = ({\n gridId,\n gridView,\n onCallbackSelectedRowFromOutside,\n}) => {\n const [itemsSelectionLog, setItemsSelectionLog] = useState([]);\n const [pageItemsSelectionLog, setPageItemsSelectionLog] = useState([]);\n const [itemsSelectionDetailLog, setItemsSelectionDetailLog] = useState([]);\n const [pageItemsSelectionDetailLog, setPageItemsSelectionDetailLog] =\n useState([]);\n\n const refLastSelectedRowData = useRef();\n\n const setRefLastSelectedRowData = (value) => {\n refLastSelectedRowData.current = value;\n };\n\n const dispatch = useDispatch();\n\n useEffect(() => {\n if (gridView) {\n dispatch(\n actionsGridView.updateDetailCurrentItemsSelection(\n _.cloneDeep(itemsSelectionDetailLog)\n )\n );\n dispatch(actionsGridView.updateActiveGrid(gridId));\n }\n\n onCallbackSelectedRowFromOutside(refLastSelectedRowData.current);\n }, [\n dispatch,\n itemsSelectionDetailLog,\n itemsSelectionDetailLog.length,\n gridId,\n ]);\n\n useEffect(() => {\n if (gridView) {\n dispatch(\n actionsGridView.updateItemsSelection(_.cloneDeep(itemsSelectionLog))\n );\n\n dispatch(\n actionsGridView.updateItemsSelection(_.clone(itemsSelectionLog))\n );\n }\n }, [dispatch, itemsSelectionLog, itemsSelectionLog.length, gridView]);\n\n return {\n itemsSelectionLog,\n pageItemsSelectionLog,\n itemsSelectionDetailLog,\n pageItemsSelectionDetailLog,\n setItemsSelectionLog,\n setPageItemsSelectionLog,\n setItemsSelectionDetailLog,\n setPageItemsSelectionDetailLog,\n setRefLastSelectedRowData,\n };\n};\n","import React, { forwardRef, useImperativeHandle } from 'react';\n\nimport { Typography, Col } from 'antd';\n\nimport { FormattedMessage } from 'react-intl';\nimport { useAggridSelection } from 'common/components/ag-grid/hooks/SelectionHook';\n\nimport { cloneDeep } from 'lodash';\n\nimport messages from 'i18n/messages/gridView';\n\nconst SelectionLog = (props, ref) => {\n const {\n gridView,\n isShowItemSelectionLog,\n gridId,\n onCallbackSelectedRowFromOutside,\n } = props;\n\n const {\n itemsSelectionLog,\n pageItemsSelectionLog,\n itemsSelectionDetailLog,\n pageItemsSelectionDetailLog,\n setItemsSelectionLog,\n setPageItemsSelectionLog,\n setItemsSelectionDetailLog,\n setPageItemsSelectionDetailLog,\n setRefLastSelectedRowData,\n } = useAggridSelection({\n gridView,\n gridId,\n onCallbackSelectedRowFromOutside,\n });\n\n useImperativeHandle(ref, () => ({\n setItemsSelectionLog: (value) => setItemsSelectionLog(cloneDeep(value)),\n setPageItemsSelectionLog: (value) =>\n setPageItemsSelectionLog(cloneDeep(value)),\n setItemsSelectionDetailLog: (value) =>\n setItemsSelectionDetailLog(cloneDeep(value)),\n setPageItemsSelectionDetailLog: (value) =>\n setPageItemsSelectionDetailLog(cloneDeep(value)),\n setRefLastSelectedRowData,\n getItemsSelectionLog: () => itemsSelectionLog,\n getPageItemsSelectionLog: () => pageItemsSelectionLog,\n getItemsSelectionDetailLog: () => itemsSelectionDetailLog,\n getPageItemsSelectionDetailLog: () => pageItemsSelectionDetailLog,\n }));\n\n return (\n <>\n {gridView && (\n \n {itemsSelectionLog &&\n isShowItemSelectionLog &&\n itemsSelectionLog.length > 0 &&\n pageItemsSelectionLog &&\n pageItemsSelectionLog.length === 1 && (\n \n {itemsSelectionLog.length}{' '}\n \n \n )}\n {isShowItemSelectionLog &&\n pageItemsSelectionLog &&\n pageItemsSelectionLog.length > 1 && (\n \n {itemsSelectionLog.length}{' '}\n \n \n )}\n \n )}\n \n );\n};\n\nexport default forwardRef(SelectionLog);\n","import React, { useState, useEffect, useCallback, useRef } from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\n\nimport { useQueryClient } from '@tanstack/react-query';\n\nimport cloneDeep from 'lodash/cloneDeep';\nimport get from 'lodash/get';\n\nimport PropTypes from 'prop-types';\nimport classnames from 'classnames';\n\nimport { Pagination, Row, Typography, Col, Empty } from 'antd';\nimport 'ag-grid-enterprise/dist/styles/ag-grid.css';\nimport 'ag-grid-enterprise/dist/styles/ag-theme-alpine.css';\n\nimport 'ag-grid-enterprise';\nimport { LicenseManager } from 'ag-grid-enterprise';\n\nimport { AgGridReact } from 'ag-grid-react';\n\nimport * as api from 'config/axios';\nimport * as formatDate from 'utils/formatDate';\nimport { updateSizeCurrent } from 'common/components/grid-view/utils';\n\nimport { AbandonDialog } from 'common/components/grid-view/components/';\n\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\nimport * as globalSelectors from '@redux/global/selectors';\n\nimport { DEFAULT_SORT } from 'static/Constants';\n\nimport LinkRender from './components/renderers/LinkRender';\nimport DragRender from './components/renderers/DragRender';\nimport CheckboxSelectionRender from './components/renderers/CheckboxSelectionRender';\nimport HeaderCheckboxRender from './components/renderers/HeaderCheckboxRender';\nimport HeaderNullRender from './components/renderers/HeaderNullRender';\nimport CheckboxRender from './components/renderers/CheckboxRender';\n\nimport usePrevious from 'hooks/usePrevious';\nimport * as _ from 'lodash';\nimport { useStatePrevious } from 'hooks/usePrevious';\n\nimport { useGetColumnDefs } from './hooks/getColumnDefsHook';\n\nimport DisplayTotalItem from '../grid-view/DisplayTotalItem';\n\nimport SelectionLog from './components/selection/SelectionLog';\nimport { GridContext } from './context/gridContext';\n\nimport './AgGrid.less';\n\nLicenseManager.setLicenseKey(\n 'Using_this_AG_Grid_Enterprise_key_( AG-040843 )_in_excess_of_the_licence_granted_is_not_permitted___Please_report_misuse_to_( legal@ag-grid.com )___For_help_with_changing_this_key_please_contact_( info@ag-grid.com )___( Global Vertical Innovations, LLC )_is_granted_a_( Multiple Applications )_Developer_License_for_( 1 ))_Front-End_JavaScript_developer___All_Front-End_JavaScript_developers_need_to_be_licensed_in_addition_to_the_ones_working_with_AG_Grid_Enterprise___This_key_has_not_been_granted_a_Deployment_License_Add-on___This_key_works_with_AG_Grid_Enterprise_versions_released_before_( 11 May 2024 )____[v2]_MTcxNTM4MjAwMDAwMA==d035e6c32ae72202e23beccd712ab105'\n);\n\nconst AgGrid = React.memo((props) => {\n const {\n styleGrid,\n columnDefs,\n urlGrid,\n urlGridDistinct,\n paramsGrid,\n gridView = false,\n distinctResponseParams,\n responseParams,\n requestParams,\n callbackDataListSelection,\n hidePagination,\n filterFromMainPage,\n hideAgSetColumnFilter,\n getGridApi,\n isPreview,\n isShowItemSelectionLog = true,\n isCacheEditMode = false,\n getDataFromGrid,\n pageNumberPagination,\n pageSizePagination,\n rowClassRules,\n frameworkComponents = {},\n gridId,\n isHiddenAbbandonDialog = false,\n onHandleSelectedRowCustom,\n urlDownload,\n triggerDownload,\n onDownloadGridHandler,\n downloadFileType,\n gridConfigProps = {},\n shouldReloadDetailGrid,\n onReloadGridCallback,\n isColumnsChanged = true,\n onGetLengthSize,\n isDownloadAllColumns,\n reloadGrid,\n notShowHeaderCheckbox,\n minimizePagination,\n initialPageSize,\n resizePagination,\n showCheckboxSelectionRender = true,\n handleChangePagination,\n mapId,\n nodeIdName,\n forceLoading,\n isSmallSizePagination = false,\n applyDefaultSort = true,\n showLessItem,\n sortAndFilterServerside = false,\n rowHeight,\n sortDataHandler, //? function\n onRowDoubleClicked,\n } = props;\n\n const refGrid = useRef();\n const refSelection = useRef();\n\n const queryClient = useQueryClient();\n\n const refItemSelection = useRef([]);\n const refItemsSelectionDetail = useRef([]);\n const refPageItemsSelection = useRef([]);\n const refPageItemsSelectionDetail = useRef([]);\n\n const refVirtualColumns = useRef([]);\n\n const dispatch = useDispatch();\n const currentRequestDataParams = useRef({});\n const filterFromMainPageRef = useRef([]);\n\n const [isGridReady, setIsGridReady] = useState(false);\n const [agGridPageSize, setAgGridPageSize, refAgGridPageSize] =\n useStatePrevious(initialPageSize || 20);\n const [\n agGridCurrentPagination,\n setAgGridCurrentPagination,\n refAgGridCurrentPagination,\n ] = useStatePrevious(1);\n\n const prevAgGridPageSize = usePrevious(agGridPageSize);\n const prevAgGridCurrentPagination = usePrevious(agGridCurrentPagination);\n\n const [\n agGridTotalPagination,\n setAgGridTotalPagination,\n refAgGridTotalPagination,\n ] = useStatePrevious(0);\n const [agGridNameColumnFilter, setAgGridNameColumnFilter] = useState(false);\n\n const [visibleSelection, setVisibleSelection] = useState(false);\n\n const [currentDefColumns, setCurrentDefColumns] = useState(null);\n\n const [isSwitchingPage, setIsSwitchingPage] = useState(false);\n const [gridFetched, setGridFetched, refGridFetched] = useStatePrevious(false);\n const [isFetching, setIsFetching] = useState(false);\n\n const isShowDetailOn = useSelector(globalSelectors.selectShowDetail());\n const showAddToFolder = useSelector(globalSelectors.selectShowAddToFolder());\n\n const resetSelection = useCallback(() => {\n refItemSelection.current = [];\n refPageItemsSelection.current = [];\n refItemsSelectionDetail.current = [];\n refPageItemsSelectionDetail.current = [];\n\n setItemsSelectionLog(refItemSelection.current);\n setPageItemsSelectionLog(refPageItemsSelection.current);\n setItemsSelectionDetailLog(refItemsSelectionDetail.current);\n setPageItemsSelectionDetailLog(refPageItemsSelectionDetail.current);\n }, []);\n\n const deselectAll = useCallback(() => {\n refGrid.current.api && refGrid.current.api.deselectAll();\n }, []);\n\n const refreshAggrid = useCallback(() => {\n resetSelection();\n deselectAll();\n setClassNameHeaderCheckbox(\n refAgGridCurrentPagination.current,\n refAgGridTotalPagination.current,\n refAgGridPageSize.current\n );\n }, []);\n\n const isItemIdEqualToNodeId = (item, nodeId) => {\n return _.toString(item.id) === nodeId;\n };\n\n const setItemsSelectionLog = (value) =>\n refSelection.current.setItemsSelectionLog(value);\n\n const setPageItemsSelectionLog = (value) =>\n refSelection.current.setPageItemsSelectionLog(value);\n\n const setItemsSelectionDetailLog = (value) =>\n refSelection.current.setItemsSelectionDetailLog(value);\n\n const setPageItemsSelectionDetailLog = (value) =>\n refSelection.current.setPageItemsSelectionDetailLog(value);\n\n const setClickedRow = (rowData) =>\n refSelection.current.setRefLastSelectedRowData(rowData);\n\n const cols = useGetColumnDefs({\n urlGrid,\n columnDefs,\n notShowHeaderCheckbox,\n hideAgSetColumnFilter,\n });\n\n useEffect(() => {\n //* set page size and page current from page info props\n const setPageInfoFromProps = () => {\n if (\n pageNumberPagination &&\n pageNumberPagination !== refAgGridCurrentPagination.current\n ) {\n setAgGridCurrentPagination(pageNumberPagination);\n }\n\n if (\n pageSizePagination &&\n pageSizePagination !== refAgGridPageSize.current\n ) {\n setAgGridPageSize(pageSizePagination);\n }\n };\n\n setPageInfoFromProps();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pageNumberPagination, pageSizePagination]);\n\n useEffect(() => {\n const isPageSizeChange = () =>\n agGridPageSize && prevAgGridPageSize !== agGridPageSize;\n\n const isPageNumberChange = () =>\n agGridCurrentPagination &&\n prevAgGridCurrentPagination !== agGridCurrentPagination;\n\n const gridApi = refGrid.current.api;\n\n //* handle load page\n const goToNewPage = async (options) => {\n if (agGridPageSize && agGridCurrentPagination && gridApi) {\n gridApi.gridOptionsWrapper.setProperty(\n 'cacheBlockSize',\n agGridPageSize\n );\n\n let datasource = serverSideDataSource({\n page: agGridCurrentPagination,\n pageSize: agGridPageSize,\n });\n gridApi.setServerSideDatasource(datasource);\n }\n };\n\n //* handle refetch page when page info update\n const handleRefetchWhenPageInfoChange = async () => {\n const isPageSizeChanged = isPageSizeChange();\n const isPageNumberChanged = isPageNumberChange();\n\n if (!gridFetched) {\n goToNewPage();\n } else {\n //* if page info state change\n if (isPageNumberChanged || isPageSizeChanged) {\n goToNewPage();\n }\n }\n\n setIsSwitchingPage(false);\n };\n\n handleRefetchWhenPageInfoChange();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n agGridPageSize,\n agGridCurrentPagination,\n prevAgGridPageSize,\n prevAgGridCurrentPagination,\n gridFetched,\n isGridReady,\n ]);\n\n useEffect(() => {\n //* update page size and page current\n\n if (\n agGridPageSize !== prevAgGridPageSize ||\n agGridCurrentPagination !== prevAgGridCurrentPagination\n ) {\n if (isCacheEditMode) {\n //* this part is for page number and page size passed down by props\n dispatch(\n actionsGridView.updateGridViewPagination({\n gridId: gridId,\n pageNumber: agGridCurrentPagination,\n pageSize: agGridPageSize,\n })\n );\n } else {\n updateSizeCurrent(\n dispatch,\n agGridCurrentPagination,\n agGridPageSize,\n gridId || window.location.pathname\n );\n }\n }\n }, [\n agGridPageSize,\n agGridCurrentPagination,\n prevAgGridPageSize,\n prevAgGridCurrentPagination,\n gridId,\n dispatch,\n isCacheEditMode,\n ]);\n\n useEffect(() => {\n if (hidePagination) {\n setAgGridPageSize(10000);\n }\n }, []);\n\n // download grid data\n const callApiDownloadGrid = () => {\n const params = _.cloneDeep(currentRequestDataParams.current);\n\n // download all data of grid, not just 1 page\n params.pageIndex = 1;\n params.pageSize = 999999999;\n\n // add columns to download display columns only\n params.columns = isDownloadAllColumns ? null : getDownloadColumns();\n\n // add file type\n params.fileType = downloadFileType;\n\n // call api download\n onDownloadGridHandler &&\n onDownloadGridHandler(\n api\n .sendPost(urlDownload, params)\n .then((response) => {\n if (response?.isSuccess) {\n return api.sendDownload({ url: response?.data?.url });\n } else {\n return new Promise.reject({ message: response.message });\n }\n })\n .catch((err) => {\n return new Promise.reject(err);\n })\n );\n };\n\n const getDownloadColumns = () => {\n const agGridColumnApi = refGrid.current.columnApi;\n\n const displayColumns = agGridColumnApi.getAllDisplayedColumns();\n const columnsParams = displayColumns.reduce((accumulator, currentCol) => {\n const displayName = currentCol?.colDef?.displayName;\n\n //* check for orgFieldName first to get field name of hidden header title columns\n const orgFieldName = currentCol?.colDef?.orgFieldName;\n\n if (orgFieldName) {\n accumulator.push({\n fieldName: orgFieldName,\n displayName: orgFieldName,\n });\n return accumulator;\n }\n\n //* check for separateFieldName next to get field name of merge values columns\n const separateFieldName = currentCol?.colDef?.separateFieldName;\n if (separateFieldName && separateFieldName.length) {\n separateFieldName.length &&\n separateFieldName.forEach((field) => {\n accumulator.push({\n fieldName: field,\n displayName: field,\n });\n });\n\n return accumulator;\n }\n\n //* finally, when col def not contain orgFieldName and separateFieldName, check colDef field for normal columns\n const colField = currentCol?.colDef?.field;\n if (!colField) return accumulator;\n if (colField === 'checkboxSelection') return accumulator;\n\n accumulator.push({\n fieldName: colField,\n displayName: displayName || colField,\n });\n return accumulator;\n }, []);\n\n return columnsParams;\n };\n\n useEffect(() => {\n if (triggerDownload && urlDownload) callApiDownloadGrid();\n // eslint-disable-next-line\n }, [triggerDownload]);\n\n const searchTextRequest = requestParams?.search?.searchText;\n const advCriteria = requestParams?.advCriteria;\n const searchTextParams = paramsGrid?.search?.searchText;\n const paramsGridStringify = JSON.stringify(paramsGrid);\n const requestParamStringify = JSON.stringify(requestParams);\n\n const reloadData = ({ keepPageIndex } = {}) => {\n const agGridApi = refGrid.current.api;\n\n if (agGridApi) {\n //* set current pagination UI to page 1\n setAgGridCurrentPagination(1);\n\n let datasource = serverSideDataSource({\n page: 1,\n pageSize: refAgGridPageSize.current,\n });\n agGridApi && agGridApi.setServerSideDatasource(datasource);\n refreshAggrid();\n onReloadGridCallback && onReloadGridCallback();\n }\n };\n\n const onRequestServerSideDataSource = useCallback(() => {\n reloadData();\n //eslint-disable-next-line\n }, [\n searchTextRequest,\n searchTextParams,\n urlGrid,\n urlGridDistinct,\n paramsGridStringify,\n requestParamStringify,\n //* NOTE: filterFromAsset - empty array make it reloadData when no cahnge\n JSON.stringify(filterFromMainPage),\n // advCriteria,\n // columnDefs,\n ]);\n\n const onRequestServerSideDataSourceKeepPageIndex = useCallback(() => {\n if (shouldReloadDetailGrid) reloadData({ keepPageIndex: true });\n //eslint-disable-next-line\n }, [shouldReloadDetailGrid]);\n\n const onRequestServerSideDataSourceWithFlag = useCallback(() => {\n if (reloadGrid) {\n onPurgeServerSideCache();\n }\n //eslint-disable-next-line\n }, [reloadGrid]);\n\n // reload data and refresh grid when search\n useEffect(() => {\n onRequestServerSideDataSource();\n //eslint-disable-next-line\n }, [onRequestServerSideDataSource]);\n\n // reload data\n useEffect(() => {\n onRequestServerSideDataSourceWithFlag();\n //eslint-disable-next-line\n }, [onRequestServerSideDataSourceWithFlag]);\n\n useEffect(() => {\n setCurrentDefColumns([]);\n //eslint-disable-next-line\n }, [shouldReloadDetailGrid]);\n\n // reload data when shouldReloadDetailGrid and keep page index\n useEffect(() => {\n onRequestServerSideDataSourceKeepPageIndex();\n\n //eslint-disable-next-line\n }, [onRequestServerSideDataSourceKeepPageIndex]);\n\n // unmount\n useEffect(() => {\n return () => {\n refItemSelection.current = [];\n };\n }, []);\n\n useEffect(() => {\n filterFromMainPageRef.current = filterFromMainPage;\n }, [filterFromMainPage]);\n\n const serverSideDataSource = ({ page, pageSize } = {}) => {\n return {\n // called by the grid when more rows are required\n getRows: function (params) {\n setIsFetching(true);\n\n //* if page or pageSize undefined get default grid param from aggrid\n\n if (!page || !pageSize) {\n pageSize = params.api.paginationGetPageSize();\n page = params.api.paginationGetCurrentPage() + 1;\n }\n\n let paramsApi = {\n pageSize: pageSize,\n pageIndex: page,\n sort: [],\n filters: [],\n };\n\n // if there are more standard request params\n if (requestParams) {\n paramsApi = { ...paramsApi, ...requestParams };\n }\n if (params.request.sortModel.length > 0) {\n // Clone a new array, don't mutate the original, prevent stupid AgGrid's bugs\n let newSort = [];\n\n params.request.sortModel.forEach((val) => {\n newSort.push({\n fieldName: val.colId,\n isAscending: val.sort === 'asc' ? true : false,\n });\n });\n\n paramsApi.sort = newSort;\n } else {\n if (applyDefaultSort) {\n paramsApi.sort = DEFAULT_SORT;\n }\n }\n let keyFilter = Object.keys(params.request.filterModel);\n let filters = filterParams(keyFilter, params.request.filterModel);\n if (filterFromMainPage && filterFromMainPage.length > 0) {\n filters = filters.concat(filterFromMainPage);\n }\n if (requestParams?.filters?.length > 0) {\n filters = filters.concat(requestParams.filters);\n }\n\n if (requestParams?.sort?.length > 0) {\n paramsApi.sort = paramsApi.sort.concat(requestParams.sort);\n }\n\n paramsApi.filters = filters;\n\n Object.assign(paramsApi, paramsGrid);\n\n currentRequestDataParams.current = paramsApi;\n\n api\n .sendPost(urlGrid, paramsApi)\n .then((response) => {\n //* fetch data first time success => allow to fetch saved pagination config\n if (response) {\n !refGridFetched.current && setGridFetched(true);\n setIsFetching(false);\n }\n\n let data;\n if (responseParams) {\n data = get(response, responseParams, []);\n\n // !New\n // ?Hide loading progress when data = null\n if (data) {\n // callback response data\n getDataFromGrid &&\n getDataFromGrid(response.data.gridData || data);\n } else {\n const loadingElement =\n document?.getElementsByClassName('ag-row-loading');\n if (loadingElement?.length > 0) {\n loadingElement[0].style.display = 'none';\n }\n }\n } else {\n data = response;\n }\n\n if (\n data &&\n data.gridData &&\n data.gridData.length >= 0 &&\n data.paging &&\n data.paging.totalRecord >= 0\n ) {\n // supply rows for requested block to grid\n const gridData = data.gridData ? data.gridData : [];\n\n const gridDataMappedId = mapId ? gridData.map(mapId) : gridData;\n const sortedGridData = sortDataHandler\n ? cloneDeep(gridDataMappedId)?.sort(sortDataHandler)\n : gridDataMappedId;\n\n let nextTotalRecord;\n\n //todo\n const numberOfItemNotInLastPage =\n refAgGridCurrentPagination.current * refAgGridPageSize.current -\n data.paging.totalRecord;\n\n if (\n numberOfItemNotInLastPage > 0 &&\n data.paging.totalRecord !== 0\n ) {\n nextTotalRecord =\n refAgGridPageSize.current - numberOfItemNotInLastPage;\n } else {\n nextTotalRecord = data.paging.totalRecord;\n }\n\n params.successCallback(sortedGridData, nextTotalRecord);\n setAgGridTotalPagination(data.paging.totalRecord);\n onGetLengthSize && onGetLengthSize(data.paging.totalRecord);\n\n params.api.forEachNode((node) => {\n // return;\n if (refItemSelection.current.indexOf(node.id) > -1) {\n node.setSelected(true);\n\n if (showCheckboxSelectionRender) {\n node.setDataValue('checkboxSelection', true);\n }\n } else {\n node.setSelected(false);\n\n if (showCheckboxSelectionRender) {\n node.setDataValue('checkboxSelection', false);\n }\n }\n\n //Should update after demo\n if (isPreview) {\n if (node?.data?.showInMemberPreview) {\n node.setSelected(true);\n\n if (showCheckboxSelectionRender) {\n node.setDataValue('checkboxSelection', true);\n }\n refItemSelection.current.push(node.id);\n refItemsSelectionDetail.current.push(node?.data);\n\n refPageItemsSelection.current.push({\n page: agGridCurrentPagination,\n items: [node.id],\n });\n refPageItemsSelectionDetail.current.push({\n page: agGridCurrentPagination,\n items: [node?.data],\n });\n }\n }\n });\n //Should update after demo\n setClassNameHeaderCheckbox(\n page,\n data.paging.totalRecord,\n pageSize\n );\n\n window.rowDataServerSide = data.gridData;\n } else {\n //* show no data\n params.successCallback([], 0);\n }\n })\n .catch((error) => {\n // inform grid request failed\n params.failCallback();\n });\n },\n };\n };\n\n const onPurgeServerSideCache = () => {\n const agGridApi = refGrid.current?.api;\n\n if (!agGridApi) return;\n\n agGridApi && agGridApi.refreshServerSide({ purge: true });\n\n refreshAggrid();\n };\n\n const onGridReadyfunction = useCallback((params) => {\n setIsGridReady(true);\n\n params.api.rivirPurgeServerSideCache = onPurgeServerSideCache;\n\n getGridApi && getGridApi(params.api);\n }, []);\n\n const onChangePagination = (page, pageSize) => {\n const isPageSizeChanged = pageSize !== agGridPageSize;\n\n const nextPage = isPageSizeChanged ? 1 : page;\n\n setAgGridCurrentPagination(nextPage);\n setAgGridPageSize(pageSize);\n\n handleChangePagination && handleChangePagination(page);\n };\n\n const onShowSizeChange = (current, size) => {\n const agGridApi = refGrid.current.api;\n\n setAgGridPageSize(size);\n agGridApi.gridOptionsWrapper.setProperty('cacheBlockSize', size);\n\n resetSelection();\n };\n\n const onSelectionChanged = (params) => {\n // setClassNameHeaderCheckbox(params);\n props.onSelectionChanged && props.onSelectionChanged(params);\n };\n\n const onRowSelected = useCallback((params) => {\n if (showCheckboxSelectionRender) {\n params.node.setDataValue('checkboxSelection', params.node.selected);\n }\n }, []);\n\n const filterParams = (keyFilter, modelFilter, columnName) => {\n let filterParams = [];\n if (keyFilter.length > 0) {\n keyFilter &&\n keyFilter.length > 0 &&\n keyFilter.forEach((key) => {\n let filterModel = modelFilter[key];\n if (\n filterModel &&\n filterModel.filterType === 'multi' &&\n filterModel.filterModels &&\n filterModel.filterModels.length > 0\n ) {\n filterModel.filterModels.forEach((model) => {\n const item = getFilterParamsItem(model, key, columnName);\n item && filterParams.push(item);\n });\n } else {\n // when filter type is AgSetColumnFilter, filterModel is not an array, so we don't need to loop through\n const item = getFilterParamsItem(filterModel, key, columnName);\n item && filterParams.push(item);\n }\n });\n }\n return filterParams;\n };\n\n const getFilterParamsItem = (model, filterKey, columnName) => {\n if (!model) return;\n let filterType = 'Like';\n let value = model.filter;\n let otherValue = false;\n if (model.filterType === 'set') {\n if (filterKey === columnName) return;\n if (model.values && model.values.length === 0) return;\n filterType = 'In';\n if (\n (model.values &&\n model.values.length > 0 &&\n model.values[0] === 'True') ||\n model.values[0] === 'False'\n ) {\n filterType = 'Equal';\n value = model.values[0] === 'True' ? true : false;\n }\n }\n if (model.type === 'equals') {\n filterType = 'Equal';\n if (model.filterType === 'date') {\n filterType = 'Equal';\n value = formatDate.formatYMD(model.dateFrom, 'day');\n }\n }\n if (model.type === 'notEqual') {\n filterType = 'NotEqual';\n }\n if (model.type === 'contains') {\n filterType = 'Like';\n }\n if (model.type === 'lessThan') {\n filterType = 'LessThan';\n if (model.filterType === 'date') {\n value = formatDate.formatYMD(model.dateFrom, 'day');\n }\n }\n if (model.type === 'lessThanOrEqual') {\n filterType = 'LessThanOrEqual';\n if (model.filterType === 'date') {\n value = formatDate.formatYMD(model.dateFrom, 'day');\n }\n }\n if (model.type === 'greaterThan') {\n filterType = 'GreaterThan';\n if (model.filterType === 'date') {\n value = formatDate.formatYMD(model.dateFrom, 'day');\n }\n }\n if (model.type === 'greaterThanOrEqual') {\n filterType = 'GreaterThanOrEqual';\n if (model.filterType === 'date') {\n value = formatDate.formatYMD(model.dateFrom, 'day');\n }\n }\n if (model.type === 'blank') {\n filterType = 'IsNull';\n }\n if (model.type === 'notBlank') {\n filterType = 'IsNotNull';\n }\n let obj = {\n FieldName: filterKey,\n filterType: filterType,\n };\n if (filterType === 'In') {\n Object.assign(obj, { values: model.values });\n } else {\n Object.assign(obj, { value: value });\n }\n if (otherValue) {\n Object.assign(obj, { otherValue: otherValue });\n }\n\n return obj;\n };\n\n const handleGetDistinctQueries = async ({ distinctKeys, paramsApi }) => {\n let responseData = await queryClient.fetchQuery({\n queryKey: distinctKeys,\n queryFn: async () => {\n return await api.sendPost(urlGridDistinct, paramsApi);\n },\n staleTime: 0,\n });\n\n return { data: responseData };\n };\n\n const displaySetFilter = (instance, show) => {\n if (instance) {\n if (instance.getChildFilterInstance(0)?.filterNameKey === 'setFilter') {\n instance.getChildFilterInstance(0).setDisplayed(show);\n }\n if (instance.getChildFilterInstance(1)?.filterNameKey === 'setFilter') {\n instance.getChildFilterInstance(1).setDisplayed(show);\n }\n }\n };\n\n const onMenuClick = async (params) => {\n let columnId = params.column?.colId;\n const fieldName = columnId;\n\n if (columnId) {\n setAgGridNameColumnFilter(columnId);\n let modelFilterChanged = params.api.getFilterModel();\n\n let keyFilter = Object.keys(modelFilterChanged);\n let filters = filterParams(keyFilter, modelFilterChanged, columnId);\n if (filterFromMainPageRef.current?.length)\n filters = [...filters, ...filterFromMainPageRef.current];\n\n let paramsApi = { fieldName: columnId, filters: filters };\n\n paramsApi = {\n ...paramsApi,\n ...requestParams,\n ...paramsGrid,\n };\n const searchText = paramsGrid?.search?.searchText;\n const distinctKeys = ['ag-grid', fieldName, filters, searchText];\n\n try {\n const response = await handleGetDistinctQueries({\n distinctKeys,\n paramsApi,\n });\n\n let data;\n\n let _distinctResponseParams = distinctResponseParams || responseParams;\n if (_distinctResponseParams) {\n // data = response?.data?.[responseParams];\n data = get(response?.data, _distinctResponseParams);\n } else {\n data = response?.data;\n }\n\n let instance = params.api.getFilterInstance(columnId);\n\n if (data && data.length > 0 && data.length < 51) {\n if (instance.__proto__.hasOwnProperty('setFilterValues')) {\n // supply rows for requested block to grid\n instance.setFilterValues(data);\n displaySetFilter(instance, true);\n instance.applyModel();\n } else {\n displaySetFilter(instance, true);\n if (!instance.getChildFilterInstance(1)) return;\n instance.getChildFilterInstance(1).setFilterValues(data);\n instance.getChildFilterInstance(1).applyModel();\n }\n } else {\n if (instance.__proto__.hasOwnProperty('setFilterValues')) {\n // supply rows for requested block to grid\n instance.setFilterValues([]);\n displaySetFilter(instance, false);\n instance.applyModel();\n } else {\n displaySetFilter(instance, false);\n\n if (!instance.getChildFilterInstance(1)) return;\n instance.getChildFilterInstance(1).setFilterValues([]);\n instance.getChildFilterInstance(1).applyModel();\n }\n }\n } catch (error) {\n console.error('Error fetching filter data: ', error);\n }\n }\n };\n\n const onHandleSortChanged = (event) => {\n refreshAggrid();\n };\n\n const onHandleFilterChanged = async (event) => {\n let modelFilterChanged = event.api.getFilterModel();\n let keyFilter = Object.keys(modelFilterChanged);\n let filters = filterParams(\n keyFilter,\n modelFilterChanged,\n agGridNameColumnFilter\n );\n if (filterFromMainPageRef.current?.length)\n filters = [...filters, ...filterFromMainPageRef.current];\n let paramsApi = {\n fieldName: agGridNameColumnFilter,\n filters: filters,\n };\n\n const searchText = paramsGrid?.search?.searchText;\n\n paramsApi = {\n ...paramsApi,\n ...paramsGrid,\n ...requestParams,\n };\n\n const distinctKeys = [\n 'ag-grid',\n agGridNameColumnFilter,\n filters,\n searchText,\n ];\n\n try {\n const response = await handleGetDistinctQueries({\n distinctKeys,\n paramsApi,\n });\n if (agGridCurrentPagination !== 1) {\n setAgGridCurrentPagination(1);\n }\n let instance = event.api.getFilterInstance(agGridNameColumnFilter);\n if (\n modelFilterChanged[agGridNameColumnFilter] === undefined ||\n modelFilterChanged[agGridNameColumnFilter].filterModels[1] === null ||\n modelFilterChanged[agGridNameColumnFilter].filterModels[1].values\n .length === 0\n ) {\n let data;\n let _distinctResponseParams = distinctResponseParams || responseParams;\n if (_distinctResponseParams) {\n // data = response?.data?.[responseParams];\n data = get(response?.data, _distinctResponseParams);\n } else {\n data = response?.data;\n }\n if (data && data.length > 0 && data.length < 51) {\n // supply rows for requested block to grid\n instance.getChildFilterInstance(1).setFilterValues(data);\n displaySetFilter(instance, true);\n } else {\n displaySetFilter(instance, false);\n instance.getChildFilterInstance(1).setFilterValues([]);\n }\n instance.getChildFilterInstance(1).applyModel();\n }\n } catch (error) {\n console.log(error);\n } finally {\n resetSelection();\n deselectAll();\n setClassNameHeaderCheckbox(\n refAgGridCurrentPagination.current,\n refAgGridTotalPagination.current,\n refAgGridPageSize.current\n );\n }\n };\n\n const setClassNameHeaderCheckbox = (pageCurrent, totalPage, pageSize) => {\n let page = pageCurrent || agGridCurrentPagination;\n let total = totalPage || agGridTotalPagination;\n let size = pageSize || agGridPageSize;\n let pageItemsSelectionFilter =\n (refPageItemsSelection.current &&\n refPageItemsSelection.current.length > 0 &&\n refPageItemsSelection.current.filter(\n (pageItem) => pageItem.page === page\n )) ||\n [];\n\n let length =\n (pageItemsSelectionFilter &&\n pageItemsSelectionFilter.length > 0 &&\n pageItemsSelectionFilter[0].items &&\n pageItemsSelectionFilter[0].items.length) ||\n 0;\n let lastPage = Math.ceil(totalPage / size) === page ? true : false;\n let lastLength = totalPage - (page - 1) * size;\n if (\n length === size ||\n length === total ||\n (lastPage && length === lastLength)\n ) {\n let element = document.getElementsByClassName(urlGrid)[0];\n let classNameCheckbox =\n element && element.className.replace('ant-checkbox-indeterminate', '');\n if (classNameCheckbox) {\n classNameCheckbox = classNameCheckbox.replace(\n 'ant-checkbox-checked',\n ''\n );\n classNameCheckbox = classNameCheckbox.concat(' ant-checkbox-checked');\n }\n if (element) {\n element.className = classNameCheckbox;\n }\n } else if (length === 0) {\n let element = document.getElementsByClassName(urlGrid)[0];\n if (element) {\n let classNameCheckbox = element.className.replace(\n 'ant-checkbox-indeterminate',\n ''\n );\n classNameCheckbox = classNameCheckbox.replace(\n 'ant-checkbox-checked',\n ''\n );\n if (element) {\n element.className = classNameCheckbox;\n }\n }\n } else {\n let element = document.getElementsByClassName(urlGrid)[0];\n let classNameCheckbox =\n element &&\n element.className &&\n element.className.replace('ant-checkbox-indeterminate', '');\n if (classNameCheckbox) {\n classNameCheckbox = classNameCheckbox.replace(\n 'ant-checkbox-checked',\n ''\n );\n classNameCheckbox = classNameCheckbox.concat(\n ' ant-checkbox-indeterminate'\n );\n }\n if (element) {\n element.className = classNameCheckbox;\n }\n }\n };\n\n const onHandleCheckboxCellClick = (params) => {\n let pageItemsSelectionFilter =\n (refPageItemsSelection.current &&\n refPageItemsSelection.current.length > 0 &&\n refPageItemsSelection.current.filter(\n (pageItem) => pageItem.page === refAgGridCurrentPagination.current\n )) ||\n [];\n\n let pageItemsSelectionDetailFilter =\n (refPageItemsSelectionDetail.current &&\n refPageItemsSelectionDetail.current.length > 0 &&\n refPageItemsSelectionDetail.current.filter(\n (pageItem) => pageItem.page === refAgGridCurrentPagination.current\n )) ||\n [];\n\n let pageItemsSelectionFilterDiff =\n (refPageItemsSelection.current &&\n refPageItemsSelection.current.length > 0 &&\n refPageItemsSelection.current.filter(\n (pageItem) => pageItem.page !== refAgGridCurrentPagination.current\n )) ||\n [];\n\n let pageItemsSelectionDetailFilterDiff =\n (refPageItemsSelectionDetail.current &&\n refPageItemsSelectionDetail.current.length > 0 &&\n refPageItemsSelectionDetail.current.filter(\n (pageItem) => pageItem.page !== refAgGridCurrentPagination.current\n )) ||\n [];\n\n let nodeId = _.toString(params.data.id);\n let nodeData = params.data;\n\n if (refItemSelection.current.indexOf(nodeId) > -1) {\n refItemSelection.current = refItemSelection.current.filter(\n (item) => item !== nodeId\n );\n refItemsSelectionDetail.current = refItemsSelectionDetail.current.filter(\n (item) => !isItemIdEqualToNodeId(item, nodeId)\n );\n pageItemsSelectionFilter[0].items.splice(\n pageItemsSelectionFilter[0].items.indexOf(nodeId),\n 1\n );\n const findId = pageItemsSelectionDetailFilter[0].items.findIndex((item) =>\n isItemIdEqualToNodeId(item, nodeId)\n );\n pageItemsSelectionDetailFilter[0].items.splice(findId, 1);\n if (pageItemsSelectionFilter[0].items?.length === 0) {\n refPageItemsSelection.current = pageItemsSelectionFilterDiff;\n refPageItemsSelectionDetail.current =\n pageItemsSelectionDetailFilterDiff;\n } else {\n refPageItemsSelection.current = pageItemsSelectionFilterDiff.concat(\n pageItemsSelectionFilter\n );\n refPageItemsSelectionDetail.current =\n pageItemsSelectionDetailFilterDiff.concat(\n pageItemsSelectionDetailFilter\n );\n }\n } else {\n if (gridConfigProps?.rowSelection === 'single') {\n refItemSelection.current = [];\n refItemsSelectionDetail.current = [];\n refPageItemsSelection.current = [];\n refPageItemsSelectionDetail.current = [];\n pageItemsSelectionFilter = [];\n pageItemsSelectionDetailFilter = [];\n }\n\n refItemSelection.current = [...refItemSelection.current, nodeId];\n refItemsSelectionDetail.current = [\n ...refItemsSelectionDetail.current,\n nodeData,\n ];\n if (pageItemsSelectionFilter && pageItemsSelectionFilter.length > 0) {\n pageItemsSelectionFilter[0].items.push(nodeId);\n pageItemsSelectionDetailFilter[0].items.push(nodeData);\n\n refPageItemsSelection.current = pageItemsSelectionFilterDiff.concat(\n pageItemsSelectionFilter\n );\n refPageItemsSelectionDetail.current =\n pageItemsSelectionDetailFilterDiff.concat(\n pageItemsSelectionDetailFilter\n );\n } else {\n refPageItemsSelection.current = refPageItemsSelection.current.concat([\n {\n page: refAgGridCurrentPagination.current,\n items: [nodeId],\n },\n ]);\n refPageItemsSelectionDetail.current =\n refPageItemsSelectionDetail.current.concat([\n {\n page: refAgGridCurrentPagination.current,\n items: [nodeData],\n },\n ]);\n }\n }\n\n params.api.forEachNode((node) => {\n if (refItemSelection.current.indexOf(node.id) > -1) {\n node.setSelected(true);\n } else {\n node.setSelected(false);\n }\n });\n\n if (gridView && refItemSelection.current?.length === 1) {\n const currentItem = refItemsSelectionDetail.current?.[0];\n\n let data = Object.assign({}, params?.data);\n if (refItemSelection.current.indexOf(data?.id) > -1) {\n dispatch(actionsGridView.updateItemCurrentSelection(data));\n } else {\n dispatch(\n actionsGridView.updateItemCurrentSelection({\n ...currentItem,\n checkboxSelection: false,\n })\n );\n }\n }\n };\n\n const onHandleCellsRowClick = (params) => {\n let nodeSelections = params.api.getSelectedNodes();\n\n let itemsSelectionNew = [];\n let itemsSelectionDetailNew = [];\n let dataNode;\n\n if (refItemSelection.current.length === 0) {\n nodeSelections &&\n nodeSelections.length > 0 &&\n nodeSelections.forEach((node) => {\n itemsSelectionNew.push(node.id);\n itemsSelectionDetailNew.push(node.data);\n dataNode = node;\n });\n refItemSelection.current = itemsSelectionNew;\n refItemsSelectionDetail.current = itemsSelectionDetailNew;\n refPageItemsSelection.current = [\n {\n page: refAgGridCurrentPagination.current,\n items: [...refItemSelection.current],\n },\n ];\n refPageItemsSelectionDetail.current = [\n {\n page: refAgGridCurrentPagination.current,\n items: [...refItemsSelectionDetail.current],\n },\n ];\n if (gridView) {\n const data = Object.assign({}, dataNode?.data);\n\n dispatch(actionsGridView.updateItemCurrentSelection(data));\n isShowDetailOn && dispatch(actionsGridView.updateVisible(true));\n }\n } else {\n if (nodeSelections.length === 1) {\n let pageItemsSelectionFilter =\n (refPageItemsSelection.current &&\n refPageItemsSelection.current.length > 0 &&\n refPageItemsSelection.current.filter(\n (pageItems) =>\n pageItems.page !== refAgGridCurrentPagination.current\n )) ||\n [];\n if (pageItemsSelectionFilter && pageItemsSelectionFilter.length > 0) {\n if (!isHiddenAbbandonDialog) {\n if (gridConfigProps?.rowSelection === 'single') {\n handleModalAbandon();\n } else {\n setVisibleSelection(true);\n }\n }\n } else {\n nodeSelections &&\n nodeSelections.length > 0 &&\n nodeSelections.forEach((node) => {\n itemsSelectionNew.push(node.id);\n itemsSelectionDetailNew.push(node.data);\n dataNode = node;\n });\n refItemSelection.current = itemsSelectionNew;\n refItemsSelectionDetail.current = itemsSelectionDetailNew;\n refPageItemsSelection.current = [\n {\n page: refAgGridCurrentPagination.current,\n items: [...refItemSelection.current],\n },\n ];\n refPageItemsSelectionDetail.current = [\n {\n page: refAgGridCurrentPagination.current,\n items: [...refItemsSelectionDetail.current],\n },\n ];\n\n if (gridView) {\n const data = Object.assign({}, dataNode?.data);\n\n dispatch(actionsGridView.updateItemCurrentSelection(data));\n isShowDetailOn && dispatch(actionsGridView.updateVisible(true));\n }\n }\n } else {\n params.api.forEachNode((node) => {\n if (node.selected) {\n itemsSelectionNew.push(node.id);\n itemsSelectionDetailNew.push(node.data);\n } else {\n refItemSelection.current = refItemSelection.current.filter(\n (item) => item !== node.id\n );\n refItemsSelectionDetail.current =\n refItemsSelectionDetail.current.filter(\n (item) => !isItemIdEqualToNodeId(item, node.id)\n );\n }\n });\n refItemSelection.current = _.union(\n refItemSelection.current,\n itemsSelectionNew\n );\n refItemsSelectionDetail.current = _.uniqBy(\n [...refItemsSelectionDetail.current, ...itemsSelectionDetailNew],\n 'id'\n );\n let pageItemsSelectionFilter =\n refPageItemsSelection.current &&\n refPageItemsSelection.current.length > 0 &&\n refPageItemsSelection.current.filter(\n (pageItems) => pageItems.page !== refAgGridCurrentPagination.current\n );\n let pageItemsSelectionDetailFilter =\n refPageItemsSelectionDetail.current &&\n refPageItemsSelectionDetail.current.length > 0 &&\n refPageItemsSelectionDetail.current.filter(\n (pageItems) => pageItems.page !== refAgGridCurrentPagination.current\n );\n pageItemsSelectionFilter.push({\n page: refAgGridCurrentPagination.current,\n items: itemsSelectionNew,\n });\n pageItemsSelectionDetailFilter.push({\n page: refAgGridCurrentPagination.current,\n items: itemsSelectionDetailNew,\n });\n refPageItemsSelection.current = pageItemsSelectionFilter;\n refPageItemsSelectionDetail.current = pageItemsSelectionDetailFilter;\n }\n }\n };\n\n const onRowClicked = (params) => {\n if (\n params.event.target &&\n params.event.target.name &&\n params.event.target.name.indexOf('ag-grid-input-check-clicked') > -1\n ) {\n onHandleCheckboxCellClick(params);\n } else {\n onHandleCellsRowClick(params);\n }\n\n setClickedRow(params?.data);\n\n if (refPageItemsSelection.current) {\n let result = [];\n refPageItemsSelection.current.forEach((data) => {\n result = result.concat(data.items);\n });\n const getSelectionList =\n callbackDataListSelection?.func || callbackDataListSelection;\n if (typeof getSelectionList === 'function') {\n getSelectionList(result.map((stringId) => _.toNumber(stringId)));\n }\n }\n\n setItemsSelectionLog(refItemSelection.current);\n setItemsSelectionDetailLog(refItemsSelectionDetail.current);\n setPageItemsSelectionLog(refPageItemsSelection.current);\n setPageItemsSelectionDetailLog(refPageItemsSelectionDetail.current);\n\n setClassNameHeaderCheckbox(\n refAgGridCurrentPagination.current,\n refAgGridTotalPagination.current,\n refAgGridPageSize.current\n );\n };\n\n const handleModalAbandon = () => {\n const agGridApi = refGrid.current.api;\n\n let nodeSelections = agGridApi.getSelectedNodes();\n let itemsSelectionNew = [];\n let itemsSelectionDetailNew = [];\n let dataNode;\n nodeSelections &&\n nodeSelections.length > 0 &&\n nodeSelections.forEach((node) => {\n itemsSelectionNew.push(node.id);\n itemsSelectionDetailNew.push(node.data);\n dataNode = node;\n });\n refItemSelection.current = itemsSelectionNew;\n refItemsSelectionDetail.current = itemsSelectionDetailNew;\n refPageItemsSelection.current = [\n { page: agGridCurrentPagination, items: [...refItemSelection.current] },\n ];\n refPageItemsSelectionDetail.current = [\n {\n page: agGridCurrentPagination,\n items: [...refItemsSelectionDetail.current],\n },\n ];\n setItemsSelectionLog(refItemSelection.current);\n setItemsSelectionDetailLog(refItemsSelectionDetail.current);\n setPageItemsSelectionLog(refPageItemsSelection.current);\n setPageItemsSelectionDetailLog(refPageItemsSelectionDetail.current);\n setClassNameHeaderCheckbox();\n // setItemsSelection(itemsSelectionNew);\n setVisibleSelection(false);\n const data = Object.assign({}, dataNode?.data);\n dispatch(actionsGridView.updateItemCurrentSelection(data));\n isShowDetailOn && dispatch(actionsGridView.updateVisible(true));\n };\n const handleModalAppend = () => {\n const agGridApi = refGrid.current.api;\n\n let nodeSelections = agGridApi.getSelectedNodes();\n let itemsSelectionNew = [];\n let itemsSelectionDetailNew = [];\n\n nodeSelections &&\n nodeSelections.length > 0 &&\n nodeSelections.forEach((node) => {\n itemsSelectionNew.push(node.id);\n itemsSelectionDetailNew.push(node.data);\n });\n agGridApi.forEachNode((node) => {\n if (refItemSelection.current.indexOf(node.id) > -1) {\n node.setSelected(true);\n }\n });\n refItemSelection.current = _.union(\n refItemSelection.current,\n itemsSelectionNew\n );\n refItemsSelectionDetail.current = _.uniqBy(\n [...refItemsSelectionDetail.current, ...itemsSelectionDetailNew],\n 'id'\n );\n refPageItemsSelection.current.push({\n page: agGridCurrentPagination,\n items: itemsSelectionNew,\n });\n refPageItemsSelectionDetail.current.push({\n page: agGridCurrentPagination,\n items: itemsSelectionDetailNew,\n });\n\n setItemsSelectionLog(refItemSelection.current);\n setItemsSelectionDetailLog(refItemsSelectionDetail.current);\n setPageItemsSelectionLog(refPageItemsSelection.current);\n setPageItemsSelectionDetailLog(refPageItemsSelectionDetail.current);\n setClassNameHeaderCheckbox();\n setVisibleSelection(false);\n };\n\n const handleModalCancel = () => {\n const agGridApi = refGrid.current.api;\n\n let nodeSelections = agGridApi.getSelectedNodes();\n nodeSelections &&\n nodeSelections.length > 0 &&\n nodeSelections.forEach((node) => {\n node.setSelected(false);\n });\n\n agGridApi.forEachNode((node) => {\n if (refItemSelection.current.indexOf(node.id) > -1) {\n node.setSelected(true);\n }\n });\n setItemsSelectionLog(refItemSelection.current);\n setItemsSelectionDetailLog(refItemsSelectionDetail.current);\n setPageItemsSelectionLog(refPageItemsSelection.current);\n setPageItemsSelectionDetailLog(refPageItemsSelectionDetail.current);\n setClassNameHeaderCheckbox();\n setVisibleSelection(false);\n };\n\n const getRowNodeId = useCallback((data) => {\n return nodeIdName ? data?.[nodeIdName] : data.id;\n }, []);\n\n const onCallbackSelectedRowFromOutside = (rowData) => {\n if (typeof onHandleSelectedRowCustom === 'function') {\n const selectedItemsDetail =\n refSelection.current.getItemsSelectionDetailLog();\n\n onHandleSelectedRowCustom(selectedItemsDetail || [], rowData);\n }\n };\n\n const handleMovedColumn = () => {\n const agGridColumnApi = refGrid.current.columnApi;\n\n const result = agGridColumnApi\n .getAllGridColumns()\n .map((col) => col.colDef?.field);\n\n dispatch(actionsGridView.changePositionColumns(result));\n };\n\n // add isColumnsChanged props to fix bug when the modal grid show will make\n // columns in modal choose columns will uncheck\n const handleDisplayedColumnsChanged = () => {\n const agGridColumnApi = refGrid.current.columnApi;\n\n if (typeof agGridColumnApi === 'object') {\n const virtualColumns = agGridColumnApi.getAllDisplayedVirtualColumns();\n if (virtualColumns && isColumnsChanged) {\n const result = virtualColumns.map((col) => col.colDef?.field);\n if (!_.isEqual(result, refVirtualColumns.current)) {\n refVirtualColumns.current = result;\n dispatch(actionsGridView.changeDisplayedColumns(result));\n }\n }\n }\n };\n\n const onCellFocused = (e) => {\n if (e?.column?.colDef?.field === 'dragColumn') {\n e.api.gridOptionsWrapper.gridOptions.suppressRowClickSelection = true;\n } else {\n e.api.gridOptionsWrapper.gridOptions.suppressRowClickSelection = false;\n }\n };\n\n const onHeaderCheckboxClick = (e, params) => {\n let className = e.currentTarget.className;\n let itemsSelectionNew = [];\n let itemsSelectionDetailNew = [];\n\n if (className.indexOf('ant-checkbox-checked') > -1) {\n params.api.forEachNode((node) => {\n node.setSelected(false);\n refItemSelection.current = refItemSelection.current.filter(\n (item) => item !== node.id\n );\n refItemsSelectionDetail.current =\n refItemsSelectionDetail.current.filter(\n (item) => !isItemIdEqualToNodeId(item, node?.id)\n );\n });\n let pageItemsSelectionFilter =\n (refPageItemsSelection.current &&\n refPageItemsSelection.current.length > 0 &&\n refPageItemsSelection.current.filter(\n (pageItems) => pageItems.page !== refAgGridCurrentPagination.current\n )) ||\n [];\n let pageItemsSelectionDetailFilter =\n (refPageItemsSelectionDetail.current &&\n refPageItemsSelectionDetail.current.length > 0 &&\n refPageItemsSelectionDetail.current.filter(\n (pageItems) => pageItems.page !== refAgGridCurrentPagination.current\n )) ||\n [];\n refPageItemsSelection.current = pageItemsSelectionFilter;\n refPageItemsSelectionDetail.current = pageItemsSelectionDetailFilter;\n } else {\n params.api.forEachNode((node) => {\n node.setSelected(true);\n itemsSelectionNew.push(node.id);\n itemsSelectionDetailNew.push(node.data);\n });\n refItemSelection.current = _.union(\n refItemSelection.current,\n itemsSelectionNew\n );\n refItemSelection.current = _.union(\n refItemSelection.current,\n itemsSelectionNew\n );\n refItemsSelectionDetail.current = _.uniqBy(\n [...refItemsSelectionDetail.current, ...itemsSelectionDetailNew],\n 'id'\n );\n let pageItemsSelectionFilter =\n (refPageItemsSelection.current &&\n refPageItemsSelection.current.length > 0 &&\n refPageItemsSelection.current.filter(\n (pageItems) => pageItems.page !== refAgGridCurrentPagination.current\n )) ||\n [];\n let pageItemsSelectionDetailFilter =\n (refPageItemsSelectionDetail.current &&\n refPageItemsSelectionDetail.current.length > 0 &&\n refPageItemsSelectionDetail.current.filter(\n (pageItems) => pageItems.page !== refAgGridCurrentPagination.current\n )) ||\n [];\n pageItemsSelectionFilter.push({\n page: refAgGridCurrentPagination.current,\n items: itemsSelectionNew,\n });\n pageItemsSelectionDetailFilter.push({\n page: refAgGridCurrentPagination.current,\n items: itemsSelectionDetailNew,\n });\n refPageItemsSelection.current = pageItemsSelectionFilter;\n refPageItemsSelectionDetail.current = pageItemsSelectionDetailFilter;\n }\n setItemsSelectionLog(refItemSelection.current);\n setPageItemsSelectionLog(refPageItemsSelection.current);\n\n if (refPageItemsSelection.current) {\n let result = [];\n refPageItemsSelection.current.forEach((data) => {\n result = result.concat(data.items);\n });\n const getSelectionList =\n callbackDataListSelection?.func || callbackDataListSelection;\n if (typeof getSelectionList === 'function') {\n getSelectionList(result.map((stringId) => _.toNumber(stringId)));\n }\n }\n\n setItemsSelectionDetailLog(refItemsSelectionDetail.current);\n setPageItemsSelectionDetailLog(refPageItemsSelectionDetail.current);\n\n setClassNameHeaderCheckbox(\n refAgGridCurrentPagination.current,\n refAgGridTotalPagination.current,\n refAgGridPageSize.current\n );\n };\n\n const { notCheckTotalRecordAgGrid } = gridConfigProps ?? {};\n\n return (\n \n \n {forceLoading ? (\n
Reloading...
\n ) : (\n \n {\n // check callback is for menu\n if (params.type !== 'columnMenu') {\n return;\n }\n\n onMenuClick(params);\n }}\n // modules: AllModules,\n // EVENTS\n // Add event handlers\n onRowClicked={onRowClicked}\n onSelectionChanged={onSelectionChanged}\n onRowSelected={onRowSelected}\n // onColumnResized={(event) => {\n // console.log('A column was resized');\n // }}\n onGridReady={onGridReadyfunction}\n isScrollLag={(event) => {\n return false;\n }}\n // onPaginationChanged={(event) => {\n // console.log('pagi');\n // }}\n onSortChanged={onHandleSortChanged}\n onFilterChanged={onHandleFilterChanged}\n onFilterModified={() => {}} // a trick for the Apply button fire onHandleFilterChanged\n rowClassRules={rowClassRules && rowClassRules}\n onDragStopped={handleMovedColumn}\n onDisplayedColumnsChanged={handleDisplayedColumnsChanged}\n onCellFocused={onCellFocused}\n applyColumnDefOrder={true}\n rowMultiSelectWithClick={\n false\n } /* TODO: rowMultiSelectWithClick = true then pageSelectionItems will not clear, maybe fix after*/\n suppressFieldDotNotation={true}\n alwaysShowHorizontalScroll={true}\n alwaysShowVerticalScroll={true}\n onRowDoubleClicked={onRowDoubleClicked}\n {...gridConfigProps}\n >\n\n {notCheckTotalRecordAgGrid\n ? null\n : agGridTotalPagination <= 0 && (\n \n \n \n )}\n\n \n \n {!hidePagination && (\n <>\n \n {minimizePagination ||\n isShowDetailOn ||\n showAddToFolder ? null : (\n <>\n \n \n \n \n )}\n \n )}\n \n\n \n \n\n {(gridView || !isHiddenAbbandonDialog) && (\n \n )}\n \n )}\n \n \n );\n});\n\nAgGrid.propTypes = {\n styleGrid: PropTypes.object,\n columnDefs: PropTypes.array,\n urlGrid: PropTypes.string,\n urlGridDistinct: PropTypes.string,\n paramsGrid: PropTypes.object,\n gridView: PropTypes.bool,\n tabView: PropTypes.string,\n pathname: PropTypes.string,\n requestParams: PropTypes.oneOfType([\n PropTypes.object,\n PropTypes.oneOf([null]),\n ]),\n callbackDataListSelection: PropTypes.func,\n hidePagination: PropTypes.bool,\n filterFromMainPage: PropTypes.array,\n rowClassRules: PropTypes.object,\n frameworkComponents: PropTypes.object,\n triggerDownload: PropTypes.bool,\n onDownloadGridHandler: PropTypes.func,\n downloadFileType: PropTypes.string,\n isDownloadAllColumns: PropTypes.bool,\n notShowHeaderCheckbox: PropTypes.bool,\n showCheckboxSelectionRender: PropTypes.bool,\n};\n\nexport default AgGrid;\n","import { LicenseManager } from 'ag-grid-enterprise';\nimport 'ag-grid-enterprise';\nimport 'ag-grid-community/dist/styles/ag-grid.css';\nimport 'ag-grid-community/dist/styles/ag-theme-alpine.css';\n\nLicenseManager.setLicenseKey(\n 'Using_this_AG_Grid_Enterprise_key_( AG-040843 )_in_excess_of_the_licence_granted_is_not_permitted___Please_report_misuse_to_( legal@ag-grid.com )___For_help_with_changing_this_key_please_contact_( info@ag-grid.com )___( Global Vertical Innovations, LLC )_is_granted_a_( Multiple Applications )_Developer_License_for_( 1 ))_Front-End_JavaScript_developer___All_Front-End_JavaScript_developers_need_to_be_licensed_in_addition_to_the_ones_working_with_AG_Grid_Enterprise___This_key_has_not_been_granted_a_Deployment_License_Add-on___This_key_works_with_AG_Grid_Enterprise_versions_released_before_( 11 May 2024 )____[v2]_MTcxNTM4MjAwMDAwMA==d035e6c32ae72202e23beccd712ab105'\n);\n","import React, { useState, useEffect } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { Row, Col, Input } from 'antd';\n\nimport { AgGrid } from 'common/components';\n\nimport * as actions from 'pages/branded-products-apl/controllers/actions';\nimport * as selectors from 'pages/branded-products-apl/controllers/selectors';\n\nimport { REDUX_MODULE, useInjectRedux } from 'hooks/useRedux';\n\nimport { GRID_ID } from 'common/components/grid-view/utils';\n\nimport { MASTER_APL_NAME } from 'pages/home/ribbon/components/sections/product-apl/constants';\n\nimport * as endpoints from 'services/product/endpoints';\n\nconst { Search } = Input;\n\nconst AplGrid = (props) => {\n const dispatch = useDispatch();\n\n useInjectRedux(REDUX_MODULE.PRODUCT_APL);\n\n const { onSelectRow } = props;\n\n const [searchText, setSearchText] = useState(null);\n\n const columns = useSelector(selectors.selectProductAPLColumns());\n\n const onSearch = (value) => {\n setSearchText(value);\n };\n\n useEffect(() => {\n dispatch(\n actions.getAPLGridColumns({\n linkTarget: '_blank',\n })\n );\n }, [dispatch]);\n\n const rowClassRules = {\n 'active-row': ({ data }) => data?.aplName === MASTER_APL_NAME,\n };\n\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nexport default AplGrid;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Button, Typography } from 'antd';\nimport { injectIntl } from 'react-intl';\nimport classNames from 'classnames';\n\nimport './ButtonWithIcon.less';\n\nconst { Text } = Typography;\n\nconst ButtonLargeIcon = ({\n icon,\n label,\n toggle = false,\n className,\n intl,\n ...otherProps\n}) => {\n const mapToLabelContent = () => {\n let newLabel = '';\n try {\n newLabel = intl.formatMessage(label);\n } catch (e) {\n newLabel = label;\n }\n return newLabel;\n };\n\n //! COMPONENT DEPRECATED\n //! use RibbonButton instead\n return (\n \n
\n \n {mapToLabelContent()}\n \n \n );\n};\n\nButtonLargeIcon.prototype = {\n icon: PropTypes.element,\n label: PropTypes.object,\n onClick: PropTypes.func,\n toggle: PropTypes.bool,\n className: PropTypes.string,\n disabled: PropTypes.bool,\n};\n\nexport default injectIntl(ButtonLargeIcon);\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Button, Typography } from 'antd';\nimport { injectIntl } from 'react-intl';\nimport classNames from 'classnames';\n\nimport './ButtonWithIcon.less';\n\nconst { Text } = Typography;\n\nconst ButtonSmallIcon = ({\n icon,\n label,\n toggle = false,\n className = '',\n textDisplay,\n intl,\n ...otherProps\n}) => {\n const mapToLabelContent = () => {\n let newLabel = '';\n try {\n newLabel = intl.formatMessage(label);\n } catch (e) {\n newLabel = label;\n }\n return newLabel;\n };\n return (\n \n \n {textDisplay\n ? textDisplay\n : // \n mapToLabelContent()}\n \n \n );\n};\n\nButtonSmallIcon.prototype = {\n icon: PropTypes.element,\n label: PropTypes.object,\n // display text without translation\n textDisplay: PropTypes.string,\n onClick: PropTypes.func,\n toggle: PropTypes.bool,\n className: PropTypes.string,\n};\n\nexport default injectIntl(ButtonSmallIcon);\n","import React from 'react';\nimport { Row } from 'antd';\n\nconst ContainerButton = (props) => {\n const { alignCenter, style = {} } = props;\n\n const propsStyle = {\n alignItems: alignCenter ? 'center' : '',\n };\n\n return ;\n};\n\nexport default ContainerButton;\n","import React, { useMemo } from 'react';\nimport { Col } from 'antd';\n\nconst ItemButton = (props) => {\n const { noneSpan, isVertical, style = {}, ...restProps } = props;\n\n const spanConfig = useMemo(() => {\n return noneSpan ? {} : { span: 12 };\n }, [noneSpan]);\n\n return (\n \n );\n};\n\nexport default ItemButton;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport classNames from 'classnames';\nimport { Button, Typography } from 'antd';\nimport { LoadingOutlined } from '@ant-design/icons';\n\nimport { injectIntl } from 'react-intl';\n\nimport './RibbonButton.less';\n\nconst { Text } = Typography;\n\nconst RibbonButton = ({\n icon,\n label,\n toggle = false,\n className,\n intl,\n size,\n disabled,\n loading,\n ...otherProps\n}) => {\n const mapToLabelContent = () => {\n let newLabel = '';\n try {\n newLabel = intl.formatMessage(label);\n } catch (e) {\n newLabel = label;\n }\n return newLabel;\n };\n\n const buttonIcon = loading ? : icon;\n\n return (\n \n {buttonIcon ? (\n {buttonIcon}\n ) : null}\n \n {mapToLabelContent()}\n \n \n );\n};\n\nRibbonButton.prototype = {\n icon: PropTypes.element,\n label: PropTypes.object,\n onClick: PropTypes.func,\n toggle: PropTypes.bool,\n className: PropTypes.string,\n disabled: PropTypes.bool,\n};\n\nexport default injectIntl(RibbonButton);\n","import { Typography, Button } from 'antd';\nimport { CaretDownOutlined, CaretUpOutlined } from '@ant-design/icons';\n\nconst { Text } = Typography;\n\nconst ShowMoreOrLess = (props) => {\n const {\n fullList,\n showList,\n style = {},\n setShowList,\n maxShowLess = 6,\n } = props;\n\n const type =\n fullList?.length === showList?.length ? 'showing full' : 'showing less';\n\n const content = type === 'showing full' ? 'View less' : 'View more';\n const icon =\n type === 'showing full' ? : ;\n\n const onClickShowMoreOrLessButton = () => {\n if (type === 'showing full') {\n setShowList(fullList.slice(0, maxShowLess));\n return;\n }\n\n if (type === 'showing less') {\n setShowList(fullList);\n return;\n }\n };\n\n const {\n text: textStyle = {},\n wrapper: wrapperStyle = {},\n button: buttonStyle = {},\n } = style;\n\n if (!fullList || fullList?.length <= maxShowLess) return null;\n\n return (\n \n \n \n {content}\n \n \n );\n};\n\nexport default ShowMoreOrLess;\n","import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport {\n ContactsOutlined,\n MailOutlined,\n MessageOutlined,\n FileTextOutlined,\n} from '@ant-design/icons';\nimport { Menu, Dropdown, Tooltip } from 'antd';\nimport { FormattedMessage } from 'react-intl';\nimport Messages from 'i18n/messages/home';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nimport * as globalAtions from '@redux/global/actions';\nimport * as globalSelectors from '@redux/global/selectors';\n\nimport userSelectors from '@redux/user/selectors';\n\nimport * as chatActions from 'common/components/message/controller/actions';\nimport * as emailActions from 'common/components/mail/controller/actions';\n\nimport * as chatServices from 'services/chatServices';\nimport { CHATTYPE } from 'static/Constants';\n\nimport { SECURE_CONFIG } from 'utils/SecureRoute';\nimport { useCheckPermissionOR } from 'hooks/useCheckPermissions';\n\nconst ActionsRibbonBar = (props) => {\n const { view, selectedItemList } = props;\n\n const dispatch = useDispatch();\n\n const userInfo = useSelector(userSelectors.makeSelectUserInfo());\n\n const contactCardInfo = useSelector(\n userSelectors.makeSelectContactCardInfo()\n );\n\n const hubConnection = useSelector(globalSelectors.selectSignalRConnection());\n\n const isChatViewOpen = useSelector(globalSelectors.selectIsChatViewOpen());\n const isEmailViewOpen = useSelector(globalSelectors.selectIsEmailViewOpen());\n\n const checkPermission = useCheckPermissionOR();\n const canChat = checkPermission([SECURE_CONFIG.CHAT_PERSONAL.PASS]);\n\n const isUser = view === 'user';\n const viewedUserCompany = contactCardInfo?.memberId;\n const loggedUserCompany = userInfo?.member?.id;\n const isUserSameCompany = viewedUserCompany === loggedUserCompany;\n\n const shouldShowContactCard = isUser && isUserSameCompany;\n\n const getTooltipProps = () => {\n const tooltipProps = {\n title: ,\n mouseEnterDelay: 0,\n mouseLeaveDelay: 0,\n };\n\n if (!shouldShowContactCard) tooltipProps.visible = false;\n\n return tooltipProps;\n };\n\n const handleSendMessage = async (type, user) => {\n try {\n const paramsSubmit = {\n userChatType: CHATTYPE.USER,\n chatType: type === 'email' ? 'Email' : 'P2P',\n threadName:\n type === 'email'\n ? view === 'user'\n ? selectedItemList &&\n selectedItemList.length > 0 &&\n selectedItemList[0]?.fullName\n : selectedItemList &&\n selectedItemList.length > 0 &&\n selectedItemList[0]?.memberName\n : '',\n users:\n view === 'user'\n ? [\n selectedItemList &&\n selectedItemList.length > 0 &&\n selectedItemList[0]?.id,\n ]\n : [],\n companies:\n view === 'user'\n ? []\n : [\n selectedItemList &&\n selectedItemList.length > 0 &&\n selectedItemList[0]?.id,\n ],\n };\n if (!isChatViewOpen && type !== 'email') {\n dispatch(globalAtions.toggleChatView(true));\n }\n\n if (!isEmailViewOpen && type === 'email') {\n dispatch(globalAtions.toggleEmailView(true));\n }\n\n const response = await chatServices.initChatCommunication(paramsSubmit);\n if (response?.isSuccess) {\n if (hubConnection) {\n try {\n setTimeout(() => {\n if (type === 'email') {\n const params = {\n threadId: response?.data?.threadId,\n userId: `U-${userInfo?.id}`,\n };\n dispatch(emailActions.getEmailThreadInfo(params));\n dispatch(\n emailActions.getEmailThreadInfoContent(\n response?.data?.threadId\n )\n );\n } else {\n dispatch(chatActions.setChatView('threadMsg'));\n dispatch(\n chatActions.getThreadInfo(\n response?.data?.threadId,\n `U-${userInfo?.id}`\n )\n );\n dispatch(\n chatActions.getThreadMessages(response?.data?.threadId)\n );\n dispatch(\n globalAtions.updateListAfterSendMessage({\n threadId: response?.data?.threadId,\n creatorId: `U-${userInfo?.id}`,\n })\n );\n }\n }, 500);\n } catch (error) {}\n }\n }\n } catch (error) {}\n };\n\n //* render\n const disabledDropdown = !(\n (view === 'member' ||\n view === 'product-shared' ||\n (view === 'user' && contactCardInfo?.userId !== userInfo?.id)) &&\n selectedItemList?.length === 1\n );\n\n const menuOptions = (\n \n {/* \n }\n label={Messages.cardMemberFull}\n onClick={onButtonClickHandler}\n className='button-item-dropdown'\n />\n */}\n \n }\n label={Messages.messageMemberFull}\n onClick={() => handleSendMessage()}\n className='button-item-dropdown'\n disabled={!canChat}\n />\n \n\n \n }\n label={Messages.emailMemberFull}\n onClick={() => handleSendMessage('email')}\n className='button-item-dropdown'\n disabled={!canChat}\n />\n \n \n }\n label={Messages.sendText}\n // onClick={() => setShowText(true)}\n className='button-item-dropdown'\n disabled\n />\n \n\n {/* \n }\n label={Messages.cardMemberFull}\n onClick={() => setShowContact(true)}\n className='contact-config__dropdown--item'\n />\n */}\n \n );\n\n return (\n \n \n }\n label={Messages.contactControl}\n disabled={disabledDropdown || !canChat}\n />\n \n \n );\n};\n\nexport default ActionsRibbonBar;\n","import React from 'react';\nimport { Modal } from 'antd';\nimport './DialogFunction.less';\n\nimport { ErrorIcon, InfoIcon, SuccessIcon, WarnIcon } from './DialogIcon';\n\nimport classnames from 'classnames';\n\nfunction dialogFunction(props) {\n const { type, className } = props;\n\n return Modal.confirm({\n ...props,\n className: classnames('dialog-modal', className),\n icon:\n type === 'warn' ? (\n \n ) : type === 'error' ? (\n \n ) : type === 'success' ? (\n \n ) : (\n \n ),\n cancelButtonProps: {\n ...props.cancelButtonProps,\n className: 'dialog-cancel-button',\n },\n okButtonProps: { ...props.okButtonProps, className: 'dialog-ok-button' },\n });\n}\ndialogFunction.defaultProps = {\n okText: 'OK',\n cancelText: 'Cancel',\n type: 'info',\n};\n\nexport default dialogFunction;\n\nexport const customFooterDialogFunction = ({ ...props }) => {\n const modal = dialogFunction({\n ...props,\n className: 'custom-dialog-function',\n });\n\n return modal;\n};\n\nexport const dialogFunctionAsync = (config) => {\n const { onOk, onCancel, ...restConfig } = config;\n\n return new Promise((resolve) => {\n dialogFunction({\n ...restConfig,\n onOk: () => {\n resolve({ ok: true });\n },\n onCancel: () => {\n resolve({ ok: false });\n },\n });\n });\n};\n","import React from 'react';\nimport { CloseOutlined } from '@ant-design/icons';\nimport './Icon.less';\n\nconst InfoIcon = () => {\n return (\n
\n
\n \n
\n
\n );\n};\n\nexport default InfoIcon;\n","import React from 'react';\nimport { InfoOutlined } from '@ant-design/icons';\nimport './Icon.less';\n\nconst InfoIcon = () => {\n return (\n
\n
\n \n
\n
\n );\n};\n\nexport default InfoIcon;\n","import React from 'react';\nimport { CheckOutlined } from '@ant-design/icons';\nimport './Icon.less';\n\nconst InfoIcon = () => {\n return (\n
\n
\n \n
\n
\n );\n};\n\nexport default InfoIcon;\n","import React from 'react';\nimport { ExclamationOutlined } from '@ant-design/icons';\nimport './Icon.less';\n\nconst InfoIcon = () => {\n return (\n
\n
\n \n
\n
\n );\n};\n\nexport default InfoIcon;\n","import React from 'react';\nimport DigitalRight from 'assets/DRM.png';\nimport { Tooltip } from 'antd';\nimport { injectIntl } from 'react-intl';\n\nconst DigitalRightIcon = (props) => {\n const { height, width, size, intl, type, ...restProps } = props;\n const iconHeight =\n size === 'small'\n ? 20\n : size === 'normal'\n ? 30\n : size === 'large'\n ? 50\n : height;\n const iconWidth =\n size === 'small'\n ? 20\n : size === 'normal'\n ? 30\n : size === 'large'\n ? 50\n : width;\n return (\n <>\n \n \n \n \n );\n};\nexport default injectIntl(DigitalRightIcon);\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\n\nimport classnames from 'classnames';\n\nconst DropWrap = (props) => {\n const {\n children,\n onDropData,\n dropClassName = '',\n className,\n ...rest\n } = props;\n const [isDraggingOver, setIsDraggingOver] = useState(false);\n\n const onDrop = (e) => {\n const dropData = JSON.parse(e.dataTransfer.getData('dragData'));\n setIsDraggingOver(false);\n onDropData && onDropData(dropData);\n };\n\n const onDragOver = (e) => {\n e.preventDefault();\n setIsDraggingOver(true);\n };\n\n const onDragLeave = (e) => {\n setIsDraggingOver(false);\n };\n\n return (\n \n {children}\n \n );\n};\n\nDropWrap.propTypes = {\n style: PropTypes.object,\n children: PropTypes.oneOfType([\n PropTypes.node,\n PropTypes.arrayOf(PropTypes.node),\n ]),\n handleDropData: PropTypes.func,\n dropClassName: PropTypes.string,\n};\n\nexport default DropWrap;\n","import React from 'react';\n\nimport { Image, Typography, Tree } from 'antd';\n\nimport { useControllableState } from 'hooks/useControllableState';\n\nimport './FolderTree.less';\n\nconst noop = () => {};\n\nexport const FolderTree = (props) => {\n const {\n treeData,\n expandedKeys: expandedKeysProp,\n onExpandedChange = noop,\n selectedItem: selectedItemProp,\n onSelectedChange = noop,\n onLoadData = () => new Promise((resolve) => resolve()),\n ...rest\n } = props;\n\n const [expandedKeys, setExpandedKeys] = useControllableState({\n defaultProp: [],\n prop: expandedKeysProp,\n onChange: onExpandedChange,\n });\n\n const [{ selectedKeys }, setSelectedItem] = useControllableState({\n defaultProp: {},\n prop: selectedItemProp,\n onChange: onSelectedChange,\n });\n\n const onExpandItem = (expandedKeys) => {\n setExpandedKeys(expandedKeys);\n };\n\n const onSelectItem = (selectedKeys, info) => {\n setSelectedItem({ selectedKeys, info });\n };\n\n return (\n \n );\n};\n\nexport const TitleFolder = ({ title, style, ...rest }) => {\n return (\n \n {title}\n \n );\n};\n\nexport const IconAsset = ({ src, preview, ...rest }) => {\n return ;\n};\n\nexport const IconFileAsset = (props) => {\n return ;\n};\n\nexport const IconFolderAsset = (props) => {\n return ;\n};\n\nexport const TreeFiles = (props) => {\n return ;\n};\n\nexport const NodeTree = ({ title, children, style, id, ...rest }) => {\n return (\n \n \n {children}\n \n );\n};\n","import { useCallback, useEffect, useState } from 'react';\n\nimport { CustomNotification } from 'common/components';\n\nimport { useAsync, useCallbackRef, useControllableState } from 'hooks';\n\nimport { getFolderList, getItemsOfFolder } from 'services/new-folder';\nimport { getFolderOwnByUser, getFolderShortDetail } from 'services/folder';\n\nimport {\n buildHierarchyTreeFolder,\n getHierarchyExpandedKeys,\n getNodeTreeData,\n mappingFolderToTreeData,\n updateTreeData,\n findNodeTreeById,\n} from './utils';\n\nimport { sleep } from 'utils/delay';\nimport { toUniqueList } from 'utils';\nimport { sortFolderToTop } from 'pages/folders/shared/utils';\n\nexport const filterParams = {\n folder: [\n {\n fieldName: 'type',\n filterType: 'Equal',\n value: 'folder', //\n },\n ],\n all: [],\n};\n\nconst defaultFolderParam = {\n isAllowViewDetail: false,\n};\n\nconst defaultFileParam = {\n isAllowViewDetail: false,\n};\n\nexport const useGetFolderTreeData = (params) => {\n const {\n defaultTreeProp = [],\n defaultSelectedItem = {},\n defaultExpandedKeys = [],\n pageIndex = 1,\n pageSize = 20,\n filterType = 'all',\n folderParam = defaultFolderParam,\n fileParam = defaultFileParam,\n navigatedIdFolder,\n } = params;\n const { folderDetail } = useGetFolderDetail({\n folderId: navigatedIdFolder,\n isLoadContent: false,\n });\n\n const { hierarchy, level } = folderDetail;\n const isRoot = level === 1;\n\n const [statusGenerateTree, setStatusGenerateTree] = useState('idle');\n const [treeData, setTreeData] = useControllableState({\n defaultProp: defaultTreeProp,\n });\n const [expandedKeys, setExpandedKeys] = useControllableState({\n defaultProp: defaultExpandedKeys,\n });\n const [loadedKeys, setLoadedKeys] = useState([]);\n const [selectedItem, setSelectedItem] = useControllableState({\n defaultProp: defaultSelectedItem,\n });\n\n const handleUpdateTreeData = useCallback(\n (data) => setTreeData(data),\n [setTreeData]\n );\n\n const handleUpdateExpandedKeys = useCallback(\n (keys) => setExpandedKeys(keys),\n [setExpandedKeys]\n );\n\n const handleSelectNodeById = useCallbackRef((id) => {\n const foundNode = findNodeTreeById(treeData, id);\n\n if (!foundNode) return false; //* 4641: cannot found nested folder, so return result to rebuild tree\n\n setSelectedItem({\n selectedKeys: [foundNode.key],\n selectedFolder: foundNode.data,\n });\n setExpandedKeys(expandedKeys.concat([foundNode.key]));\n\n return foundNode;\n });\n\n const handleUpdateSelectedItem = useCallbackRef((item) => {\n const wasClickOnSameItem = selectedItem?.selectedKeys?.includes(\n item?.info?.node?.key\n );\n\n const isFolderType =\n item?.info?.node?.data?.type?.toLowerCase() === 'folder';\n\n if (wasClickOnSameItem) return;\n\n setSelectedItem({\n selectedKeys: item?.selectedKeys,\n selectedFolder: item?.info?.node?.data,\n });\n\n isFolderType &&\n setExpandedKeys(toUniqueList(expandedKeys.concat(item.selectedKeys)));\n });\n\n const handleUpdateLoadedKeys = useCallback(\n (keys) =>\n setLoadedKeys((prevVal) => {\n if (prevVal?.includes(keys)) {\n return prevVal;\n }\n return prevVal?.concat(keys);\n }),\n [setLoadedKeys]\n );\n\n const handleBuildRootTree = useCallbackRef(() => {\n const rootNode = getNodeTreeData({\n node: { ...folderDetail, type: 'folder' }, // folder doesn't have type value !!!\n folderParam,\n fileParam,\n });\n setExpandedKeys([rootNode.key]);\n setStatusGenerateTree('success');\n setSelectedItem({\n selectedKeys: [rootNode?.key],\n selectedFolder: rootNode?.data,\n });\n handleUpdateTreeData([rootNode]);\n });\n\n const handleBuildHierarchyTree = useCallbackRef(async (hierarchyId) => {\n const listIds = hierarchyId.split('/').filter(Boolean); //\n\n setStatusGenerateTree('loading');\n\n try {\n const hierarchyTreeData = await buildHierarchyTreeFolder({\n listIds,\n folderParam,\n fileParam,\n filterType,\n });\n const foundNode = findNodeTreeById(hierarchyTreeData, navigatedIdFolder);\n\n const expandedKeys = getHierarchyExpandedKeys(\n hierarchyTreeData,\n listIds.map((id) => parseInt(id))\n );\n\n setExpandedKeys(expandedKeys);\n setLoadedKeys(expandedKeys);\n setSelectedItem({\n selectedKeys: [foundNode?.key],\n selectedFolder: foundNode?.data,\n });\n setStatusGenerateTree('success');\n handleUpdateTreeData(hierarchyTreeData);\n\n return {\n foundNode,\n hierarchyTreeData,\n };\n } catch (error) {\n setStatusGenerateTree('error');\n handleUpdateTreeData([]);\n }\n });\n\n useEffect(() => {\n if (isRoot) {\n handleBuildRootTree();\n return;\n }\n\n //* build tree from subfolder\n if (hierarchy) {\n // hierarchy is parent path\n const fullHierarchyId = `${hierarchy}/${navigatedIdFolder}`;\n handleBuildHierarchyTree(fullHierarchyId);\n }\n }, [\n isRoot,\n hierarchy,\n handleBuildHierarchyTree,\n handleBuildRootTree,\n navigatedIdFolder,\n ]);\n\n // Need to catch error, this function is using pageSize, pageIndex as params. Wrap this function with useCallbackRef ???\n const handleLoadMoreFolder = async ({ key, children, data }) => {\n if (loadedKeys.includes(key)) return;\n\n const { id: folderId } = data;\n\n const params = {\n folderId,\n pageIndex, // change later\n pageSize, // change later\n filters: filterParams[filterType],\n sort: [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ], // new first,\n };\n\n const response = await getItemsOfFolder(params);\n\n return new Promise(async (resolve) => {\n if (children || response === null) {\n resolve();\n return;\n }\n\n const sortedData = response?.data?.gridData?.sort(sortFolderToTop);\n\n const mappedTreeData = mappingFolderToTreeData(\n sortedData,\n folderParam,\n fileParam\n );\n\n await sleep(500); // sleep a little bit to update tree (get idea from antd :))\n setTreeData((prevTreeData) =>\n updateTreeData(prevTreeData, key, mappedTreeData)\n );\n resolve();\n });\n };\n\n const handleSetStatusTree = (status) => {\n setStatusGenerateTree(status);\n };\n\n const handleSelectDeepNestedFolder = (folder) => {\n const folderId = folder?.type?.toLowerCase() === 'folder' && folder?.id;\n\n if (!folderId) return;\n\n const foundTreeNode = handleSelectNodeById(folderId);\n\n if (!foundTreeNode) rebuildTreeToSelectFolder(folder);\n };\n\n const rebuildTreeToSelectFolder = async (selectedFolder) => {\n if (!selectedFolder) return;\n\n const buildingHierarchy = `${selectedFolder.hierarchy}/${selectedFolder.id}`;\n\n const { foundNode } = await handleBuildHierarchyTree(buildingHierarchy);\n\n if (!foundNode) return;\n\n //* if foundNode mean building succeed\n await sleep(1); //* make sure state updated\n handleSelectNodeById(selectedFolder.id);\n };\n\n return {\n isLoadingTree:\n statusGenerateTree === 'idle' || statusGenerateTree === 'loading',\n treeData,\n expandedKeys,\n loadedKeys,\n selectedItem,\n handleSelectNodeById,\n handleUpdateSelectedItem,\n handleUpdateTreeData,\n handleLoadMoreFolder,\n handleUpdateExpandedKeys,\n handleUpdateLoadedKeys,\n handleSetStatusTree,\n handleBuildHierarchyTree,\n handleSelectDeepNestedFolder,\n };\n};\n\nexport const useGetAllFolderGrid = ({ isEnabled, onResetParentId }) => {\n const { data: initialData, run, status, setData } = useAsync();\n\n const [fetchMoreFolderLoading, setFetchMoreFolderLoading] = useState(false);\n\n const handleCacheListFolder = (key, data) => {\n setData({\n ...initialData,\n [key]: data,\n });\n };\n\n const getGridFolder = () => {\n //? need to improve: use load on scroll for better performance\n const params = {\n folderId: null,\n pageIndex: 1,\n pageSize: 9999,\n filters: [\n {\n fieldName: 'isOwner',\n filterType: 'equal',\n value: true,\n },\n ],\n sort: [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ],\n };\n\n run(getFolderList(params));\n };\n\n const handleSearchFolder = async (searchText) => {\n onResetParentId?.();\n handleCacheListFolder('home', []);\n\n if (!searchText) {\n getGridFolder();\n return;\n }\n\n try {\n const { data, isSuccess } = await getFolderOwnByUser({\n Search: searchText,\n });\n if (isSuccess) {\n handleCacheListFolder('home', data?.folderList);\n }\n } catch (error) {\n CustomNotification.error(error?.message ?? 'Folder is not found');\n }\n };\n\n const handleFetchMoreFolder = async (folderId) => {\n const params = {\n folderId,\n pageIndex: 1, // change later\n pageSize: 9999, // change later\n filters: [\n {\n fieldName: 'isOwner',\n filterType: 'equal',\n value: true,\n },\n {\n fieldName: 'type',\n filterType: 'equal',\n value: 'folder',\n },\n ],\n sort: [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ],\n };\n try {\n setFetchMoreFolderLoading(true);\n const { isSuccess, data, message } =\n (await getItemsOfFolder(params)) ?? {};\n if (isSuccess) {\n handleCacheListFolder(folderId, data?.gridData);\n } else {\n CustomNotification.error(message ?? 'Folder is not found');\n }\n } catch (error) {\n CustomNotification.error(error?.message ?? 'Folder is not found');\n }\n\n setFetchMoreFolderLoading(false);\n };\n useEffect(() => {\n if (isEnabled) {\n getGridFolder();\n }\n }, [run, isEnabled]);\n\n useEffect(() => {\n if (!initialData?.['home'] && initialData?.gridData)\n setData({\n home: initialData?.gridData ?? [],\n });\n }, [JSON.stringify(initialData)]);\n\n return {\n isLoading: status === 'pending' || fetchMoreFolderLoading,\n folderData: initialData,\n getGridFolder,\n handleSearchFolder,\n handleFetchMoreFolder,\n };\n};\n\nexport const useGetFolderDetail = ({ folderId, isLoadContent = false }) => {\n const { data, run } = useAsync();\n\n useEffect(() => {\n if (folderId) {\n run(\n getFolderShortDetail({\n id: folderId,\n IsLoadContent: isLoadContent,\n })\n );\n }\n }, [folderId, run]);\n\n return {\n folderDetail: data ?? {},\n };\n};\n","import React from 'react';\n\nimport {\n Breadcrumb,\n Typography,\n Popover,\n Row,\n Col,\n Button,\n Tooltip,\n} from 'antd';\n\nimport { EllipsisOutlined, HomeTwoTone } from '@ant-design/icons';\n\nimport './FolderTree.less';\n\n/*\n Will support limit items based on container later\n*/\nexport const FolderBreadcrumb = (props) => {\n const { items, onClick: onClickBreadcrumb, maxItems, ...rest } = props;\n\n const isLimited = Boolean(maxItems) && items.length > maxItems;\n\n const onClick = (breadcrumb) => {\n onClickBreadcrumb && onClickBreadcrumb(breadcrumb?.id, items);\n };\n\n if (isLimited) {\n const { overflowBreadcrumbs, otherBreadcrumbs } = separateBreadcrumbs(\n items,\n maxItems\n );\n\n const content = () => (\n \n {overflowBreadcrumbs.map((breadcrumb) => (\n {\n onClick(breadcrumb);\n }}\n >\n {breadcrumb?.folderName}\n \n ))}\n \n );\n\n return (\n \n \n
\n \n }\n />\n \n / \n
\n \n \n \n {otherBreadcrumbs.map((breadcrumb) => (\n {\n onClick(breadcrumb);\n }}\n >\n \n {breadcrumb?.folderName}\n \n \n ))}\n \n \n
\n );\n }\n\n return (\n \n {items.map((breadcrumb) => (\n {\n onClick(breadcrumb);\n }}\n >\n \n \n {breadcrumb?.id === 'home' ? (\n \n ) : (\n breadcrumb?.folderName\n )}\n \n \n \n ))}\n \n );\n};\n\nexport const FolderOverflowBreadcrumb = ({ children, ...rest }) => {\n return (\n \n {children}\n \n );\n};\n\nconst separateBreadcrumbs = (items, maxItems) => {\n const countOfItems = items.length;\n\n return {\n overflowBreadcrumbs: items.slice(0, countOfItems - maxItems),\n otherBreadcrumbs: items.slice(countOfItems - maxItems),\n };\n};\n\nexport default FolderBreadcrumb;\n","import React, { useRef, memo } from 'react';\n\nimport { Row, Avatar, Col, Typography, Divider } from 'antd';\nimport classnames from 'classnames';\n\nimport { RightOutlined } from '@ant-design/icons';\nimport EmptyFolder from 'assets/folder/empty-folder.png';\nimport hasItemsFolder from 'assets/folder/folder.png';\n\nimport DropWrap from '../drapDropWrap/drap-and-drop/DropWrap';\n\nimport useDoubleClick from 'hooks/useDoubleClick';\n\nimport { formatMDY } from 'utils/formatDate';\n\nexport const FolderItemContainer = (props) => {\n const ref = useRef();\n\n const { onClick, children, onDoubleClick, ...rest } = props;\n\n useDoubleClick({\n onSingleClick: (event) => {\n onClick?.(event);\n },\n onDoubleClick: () => onDoubleClick?.(),\n ref,\n latency: 200,\n });\n\n return (\n \n {children}\n \n );\n};\n\n// Edit component for complex info\nexport const FolderInfo = (props) => {\n const { title, style, dateCreated, children, ...rest } = props;\n return (\n \n \n \n {title}\n \n \n {children}\n
\n );\n};\n\nexport const FolderIcon = ({ src, style, ...rest }) => {\n return (\n \n );\n};\n\nexport const FolderAction = (props) => {\n return (\n
\n \n
\n );\n};\n\nexport const FolderItem = memo((props) => {\n const {\n item,\n onExpand,\n onDrop,\n handleSelectFolder,\n selectedFolderId,\n disableItemHandler,\n } = props;\n const { id, subFolderCount, dateCreated, folderName, description } =\n item ?? {};\n\n const folderSrc = subFolderCount > 0 ? hasItemsFolder : EmptyFolder;\n const title = folderName ?? description ?? '';\n\n const disabled = disableItemHandler ? disableItemHandler(item) : false;\n\n return (\n {\n if (item?.subFolderCount) onExpand(item, title);\n }}\n onClick={() => handleSelectFolder(item)}\n >\n onDrop(dropData, item)}\n >\n \n \n \n \n Date created: {formatMDY(dateCreated)}\n \n \n \n \n {item?.subFolderCount ? (\n onExpand(item, title)} />\n ) : null}\n \n \n \n \n );\n});\n","import React from 'react';\n\nimport { FolderItem } from './FolderItem';\n\nexport const FolderList = (props) => {\n const {\n onExpand,\n folderData,\n handleDropItem,\n selectedFolderId,\n onSelectFolder,\n disableItemHandler,\n } = props;\n\n const handleSelectFolder = (currentFolder) => {\n onSelectFolder && onSelectFolder(currentFolder);\n };\n\n const onDrop = (dropData, folder) => {\n if (!dropData) return;\n\n handleDropItem && handleDropItem(dropData, folder);\n };\n\n return (\n
\n {folderData.map((item) => {\n const itemProps = {\n item,\n onExpand,\n onDrop,\n handleSelectFolder,\n selectedFolderId,\n disableItemHandler,\n };\n\n return ;\n })}\n
\n );\n};\n\nexport default FolderList;\n","import React, { useState, forwardRef, useImperativeHandle } from 'react';\nimport { Input, Spin, Divider } from 'antd';\n\nimport { FolderList } from './FolderList';\nimport { FolderBreadcrumb } from './FolderBreadcrumb';\nimport DropWrap from '../drapDropWrap/drap-and-drop/DropWrap';\n\nimport { useGetAllFolderGrid } from './hooks';\nimport './FolderSelector.less';\n\nconst DEFAULT_KEY_FOLDER = [{ id: 'home', folderName: 'Home' }];\n\nexport const FolderSelector = forwardRef((props, ref) => {\n const { onDrop, onExpandFolder, onBreadcrumbChange, disableItemHandler } =\n props;\n\n const [keyFolder, setKeyFolder] = useState(DEFAULT_KEY_FOLDER);\n const [currentFolderId, setCurrentFolderId] = useState();\n const [selectedFolder, setSelectedFolder] = useState();\n\n const {\n folderData,\n isLoading,\n getGridFolder,\n handleSearchFolder,\n handleFetchMoreFolder,\n } = useGetAllFolderGrid({\n isEnabled: true,\n onResetParentId: () => setCurrentFolderId(null),\n });\n\n useImperativeHandle(\n ref,\n () => {\n return {\n reloadList: (id) => {\n id ? handleFetchMoreFolder(id) : getGridFolder();\n },\n };\n },\n []\n );\n\n const onSearch = (searchText) => {\n setKeyFolder(DEFAULT_KEY_FOLDER);\n handleSearchFolder(searchText);\n };\n\n const onSelectFolder = (currentFolder) => {\n const breadcrumbSelected = keyFolder[keyFolder?.length - 1];\n\n const newSelectedFolder =\n selectedFolder?.id === currentFolder?.id\n ? breadcrumbSelected\n : currentFolder;\n\n setSelectedFolder(newSelectedFolder);\n props?.onSelectFolder?.(newSelectedFolder);\n };\n\n const handleBreadcrumb = (valueSelected, hierarchyList) => {\n const folderId = valueSelected !== 'home' ? valueSelected : null;\n\n setCurrentFolderId(folderId);\n setSelectedFolder(null);\n setKeyFolder((pre) => {\n const indexBreadcrumb = keyFolder\n .map((item) => item?.id)\n .indexOf(valueSelected);\n return pre.slice(0, indexBreadcrumb + 1);\n });\n\n const breadcrumbSelected = keyFolder?.filter(\n (item) => valueSelected === item?.id\n );\n\n onBreadcrumbChange &&\n onBreadcrumbChange(folderId, hierarchyList, breadcrumbSelected?.[0]);\n };\n\n const handleExpand = (folder, folderName) => {\n setCurrentFolderId(folder?.id);\n setSelectedFolder(null);\n handleFetchMoreFolder(folder?.id);\n setKeyFolder((pre) => [...pre, { id: folder?.id, folderName }]);\n\n onExpandFolder && onExpandFolder(folder);\n };\n\n const breadcrumbKey = currentFolderId ? currentFolderId : 'home';\n const breadcrumbData = folderData?.[breadcrumbKey] ?? [];\n\n return (\n \n \n \n \n \n \n \n onDrop && onDrop(dropData, keyFolder[keyFolder.length - 1])\n }\n />\n \n \n );\n});\n\nexport default FolderSelector;\n","import { v4 as uuidv4 } from 'uuid';\n\nimport { IconFolderAsset, NodeTree } from './FolderTree';\n\nimport folderIcon from 'assets/folder/folder.png';\n\nimport { entityTypeIcon } from 'utils/entityTypeIcon';\nimport { sortFolderToTop } from 'pages/folders/shared/utils';\n\nimport { getItemsOfFolder } from 'services/new-folder';\nimport { getFolderShortDetail } from 'services/folder';\n\nexport const filterParams = {\n folder: [\n {\n fieldName: 'type',\n filterType: 'Equal',\n value: 'folder', //\n },\n ],\n all: [],\n};\n\nconst getUuidKey = () => uuidv4();\n\nexport const handleOpenDetailItem = (type, id) => {\n const openInNewTab = (url) => {\n window.open(url).focus();\n };\n\n switch (type.toLowerCase()) {\n case 'folder':\n return openInNewTab(`/folder/${id}`);\n\n case 'product':\n return openInNewTab(`/product/${id}`);\n\n case 'asset':\n return openInNewTab(`/asset/${id}`);\n\n case 'member':\n return openInNewTab(`/company/${id}`);\n\n case 'reporting':\n return openInNewTab(`/reporting/${id}`);\n\n case 'query':\n return openInNewTab(`/execute-query/${id}`);\n\n default:\n return null;\n }\n};\n\nexport const getNodeTreeData = ({ node, folderParam = {}, fileParam = {} }) => {\n if (node.type.toLowerCase() === 'folder') {\n const { renderFolder = () => {} } = folderParam;\n return {\n key: getUuidKey(),\n title: ,\n icon: ,\n data: node,\n selectable: true,\n checkable: false,\n ...renderFolder(node),\n };\n }\n\n const { renderFile = () => {} } = fileParam;\n return {\n key: getUuidKey(),\n title: ,\n icon: entityTypeIcon(node.type.toLowerCase()),\n data: node,\n selectable: true,\n checkable: false,\n isLeaf: true,\n ...renderFile(node),\n };\n};\n\nexport const updateTreeData = (list, key, children) => {\n return list.map((node) => {\n if (node.key === key) {\n return { ...node, children };\n }\n\n if (node.children) {\n return {\n ...node,\n children: updateTreeData(node.children, key, children),\n };\n }\n\n return node;\n });\n};\n\nexport const mappingFolderToTreeData = (folders, folderParam, fileParam) => {\n let treeData = [];\n\n folders.forEach((item) => {\n if (item.type.toLowerCase() === 'folder') {\n let node = getNodeTreeData({ node: item, folderParam, fileParam });\n treeData.push(node);\n } else {\n let node = getNodeTreeData({ node: item, folderParam, fileParam });\n treeData.push(node);\n }\n });\n\n return treeData;\n};\n\nexport const fetchChildNodeFolder = async (params) => {\n const response = await getItemsOfFolder(params);\n if (response?.isSuccess) {\n if (response?.data?.gridData) {\n return response?.data?.gridData;\n }\n }\n return null;\n};\n\nconst getExpandedNodeData = async ({\n folderId,\n folderParam,\n filterType = 'folder',\n}) => {\n const items = await fetchChildNodeFolder({\n folderId,\n pageIndex: 1, // change later\n pageSize: 9999, // change later\n filters: filterParams[filterType],\n sort: [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ], // new first,\n });\n if (items) {\n const sortedItems = items.sort(sortFolderToTop);\n return mappingFolderToTreeData(sortedItems, folderParam);\n }\n\n return [];\n};\n\nexport const generateListChildNode = async ({\n childNode,\n childIds,\n folderParam,\n filterType,\n}) => {\n let result = [];\n\n for (const node of childNode) {\n const { id } = node.data;\n\n if (childIds.includes(parseInt(id))) {\n const respContent = await getExpandedNodeData({\n folderId: id,\n folderParam,\n filterType,\n });\n\n const newNode = {\n ...node,\n children: await generateListChildNode({\n childNode: respContent,\n childIds: childIds.slice(1),\n folderParam,\n filterType,\n }),\n };\n result.push(newNode);\n } else {\n result.push(node);\n }\n }\n\n return result;\n};\n\nexport const buildHierarchyTreeFolder = async ({\n listIds,\n folderParam,\n filterType,\n}) => {\n const [rootFolderId, ...childIds] = listIds;\n\n /* Need to check error in here, sometimes one of two responses is fail.\n Show error and back to grid folder??\n Use Promise.allSettle instead of using Promise.all to don't crash system\n */\n const [rootFolderDetailResp, rootContentFolderResp] = await Promise.all([\n getFolderShortDetail({\n id: rootFolderId,\n IsLoadContent: false,\n }),\n getExpandedNodeData({ folderId: rootFolderId, folderParam, filterType }),\n ]);\n\n const hierarchyNodes = await generateListChildNode({\n childNode: rootContentFolderResp,\n childIds: childIds.map((id) => parseInt(id)),\n folderParam,\n filterType,\n });\n\n let parentNode = {\n ...getNodeTreeData({\n node: { ...rootFolderDetailResp?.data, type: 'folder' }, // folder doesn't have type value !!!\n folderParam,\n }),\n children: hierarchyNodes,\n };\n\n return [parentNode];\n};\n\nexport const getHierarchyExpandedKeys = (children, listIds) => {\n let result = [];\n\n for (const child of children) {\n if (listIds.includes(parseInt(child.data.id))) {\n result.push(child.key);\n }\n if (child.children) {\n result = result.concat(getHierarchyExpandedKeys(child.children, listIds));\n }\n }\n\n return result;\n};\n\nexport const findNodeTreeById = (treeData = [], id) => {\n for (let i = 0; i < treeData.length; i++) {\n if (parseInt(treeData[i]?.data?.id) === parseInt(id)) {\n return treeData[i];\n }\n if (treeData[i]?.children) {\n const result = findNodeTreeById(treeData[i].children, id);\n if (result) {\n return result;\n }\n }\n }\n return null;\n};\n","import React, { useMemo } from 'react';\n\nimport { Input, Form, InputNumber, Select, Checkbox, Tooltip } from 'antd';\n\nimport classnames from 'classnames';\n\nimport './BasicFormItem.less';\n\nconst { TextArea } = Input;\nconst { Option } = Select;\n\nconst BasicFormItem = (props) => {\n const {\n name,\n label,\n rules = [],\n type,\n renderInput,\n selectProps = {\n options: [],\n inputProps: {},\n },\n inputProps = {},\n allowEdit = true,\n layout,\n showTooltip = false,\n ...restProps\n } = props;\n\n const newRuleItems = rules?.map((ruleItem = {}) => {\n let newRuleItem;\n\n const { type, message } = ruleItem;\n\n switch (type) {\n default:\n newRuleItem = ruleItem;\n }\n\n return newRuleItem;\n });\n\n const renderInputComponent = () => {\n if (renderInput) {\n return renderInput({ allowEdit, inputProps, name });\n }\n\n if (type === 'numeric') {\n return ;\n }\n\n if (type === 'textarea') {\n return \n );\n};\n\nTextarea.propTypes = {\n content: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.node,\n PropTypes.object,\n ]),\n minRows: PropTypes.number,\n maxRows: PropTypes.number,\n};\n\nTextarea.defaultProps = {\n minRows: 8,\n maxRows: 8,\n};\n\nexport default Textarea;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Slider from 'react-slick';\nimport 'slick-carousel/slick/slick.css';\nimport 'slick-carousel/slick/slick-theme.css';\nimport './TextSlickSlider.less';\nimport { LeftOutlined, RightOutlined } from '@ant-design/icons';\n\nfunction SampleNextArrow(props) {\n const { className, onClick } = props;\n return (\n
\n \n
\n );\n}\n\nfunction SamplePrevArrow(props) {\n const { className, onClick } = props;\n return (\n
\n \n
\n );\n}\n\nexport default function SlickSlider(props) {\n const settings = {\n className: 'center',\n infinite: true,\n centerPadding: '0',\n slidesToShow: 2,\n speed: 500,\n dots: true,\n nextArrow: ,\n prevArrow: ,\n };\n const { children } = props;\n return (\n
\n {children}\n
\n );\n}\nSlickSlider.propTypes = {\n children: PropTypes.array.isRequired,\n};\n","import React, {\n useState,\n useCallback,\n useImperativeHandle,\n forwardRef,\n} from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Typography, Button, Col, Row } from 'antd';\nimport { EditOutlined } from '@ant-design/icons';\nimport classnames from 'classnames';\nimport { FormCancelButton } from 'common/components';\n\nimport './WithAggridHeaderEdit.less';\n\nconst { Title } = Typography;\n\nconst WithAggridHeaderEdit = (props, ref) => {\n const {\n title,\n children,\n show = false,\n buttons,\n extraButtons,\n allowEdit = true,\n } = props;\n\n const [showEdit, setShowEdit] = useState(show);\n const [isEdit, setIsEdit] = useState(false);\n\n const onMouseEnter = () => {\n !show && setShowEdit(true);\n };\n\n const onMouseLeave = () => {\n !show && setShowEdit(false);\n };\n\n const toggleEditMode = useCallback(() => {\n setIsEdit((prev) => !prev);\n }, []);\n\n useImperativeHandle(ref, () => ({\n changeEditMode: (editMode) => {\n setIsEdit(editMode);\n },\n getEditMode: () => isEdit,\n }));\n\n return (\n
\n \n \n \n {title || 'Unknown'}\n \n \n \n {isEdit && (\n <>\n {buttons?.map((buttonItem, idx) => (\n {buttonItem}\n ))}\n \n )}\n \n {showEdit && !isEdit && allowEdit && (\n }\n onClick={toggleEditMode}\n />\n )}\n {isEdit && (\n \n )}\n \n {extraButtons?.map((buttonItem, idx) => (\n {buttonItem}\n ))}\n \n \n {children && children}\n \n
\n );\n};\n\nWithAggridHeaderEdit.propsTypes = {\n title: PropTypes.string,\n children: PropTypes.object,\n show: PropTypes.bool,\n buttons: PropTypes.arrayOf(PropTypes.object),\n extraButtons: PropTypes.arrayOf(PropTypes.object),\n allowEdit: PropTypes.bool,\n};\n\nexport default forwardRef(WithAggridHeaderEdit);\n","/*\n * Common Messages\n *\n * This contains all the text for the common component.\n */\nimport { defineMessages } from 'react-intl';\n\nexport const scope = 'Taco.common.components.ag-grid';\n\nexport default defineMessages({\n btnAdd: {\n id: `${scope}.components.agGridEditHeader.btn.add`,\n defaultMessage: 'Add',\n },\n btnEdit: {\n id: `${scope}.components.agGridEditHeader.btn.edit`,\n defaultMessage: 'Edit',\n },\n btnCancel: {\n id: `${scope}.components.agGridEditHeader.btn.cancel`,\n defaultMessage: 'Cancel',\n },\n btnDelete: {\n id: `${scope}.components.agGridEditHeader.btn.delete`,\n defaultMessage: 'Delete',\n },\n btnResetPassword: {\n id: `${scope}.components.agGridEditHeader.btn.resetPassword`,\n defaultMessage: ' Reset Password',\n },\n chooseDownloadFileType: {\n id: `${scope}.components.agGridEditHeader.btn.chooseDownloadOptions`,\n defaultMessage: ' Choose file type',\n },\n});\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Menu } from 'antd';\n\nimport { WithLoading } from 'common/components';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/message-ag-grid';\n\nimport './AgGridDownloadOptions.less';\n\nconst AgGridDownloadOptions = (props) => {\n const intl = useIntl();\n const { handleDownload, loading } = props;\n\n return (\n \n {\n //* send file type to parent component\n handleDownload && handleDownload(key);\n }}\n style={{ width: 180 }}\n >\n \n XLSX\n XLS\n CSV\n XML \n \n \n \n );\n};\n\nAgGridDownloadOptions.defaultProps = {\n loading: false,\n};\n\nAgGridDownloadOptions.propType = {\n loading: PropTypes.bool,\n handleDownload: PropTypes.func,\n};\n\nexport default AgGridDownloadOptions;\n","import { defineMessages } from 'react-intl';\n\nexport const scope = 'Taco.logo-assets';\n\nexport default defineMessages({\n okBtn: {\n id: `${scope}.modal.okBtn`,\n defaultMessage: 'Select',\n },\n errorMessage: {\n id: `${scope}.list.errorMessage`,\n defaultMessage: 'Cannot get logo assets.',\n },\n emptyMessage: {\n id: `${scope}.list.emptyMessage`,\n defaultMessage: 'Cannot get logo assets.',\n },\n totalItems: {\n id: `${scope}.list.totalItems`,\n defaultMessage: 'items found',\n },\n});\n","import React, { useState, useEffect } from 'react';\n\nimport { Row, Col, Result, Empty, Pagination, Typography } from 'antd';\nimport { WithLoading, ThumbnailItem } from '../index';\n\nimport { useIntl, FormattedMessage } from 'react-intl';\nimport Messages from 'i18n/messages/logoAsset';\n\nimport './LogoAssetGrid.less';\n\nconst LogoAssetGrid = (props) => {\n const intl = useIntl();\n\n const { visible, getLogoAssetRequest, onSelectLogoAsset, responseParams } =\n props;\n\n //* state\n const [loading, setLoading] = useState(false);\n const [logoAssetList, setLogoAssetList] = useState(false);\n const [error, setError] = useState(false);\n const [selectedLogo, setSelectedLogo] = useState(false);\n const [pageIndex, setPageIndex] = useState(1);\n const [pageSize, setPageSize] = useState(8);\n const [total, setTotal] = useState(0);\n\n //* functions\n const getLogoAssetList = () => {\n setLoading(true);\n\n const params = {\n pageIndex,\n pageSize,\n };\n\n getLogoAssetRequest &&\n getLogoAssetRequest(params)\n .then((response) => {\n let data;\n if (responseParams) {\n data = response[responseParams];\n } else {\n data = response;\n }\n const {\n gridData,\n paging: { totalRecord },\n } = data;\n if (gridData) {\n setLogoAssetList(gridData);\n setTotal(totalRecord);\n } else {\n getLogoAssetErrorHandler();\n }\n })\n .catch(() => {\n getLogoAssetErrorHandler();\n })\n .finally(() => {\n setLoading(false);\n });\n };\n\n const getLogoAssetErrorHandler = () => {\n setError(true);\n };\n\n const selectLogoAssetItem = (item) => {\n if (selectedLogo?.uniqueId !== item?.uniqueId) {\n setSelectedLogo(item);\n } else {\n setSelectedLogo(false);\n }\n };\n\n const resetLogoAssetList = () => {\n setLogoAssetList(false);\n setSelectedLogo(false);\n };\n\n const changePageSizeHandler = (page, pageSize) => {\n setPageIndex(page);\n setPageSize(pageSize);\n };\n\n //* did update\n useEffect(() => {\n visible ? getLogoAssetList() : resetLogoAssetList();\n }, [visible, pageIndex, pageSize]);\n\n useEffect(() => {\n onSelectLogoAsset &&\n onSelectLogoAsset(\n selectedLogo?.uniqueId,\n selectedLogo?.thumbnail300 ||\n selectedLogo?.thumbnail100 ||\n selectedLogo?.thumb100 ||\n selectedLogo?.url ||\n selectedLogo?.fileUrl,\n selectedLogo\n );\n }, [selectedLogo]);\n\n //* render\n const renderLogoAssetList = () => {\n const emptyMessage = intl.formatMessage(Messages.emptyMessage);\n\n if (logoAssetList?.length === 0)\n return ;\n\n return (\n logoAssetList &&\n logoAssetList.map((asset) => {\n const { uniqueId, url } = asset;\n const isSelected = selectedLogo.uniqueId === uniqueId;\n\n return (\n \n \n \n );\n })\n );\n };\n\n const errorMessage = intl.formatMessage(Messages.errorMessage);\n\n const showShowPagination = logoAssetList?.length > 0 && !error;\n\n return (\n \n \n {error ? (\n \n ) : (\n renderLogoAssetList()\n )}\n \n {showShowPagination ? (\n \n \n \n \n {total ? total : ''}  \n \n \n \n \n ) : null}\n \n );\n};\n\nexport default LogoAssetGrid;\n","import React, { useState, useEffect } from 'react';\n\nimport { Tabs } from 'antd';\nimport classnames from 'classnames';\n\nimport StyledModal from '../modal';\nimport UploadFile from '../uploadFile/UploadFile';\nimport LogoAssetGrid from './LogoAssetGrid';\n\nimport { getUploadImageUrl } from 'utils/image';\n\nimport Messages from 'i18n/messages/common';\nimport { useIntl } from 'react-intl';\n\nimport { UPLOAD_MAX_SIZE } from 'static/Constants';\n\nimport './EditLogoModal.less';\n\nconst { TabPane } = Tabs;\n\nconst SUPPORT_LOGO_TYPES = ['jpeg', 'png', 'jpg'];\n\nconst EditLogoModal = (props) => {\n const intl = useIntl();\n\n const {\n title,\n visible,\n setVisible,\n onSubmit,\n logoAssetsUniqueId,\n getLogoAssetsService,\n getLogoAssetResponseParams,\n } = props;\n\n const [file, setFile] = useState(null);\n const [logoAsset, setLogoAsset] = useState(null);\n const [activeTab, setActiveTab] = useState('1');\n\n const [submitDisabled, setSubmitDisabled] = useState(true);\n\n const onChangeTab = (activeKey) => {\n setActiveTab(activeKey);\n };\n\n const onFileChange = (fileResult) => {\n if (!fileResult?.file) return;\n\n setFile(fileResult?.file?.originFileObj);\n };\n\n const onOk = () => {\n if (activeTab === '1' && file) getUploadImageUrl(file, onSubmit);\n if (activeTab === '2' && logoAsset) uploadLogoFromLogoAsset();\n onCancel();\n };\n\n const onCancel = () => {\n setVisible(false);\n setFile(null);\n setLogoAsset(null);\n setSubmitDisabled(true);\n setActiveTab('1');\n };\n\n const onSelectLogoAsset = (selectedLogoId, logoImage, selectedLogo) => {\n const uniqueObject = {};\n uniqueObject[logoAssetsUniqueId] = selectedLogoId;\n uniqueObject.imageSrc = logoImage;\n uniqueObject.selectedLogo = selectedLogo;\n\n setLogoAsset(uniqueObject);\n };\n\n const uploadLogoFromLogoAsset = () => {\n onSubmit(logoAsset);\n };\n\n const checkSubmitDisable = () => {\n if (!visible) return;\n\n if (activeTab === '1' && file) {\n setSubmitDisabled(false);\n return;\n }\n\n if (activeTab === '2' && logoAsset?.selectedLogo) {\n setSubmitDisabled(false);\n return;\n }\n\n setSubmitDisabled(true);\n };\n\n useEffect(() => {\n checkSubmitDisable();\n }, [visible, activeTab, file, logoAsset]);\n\n const okBtnText =\n activeTab === '1'\n ? intl.formatMessage(Messages.useImage)\n : intl.formatMessage(Messages.submit);\n return (\n \n \n \n \n \n {getLogoAssetsService ? (\n \n \n \n ) : null}\n \n \n );\n};\n\nexport default EditLogoModal;\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Button } from 'antd';\nimport { CameraOutlined } from '@ant-design/icons';\nimport { ThumbnailItem } from 'common/components';\nimport EditLogoModal from '../modal-edit-logo/EditLogoModal';\nimport noImage from 'assets/product-no-image.jpg';\n\nimport './ProfileImage.less';\n\nconst ProfileImage = (props) => {\n const {\n src,\n title,\n responsive,\n enableCustom,\n className,\n isEditMode,\n loading,\n uploadBtnProps,\n style,\n isDefaultSrc = false,\n onSubmit,\n getLogoAssetsService,\n logoAssetsUniqueId,\n editLogoTitle,\n getLogoAssetResponseParams,\n } = props;\n\n const [editLogoModalVisible, setEditLogoModalVisible] = useState(false);\n\n const onClickUploadBtn = () => {\n showUploadModal();\n };\n\n const showUploadModal = () => {\n setEditLogoModalVisible(true);\n };\n\n //* render\n const isShowEditButton = isEditMode && !loading;\n const UploadBtn = Button;\n\n return (\n
\n \n {isShowEditButton ? (\n }\n size='small'\n onClick={onClickUploadBtn}\n {...uploadBtnProps}\n />\n ) : null}\n {onSubmit ? (\n \n ) : null}\n
\n );\n};\n\nProfileImage.propsTypes = {\n /**\n * Profile Image Source\n */\n src: PropTypes.string.isRequired,\n /**\n * Profile Image Alt\n */\n alt: PropTypes.string,\n /**\n * Size of Profile Image\n */\n size: PropTypes.number,\n /**\n * Edit mode\n */\n isEditMode: PropTypes.bool,\n /**\n * upload image handler\n */\n onUploadHandler: PropTypes.func,\n /**\n * upload image loading\n */\n loading: PropTypes.bool,\n};\n\nProfileImage.defaultProps = {\n size: 150,\n className: 'profile-image',\n alt: 'Profile Image',\n};\n\nexport default ProfileImage;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Space, Typography } from 'antd';\n\nconst { Text } = Typography;\n\nconst ProfileAddress = (props) => {\n const { address, className, style } = props;\n const clp = 'profile-address';\n const isAddressAvailabel =\n address &&\n typeof address === 'object' &&\n Object.values(address).filter((item) => item != null && item !== undefined)\n .length > 0;\n\n const renderAddresses = (address) => {\n return address ? (\n \n {address}\n \n ) : null;\n };\n\n const addressData = {\n primaryAddressCity: address?.primaryAddressCity,\n primaryAddressMainAddress: address?.primaryAddressMainAddress,\n address2: address?.address2,\n address3: address?.address3,\n primaryAddressState: address?.primaryAddressState,\n primaryAddressZipcode: address?.primaryAddressZipcode,\n primaryAddressCountry: address?.primaryAddressCountry,\n address1: address?.address1,\n city: address?.city,\n country: address?.country,\n state: address?.state,\n zipCode: address?.zipCode,\n };\n\n const mapAddressToAddress4 = () => {\n if (address) {\n const stateAddress =\n addressData?.primaryAddressState || addressData?.state\n ? ', ' + (addressData?.primaryAddressState || addressData?.state)\n : '';\n const countryAddress =\n (addressData?.country || addressData?.primaryAddressCountry) &&\n (addressData?.country || addressData?.primaryAddressCountry) !== 'USA'\n ? ', ' + (addressData?.country || addressData?.primaryAddressCountry)\n : '';\n return `${addressData?.primaryAddressCity || addressData?.city || ''}${\n stateAddress || ''\n }${countryAddress || ''}`;\n }\n };\n\n return (\n <>\n {isAddressAvailabel && (\n \n {renderAddresses(\n addressData.primaryAddressMainAddress || addressData.address1\n )}\n {renderAddresses(addressData.address2)}\n {renderAddresses(addressData.address3)}\n {renderAddresses(mapAddressToAddress4())}\n {renderAddresses(\n addressData.primaryAddressZipcode || addressData.zipCode\n )}\n \n )}\n \n );\n};\n\nProfileAddress.propTypes = {\n className: PropTypes.string,\n address: PropTypes.object,\n style: PropTypes.object,\n};\n\nexport default ProfileAddress;\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\n\nimport {\n ContactsOutlined,\n MailOutlined,\n MessageOutlined,\n} from '@ant-design/icons';\nimport { Space, Modal, Typography } from 'antd';\nimport './ContactActions.less';\n\nconst { Paragraph } = Typography;\nconst ContactActions = (props) => {\n // props\n const { title, alignment, className } = props;\n // state\n const [showContact, setShowContact] = useState(false);\n const [showEmail, setShowEmail] = useState(false);\n const [showMessage, setShowMessage] = useState(false);\n const sendContact = () => {\n setShowContact(true);\n };\n\n const sendEmail = () => {\n setShowEmail(true);\n };\n\n const sendMessage = () => {\n setShowMessage(true);\n };\n\n const handleCancelContact = (e) => {\n setShowContact(false);\n };\n const handleCancelEmail = (e) => {\n setShowEmail(false);\n };\n const handleCancelMessage = (e) => {\n setShowMessage(false);\n };\n\n return (\n \n {title && (\n {title}:\n )}\n \n \n \n \n \n\n \n

contact action

\n \n \n

send mail

\n \n \n

send message

\n \n \n );\n};\n\nContactActions.propTypes = {\n title: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.node,\n PropTypes.object,\n ]),\n alignment: PropTypes.oneOf(['left', 'center', 'right']),\n};\n\nContactActions.defaultProps = {\n alignment: 'center',\n};\nexport default ContactActions;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Row, Col, Typography, Checkbox } from 'antd';\nimport { isObject } from 'lodash';\n\nimport './InfoWithLabel.less';\nconst { Text } = Typography;\n\nconst InfoWithLabel = (props) => {\n const {\n label,\n info,\n className,\n labelColProps,\n infoColProps,\n boldInfo,\n labelAlign = 'left',\n infoTextStyle = {},\n labelTextStyle = {},\n align,\n infoAppend,\n gutter,\n showTooltip,\n editIconRender,\n style,\n log,\n } = props;\n const clp = 'info-with-label';\n const isBoolean = typeof info === 'boolean';\n\n const renderInfo = () => {\n if (info !== null) {\n if (isBoolean) return ;\n\n if (React.isValidElement(info)) return info;\n\n if (!isObject(info)) return info;\n }\n\n return null;\n };\n\n return label ? (\n \n \n \n {label}:\n \n \n \n \n {renderInfo()}\n {infoAppend ? infoAppend : null}\n \n \n {editIconRender ? {editIconRender} : null}\n \n ) : null;\n};\nInfoWithLabel.propTypes = {\n /**\n * className of container\n */\n className: PropTypes.string,\n /**\n * Props of label col - Ant Col Component props\n */\n labelColProps: PropTypes.object,\n /**\n * Props of info col - Ant Col Component props\n */\n infoColProps: PropTypes.object,\n /**\n * Make info text bolder\n */\n boldInfo: PropTypes.bool,\n /**\n * Text alignment of label\n */\n labelAlign: PropTypes.oneOf(['center', 'left', 'right']),\n /**\n * Text alignment of label\n */\n infoComponent: PropTypes.func,\n};\nexport default InfoWithLabel;\n","import React, { useState } from 'react';\nimport { Input, Row, Typography } from 'antd';\nimport PropTypes from 'prop-types';\n\nimport './TextAreaGrid.less';\nconst { TextArea } = Input;\nconst { Text } = Typography;\n\nconst TextAreaGrid = (props) => {\n const [isMouseInside, setMouseInside] = useState(false);\n const { title, content, minRows, maxRows, underlineTitle } = props;\n\n return (\n setMouseInside(true)}\n onMouseLeave={() => setMouseInside(false)}\n style={{ width: '100%' }}\n >\n \n {title}\n \n \n \n );\n};\n\nTextAreaGrid.propTypes = {\n title: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.node,\n PropTypes.object,\n ]),\n content: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.node,\n PropTypes.object,\n ]),\n minRows: PropTypes.number,\n maxRows: PropTypes.number,\n underlineTitle: PropTypes.bool,\n};\n\nTextAreaGrid.defaultProps = {\n minRows: 4,\n maxRows: 4,\n underlineTitle: false,\n};\n\nexport default TextAreaGrid;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Tabs } from 'antd';\nimport classnames from 'classnames';\n\nimport './TabLayout.less';\n\nconst { TabPane } = Tabs;\n\nconst TabLayout = (props) => {\n const {\n options,\n defaultActiveTab,\n className,\n onChangeTab,\n containerHeight,\n onTabClick,\n activeKey,\n } = props;\n\n return (\n \n {options &&\n !!options.length &&\n options?.map((item) => {\n const { title, key, module, disabled = false } = item;\n\n return (\n \n {module}\n \n );\n })}\n \n );\n};\n\nTabLayout.propTypes = {\n /**\n * className of wrapper\n */\n className: PropTypes.string,\n /**\n * Tab item option array\n */\n option: PropTypes.arrayOf(\n PropTypes.shape({\n item: PropTypes.string,\n module: PropTypes.func,\n })\n ),\n /**\n * Function to set active tab\n */\n setTabKey: PropTypes.func,\n};\nTabLayout.defaultProps = {\n className: '',\n};\nexport default TabLayout;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Badge } from 'antd';\nimport './Action.less';\n\nconst Action = (props) => {\n const { count, offset, icon, iconStyle, onClick } = props;\n const Icon = icon;\n return (\n \n \n \n );\n};\n\nAction.propTypes = {\n count: PropTypes.number,\n offset: PropTypes.array,\n icon: PropTypes.any,\n};\n\nexport default Action;\n","import React from 'react';\nimport Action from './Action';\nimport { MessageOutlined } from '@ant-design/icons';\n\nconst Chat = (props) => {\n const { count, offset, iconStyle, onClick } = props;\n return (\n \n );\n};\n\nexport default Chat;\n","import React, { useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport Action from './Action';\nimport {\n List,\n Popover,\n Button,\n notification,\n Spin,\n Row,\n Col,\n Typography,\n Divider,\n} from 'antd';\nimport { BellOutlined } from '@ant-design/icons';\nimport { forwardTo } from 'utils/common/route';\nimport classnames from 'classnames';\n// import MeetingNotification from './MeetingNotification';\nimport gridViewSelectors from 'common/components/grid-view/controllers/selectors';\nimport * as workflowActions from 'pages/workflow/controllers/actions';\nimport * as api from 'config/axios';\n\n// import QaSpecWorkflowTodoList from './components/QaSpecWorkflowTodoList';\n\n// import { useGetQaSpecTodoList } from 'pages/qa-spec-workflow/hook';\n// import { updateSearchText } from 'pages/home/utils';\n// import { useCheckPermissions } from 'hooks';\n\n// import { PERMISSION_MANAGE_QA_SPEC_WORKFLOW } from 'static/Permission';\nimport {\n TO_DO_DISPLAY_BELL_COLUMN,\n TO_DO_NOT_DISPLAY_BELL_COLUMN,\n // SEE_MORE_DISPLAY_BELL_COLUMN,\n // SEE_MORE_NOT_DISPLAY_BELL_COLUMN,\n} from './constants';\n\nimport './Task.less';\n\nconst Task = (props) => {\n const {\n count,\n offset,\n iconStyle,\n workflowsNotification,\n updateTodoList,\n awaitingList,\n updateAwaitingList,\n isDisplayBell,\n } = props;\n const [loading, setLoading] = useState(false);\n const [visible, setVisible] = useState(false);\n const { Title } = Typography;\n\n const dispatch = useDispatch();\n\n const visibleContentPane = useSelector(gridViewSelectors.makeSelectVisible());\n const pathname = window.location.pathname;\n\n // const hasPermissionManageQaSpecWorkflow = useCheckPermissions(\n // PERMISSION_MANAGE_QA_SPEC_WORKFLOW\n // );\n\n // const { qaSpecWorkflowTodoList } = useGetQaSpecTodoList(\n // hasPermissionManageQaSpecWorkflow\n // );\n\n const updateIsAcceptStepGrid = () => {\n if (visibleContentPane && pathname === '/workflows') {\n dispatch(workflowActions.updateAcceptStepGrid(true));\n }\n };\n\n const updateIsApproveStepGrid = () => {\n if (visibleContentPane && pathname === '/workflows') {\n dispatch(workflowActions.updateApproveStepGrid(true));\n }\n };\n\n const onClickSeemore = () => {\n forwardTo('/workflows');\n setVisible(false);\n };\n\n const onClickViewItem = (item) => {\n forwardTo(\n `/workflow?workflowImplId=${item?.workflowImplementationId}&stepImplId=${item?.workflowImplementationStepId}`\n );\n setVisible(false);\n };\n\n const onRejectTodo = (event, id) => {\n setLoading(true);\n event.stopPropagation();\n const params = {\n id: id,\n isAccepted: false,\n };\n api\n .sendPost('/api/workflow/accept-or-reject-todo-list', params)\n .then((response) => {\n if (response?.isSuccess) {\n notification.success({ message: 'Reject Todo list success' });\n updateTodoList();\n updateIsAcceptStepGrid();\n } else {\n notification.error({ message: response?.message });\n }\n })\n .catch((error) => {})\n .finally(() => {\n setLoading(false);\n });\n };\n\n const onAcceptTodo = (event, id) => {\n setLoading(true);\n event.stopPropagation();\n const params = {\n id: id,\n isAccepted: true,\n };\n api\n .sendPost('/api/workflow/accept-or-reject-todo-list', params)\n .then((response) => {\n if (response.isSuccess) {\n notification.success({ message: 'Accept Todo list success' });\n updateTodoList();\n updateIsAcceptStepGrid();\n } else {\n notification.error({ message: response?.message });\n }\n })\n .catch((error) => {})\n .finally(() => {\n setLoading(false);\n });\n };\n\n const onRejectAwaiting = (event, id) => {\n setLoading(true);\n event.stopPropagation();\n const params = {\n wfImpStepId: id,\n isApprove: false,\n };\n api\n .sendPost('/api/workflow/accept-waiting-for-approve', params)\n .then((response) => {\n if (response?.isSuccess) {\n notification.success({ message: 'Awaiting workflow is rejected' });\n updateAwaitingList();\n updateIsApproveStepGrid();\n } else {\n notification.error({ message: response?.message });\n }\n })\n .catch((error) => {})\n .finally(() => {\n setLoading(false);\n });\n };\n\n const onAcceptAwaiting = (event, id) => {\n setLoading(true);\n event.stopPropagation();\n const params = {\n wfImpStepId: id,\n isApprove: true,\n };\n api\n .sendPost('/api/workflow/accept-waiting-for-approve', params)\n .then((response) => {\n if (response.isSuccess) {\n notification.success({ message: 'Awaiting workflow is accepted.' });\n updateAwaitingList();\n updateIsApproveStepGrid();\n } else {\n notification.error({ message: response?.message });\n }\n })\n .catch((error) => {})\n .finally(() => {\n setLoading(false);\n });\n };\n // const showMoreQaSpecWorkflowGrid = () => {\n // const qaSpecPath = '/qa-spec-workflows';\n // forwardTo(qaSpecPath);\n // setVisible(false);\n // updateSearchText(dispatch, '', qaSpecPath);\n // };\n\n const workflowList = () => {\n return (\n \n \n {isDisplayBell && (\n \n \n Awaiting List\n \n \n (\n \n {\n onAcceptAwaiting(event, item?.id);\n }}\n style={{ borderRadius: '4px' }}\n type='primary'\n className='header-task__popover-item--accept-button'\n >\n Accept\n \n {\n onRejectAwaiting(event, item?.id);\n }}\n danger\n >\n Reject\n \n \n }\n >\n \n \n )}\n />\n \n )}\n\n \n \n To do List\n \n \n (\n \n {\n onClickViewItem(item);\n }}\n type='primary'\n className='header-task__popover-item--view-button'\n >\n View\n \n \n ) : (\n
\n {\n onAcceptTodo(event, item?.id);\n }}\n style={{ borderRadius: '4px' }}\n type='primary'\n className='header-task__popover-item--accept-button'\n >\n Accept\n \n {\n onRejectTodo(event, item?.id);\n }}\n danger\n >\n Reject\n \n
\n )\n }\n >\n \n \n {item?.status}\n \n }\n />\n \n )}\n />\n \n {/* \n \n */}\n
\n \n \n onClickSeemore()}\n >\n
\n See More\n
\n \n \n\n <>\n {/* \n \n
\n See More\n
\n \n */}\n \n
\n
\n );\n };\n\n const handleVisibleChange = (visible) => {\n setVisible(visible);\n };\n\n const renderTotalCount = () => {\n // const workflowCount = qaSpecWorkflowTodoList?.length ?? 0;\n // return parseInt(count) + parseInt(workflowCount);\n return parseInt(count);\n };\n\n const totalCount = renderTotalCount();\n\n return (\n
\n \n setVisible(true)}\n count={totalCount}\n offset={offset}\n icon={BellOutlined}\n iconStyle={iconStyle}\n />\n \n
\n );\n};\n\nexport default Task;\n","export const TO_DO_DISPLAY_BELL_COLUMN = 12;\nexport const TO_DO_NOT_DISPLAY_BELL_COLUMN = 24;\nexport const SEE_MORE_DISPLAY_BELL_COLUMN = 15;\nexport const SEE_MORE_NOT_DISPLAY_BELL_COLUMN = 12;\n","import React from 'react';\nimport Action from './Action';\nimport { MailOutlined } from '@ant-design/icons';\n\nconst Email = (props) => {\n const { count, offset, iconStyle, onClick } = props;\n return (\n \n );\n};\n\nexport default Email;\n","import React, { useState, useEffect, useCallback } from 'react';\nimport PropTypes from 'prop-types';\nimport Cropper from 'react-cropper';\nimport 'cropperjs/dist/cropper.css';\nimport './CropImage.less';\n\nexport const CropImage = (props) => {\n const {\n imgSrc,\n getRealTimeCropper,\n aspectRatio,\n wrapperStyle,\n cropperHeight,\n refCropper,\n ...restProps\n } = props;\n\n const [cropper, setCropper] = useState();\n\n const getCropDataCallback = useCallback(() => {\n if (!refCropper.current) return;\n\n const canvasData = refCropper.current.cropper.getCroppedCanvas();\n\n if (canvasData && getRealTimeCropper) {\n getRealTimeCropper(\n canvasData.toDataURL(),\n refCropper.current.cropper.getCropBoxData()\n );\n }\n }, []);\n\n const onCrop = (e) => {\n getCropDataCallback();\n };\n\n const onReady = (e) => {\n getCropDataCallback();\n };\n\n useEffect(() => {\n if (cropper) {\n getCropDataCallback();\n }\n }, [cropper, getCropDataCallback]);\n\n return (\n
\n {\n setCropper(instance);\n }}\n cropend={onCrop}\n ref={refCropper}\n ready={onReady}\n {...restProps}\n />\n
\n );\n};\n\nCropper.propTypes = {\n imgSrc: PropTypes.string,\n getCropperInstance: PropTypes.func,\n getRealTimeCropper: PropTypes.func,\n aspectRatio: PropTypes.number,\n};\n\nexport default CropImage;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Space, Typography } from 'antd';\nimport './HistorySection.less';\nconst { Text } = Typography;\n\nconst HistorySection = (props) => {\n const { title, children, className } = props;\n return (\n \n {title && (\n \n {title}\n \n )}\n {children}\n \n );\n};\nHistorySection.propTypes = {\n /**\n * className of section\n */\n className: PropTypes.string,\n /**\n * className prefix/Block\n */\n clp: PropTypes.string,\n /**\n * Section Title\n */\n title: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n};\nexport default HistorySection;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Table } from 'antd';\nimport {\n ArrowDownOutlined,\n ArrowUpOutlined,\n PhoneOutlined,\n ContactsOutlined,\n MailOutlined,\n MessageOutlined,\n} from '@ant-design/icons';\n\nimport { concat, pick, get } from 'lodash';\n\nimport './ProfileContactHistory.less';\n\nconst ProfileContactHistory = (props) => {\n const { data, dataField, dataKey, typeField, arrowField, loading } = props;\n\n const iconSet = {\n Email: MailOutlined,\n Phone: PhoneOutlined,\n Message: MessageOutlined,\n Contact: ContactsOutlined,\n };\n\n // generate more columns\n const generateColumns = () => {\n return dataField && !!dataField.length\n ? dataField.map((field) => {\n const { key, options } = field;\n return {\n title: key,\n dataIndex: key,\n key: key,\n ...options,\n };\n })\n : [];\n };\n\n // generate data source from dataField, typeField and arrowField\n const generateDataSource = () => {\n const dataFieldKey =\n dataField &&\n !!dataField.length &&\n dataField.map((field) => {\n return field.key;\n });\n return data && !!data.length && true\n ? data.map((item) => {\n const modifiedItem = pick(item, dataFieldKey);\n modifiedItem.key = item[dataKey];\n modifiedItem.type = item[typeField];\n modifiedItem.arrow = item[arrowField];\n return modifiedItem;\n })\n : [];\n };\n\n // define the two first columns of contact history table\n const initColumns = [\n // the first column is in-out arrow icon\n {\n title: 'arrow',\n dataIndex: 'arrow',\n key: 'arrow',\n width: 30,\n render: (text) => {\n return text ? (\n \n ) : (\n \n );\n },\n },\n // the second column is type icon\n {\n title: 'Type',\n dataIndex: 'type',\n key: 'type',\n width: 30,\n render: (text) => {\n const TypeIcon = get(iconSet, text, ContactsOutlined);\n return ;\n },\n },\n ];\n // define more column\n const dataColumns = generateColumns();\n // merge initColumns with more columns\n const columns = concat(initColumns, dataColumns);\n // define data source\n const dataSource = generateDataSource();\n\n return (\n \n );\n};\n\nProfileContactHistory.propTypes = {\n /**\n * Contact history data\n */\n data: PropTypes.arrayOf(PropTypes.object),\n /**\n * Array of fields will show in table\n */\n dataField: PropTypes.arrayOf(\n PropTypes.shape({\n /**\n * key name of field\n */\n key: PropTypes.string,\n /**\n * Column props of Ant Table use for this field\n */\n options: PropTypes.object,\n })\n ),\n /**\n * Key for each item of dataSource of Ant Table\n */\n dataKey: PropTypes.string,\n /**\n * Key for selecting value of Type Icon column\n */\n typeField: PropTypes.string,\n /**\n * Key for selecting value of Arrow Icon column\n */\n arrowField: PropTypes.string,\n};\n\nexport default ProfileContactHistory;\n","import React, { useState } from 'react';\nimport { Tooltip, Typography } from 'antd';\n\nconst { Paragraph } = Typography;\n\nconst TooltipParagraph = ({ children, ellipsis, ...props }) => {\n const [truncated, setTruncated] = useState(false);\n\n return (\n \n \n <>{children}\n \n \n );\n};\n\nexport default TooltipParagraph;\n","import React from 'react';\n\nimport { Space, Typography } from 'antd';\n\nconst { Text } = Typography;\n\nconst MemberGlnList = (props) => {\n const { glns, color } = props;\n\n return (\n \n {glns?.length\n ? glns.map((gln) => {\n return {gln};\n })\n : null}\n \n );\n};\n\nexport default MemberGlnList;\n","import React from 'react';\n\nimport { Tooltip, Typography } from 'antd';\n\nimport MemberGlnList from '../member-grid/MemberGlnList';\n\nconst { Text } = Typography;\n\nconst GlnTooltip = (props) => {\n const { glns } = props;\n\n const renderTitle = () => {\n return ;\n };\n\n const renderGlnText = () => {\n return glns?.length ? (\n \n {glns.join(', ')}\n \n ) : null;\n };\n\n return {renderGlnText()};\n};\n\nexport default GlnTooltip;\n","import http from 'assets/download-method/http.png';\nimport email from 'assets/download-method/email.png';\nimport interop from 'assets/download-method/interop.png';\n\n// Array of types digital asset map with images\nexport const DownloadMethodImage = [\n { fileType: 'direct', fileImg: http },\n { fileType: 'email', fileImg: email },\n { fileType: 'ftp', fileImg: interop },\n];\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { DigitalAssetTypeImage } from 'static/FileType';\nimport { DownloadMethodImage } from 'static/DownloadMethod';\nimport { LoadingOutlined } from '@ant-design/icons';\nimport unknownType from 'assets/file-formats/unknown.jpg';\n\nimport './TypePicker.less';\n\nconst TypePicker = (props) => {\n const { group, type, loading } = props;\n let optionList;\n if (group === 'file-type') {\n optionList = DigitalAssetTypeImage;\n } else if (group === 'download-method') {\n optionList = DownloadMethodImage;\n } else optionList = [];\n const image =\n optionList.filter((image) => image.fileType === type?.toLowerCase())[0]\n ?.fileImg || unknownType;\n\n return (\n <>\n {loading ? (\n \n ) : (\n {type}\n )}\n \n );\n};\n\nTypePicker.propsTypes = {\n group: PropTypes.string,\n type: PropTypes.string,\n loading: PropTypes.bool,\n};\n\nexport default TypePicker;\n","// Service Type List\nimport dropbox from 'assets/system/dropbox.png';\nimport ftp from 'assets/system/ftp.png';\nimport instacart from 'assets/system/instacart.png';\nimport salsify from 'assets/system/salsify.png';\nimport sftp from 'assets/system/sftp.png';\nimport sharepoint from 'assets/system/sharepoint.jpg';\nimport sagetree from 'assets/system/sagetree.png';\nimport gs1 from 'assets/gs1.png';\n\nconst serviceTypeList = [\n {\n value: 'dropbox',\n icon: dropbox,\n },\n {\n value: 'ftp',\n icon: ftp,\n },\n {\n value: 'instacart',\n icon: instacart,\n },\n {\n value: 'salsify',\n icon: salsify,\n },\n {\n value: 'sftp',\n icon: sftp,\n },\n {\n value: 'sharepoint',\n icon: sharepoint,\n },\n {\n value: 'sagetree',\n icon: sagetree,\n },\n {\n value: 'gs1',\n icon: gs1,\n },\n];\n\nexport default serviceTypeList;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Typography } from 'antd';\nimport serviceTypeList from './ServiceTypeMapping';\nimport classNames from 'classnames';\nimport { Images } from 'config/assets';\n\nimport './ServiceType.less';\n\nconst { Text } = Typography;\n\nconst ServiceType = (props) => {\n const { className, type, hideTitle } = props;\n const service = serviceTypeList.filter(\n (icon) => icon.value === type?.toLowerCase()\n )[0]?.icon;\n return (\n
\n \n {!hideTitle && {type || 'UNKNOWN SERVICE'}}\n
\n );\n};\n\nServiceType.propsTypes = {\n type: PropTypes.string,\n className: PropTypes.string,\n hideTitle: PropTypes.bool,\n};\n\nexport default ServiceType;\n","import React from 'react';\nimport PropTypes, { oneOfType } from 'prop-types';\nimport { Row, Col } from 'antd';\nimport { injectIntl } from 'react-intl';\nimport classnames from 'classnames';\nimport './LabelValueWrapper.less';\n\nconst LabelValueWrapper = (props) => {\n const { object, parentScoop, colspan, labelSuffix, intl, valueStyle } = props;\n let initialCol = colspan || 8;\n\n const modifyData = (data) => {\n if (typeof data === 'boolean') {\n switch (data) {\n case true:\n return 'Yes';\n case false:\n return 'No';\n }\n } else return data;\n };\n\n return (\n <>\n {object &&\n Object.entries(object).map(([key, value]) => {\n return (\n \n \n {intl.formatMessage({\n id: `Taco.${parentScoop}.${key}`,\n })}\n {labelSuffix}\n \n \n {modifyData(value)}\n \n \n );\n })}\n \n );\n};\n\nLabelValueWrapper.propsTypes = {\n object: oneOfType([PropTypes.array, PropTypes.object]),\n parentScoop: PropTypes.string,\n colspan: PropTypes.number,\n labelSuffix: PropTypes.string,\n};\n\nexport default injectIntl(LabelValueWrapper);\n","import React from 'react';\nimport PropTypes, { oneOfType } from 'prop-types';\nimport { Modal } from 'antd';\nimport './IframePreview.less';\n\nconst IframePreview = (props) => {\n const { title, height, width, url, visible, onClose, ...otherProps } = props;\n\n const iframe = ``;\n const Iframe = ({ iframe }) => {\n return (\n \n );\n };\n\n return (\n onClose()}\n width='100%'\n bodyStyle={{\n height: 'calc(100vh - 36px)',\n display: ' flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n footer={null}\n {...otherProps}\n >\n `;\n return (\n \n );\n };\n\n const isRenderUnsupportedFileViewer = () => {\n return (\n UNPREVIEWABLE_FILE_TYPES.indexOf(fileType) > -1 || !link || isEmptyFile\n );\n };\n\n return (\n <>\n {fileType && fileType?.toLowerCase() === 'iframe' ? (\n `;\n return (\n \n );\n };\n\n return (\n
\n {isCreateAsset && (\n \n )}\n \n \n \n onInputChange(form.getFieldValue('iFrameLink'))}\n />\n \n \n \n \n \n {link ? (\n iFramePreviewRender(link)\n ) : loading ? (\n \n ) : (\n \n )}\n \n \n \n \n \n onPreview()}\n // size='large'\n disabled={btnDisabled}\n >\n Preview\n \n \n Submit\n \n \n \n \n \n
\n );\n};\n\nIframeAsset.propTypes = {\n onSuccess: PropTypes.func,\n assetData: oneOfType([PropTypes.array, PropTypes.object]),\n setUploadType: PropTypes.func,\n};\n\nexport default React.memo(IframeAsset);\n","import React from 'react';\nimport { Image, Typography, Tree, Button, Tag } from 'antd';\n\nimport { CloseOutlined } from '@ant-design/icons';\n\nimport folderIcon from 'assets/folder/folder.png';\nimport fileIcon from 'assets/file-formats/file-icon.webp';\n\nimport '../dropbox-upload/AssetDropboxUpload.less';\n\nexport const TitleFolderAsset = ({ title, style, ...rest }) => {\n return (\n \n {title}\n \n );\n};\n\nexport const TitleFileAsset = ({ title, style, ...rest }) => {\n return (\n \n {title}\n \n );\n};\n\nexport const IconAsset = ({ src, preview, ...rest }) => {\n return ;\n};\n\nexport const IconFileAsset = (props) => {\n return (\n \n );\n};\n\nexport const IconFolderAsset = (props) => {\n return ;\n};\n\nconst { DirectoryTree } = Tree;\n\nexport const TreeFiles = (props) => {\n return ;\n};\n\nexport const SelectedFile = ({ name, itemId, type, onDeleteItem }) => {\n return (\n \n ) : (\n \n )\n }\n color='success'\n className='dropbox-asset__result-tag'\n >\n \n {name}\n \n }\n style={{\n marginLeft: 4,\n border: 'none',\n }}\n onClick={() => onDeleteItem(itemId)}\n />\n \n );\n};\n","import React from 'react';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport {\n TitleFolderAsset,\n IconFolderAsset,\n TitleFileAsset,\n IconFileAsset,\n} from '../shared/components';\n\nimport { getInteropListItems } from 'services/interoperability';\n\nimport { ASSET_VIRTUAL_SCROLL_HEIGHT } from 'static/Constants';\nimport { getFolderShortDetail } from 'services/folder';\nimport { formatRangeDateTime } from 'utils/formatDate';\n\nconst getUuidKey = () => uuidv4();\n\nconst getNodeTreeData = (interop, multipleImport) => {\n if (interop.type === 'folder') {\n return {\n key: getUuidKey(),\n title: ,\n icon: ,\n data: interop,\n selectable: false,\n checkable: multipleImport ? true : false,\n };\n }\n return {\n key: getUuidKey(),\n title: ,\n icon: ,\n data: interop,\n selectable: multipleImport ? false : true,\n isLeaf: true,\n };\n};\n\n/**\n *\n * @param {*} list\n * @param {*} key\n * @param {*} children\n * @param {*} folderId - //! folder id can be used to check instead of key\n * @returns\n */\nexport const updateTreeData = (list, key, children, folderId) => {\n return list.map((node) => {\n const { data, key: nodeKey } = node;\n const { id } = data || {};\n\n if (id === folderId && folderId) {\n return { ...node, children };\n }\n\n if (nodeKey === key) {\n return { ...node, children };\n }\n\n if (node.children) {\n return {\n ...node,\n children: updateTreeData(node.children, key, children, folderId),\n };\n }\n\n return node;\n });\n};\n\nexport const mappingInteropItemsToTreeData = (\n interopItems = [],\n multipleImport = false\n) => {\n let treeData = [];\n\n if (interopItems) {\n interopItems.forEach((interop) => {\n if (interop.type === 'folder') {\n let node = getNodeTreeData(interop, multipleImport);\n treeData.push(node);\n } else {\n let node = getNodeTreeData(interop, multipleImport);\n treeData.push(node);\n }\n });\n }\n\n return treeData;\n};\n\nexport const getExpandedData = async (params) => {\n const response = await getInteropListItems(params);\n if (response?.isSuccess) {\n if (response?.data?.interopItems) {\n return response?.data?.interopItems;\n }\n }\n return null;\n};\n\nexport const getFormDataParams = (params = {}) => {\n let formData = new FormData();\n\n Object.entries(params).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((item) => {\n formData.append(key, item);\n });\n } else {\n formData.append(key, value);\n }\n });\n\n return formData;\n};\n\nexport const filterFoldersAndFilesInSelectedItems = (selectedItems = []) => {\n let folders = [];\n let files = [];\n\n selectedItems.forEach((item) => {\n const { data } = item;\n\n if (data.type === 'file') {\n files.push(item);\n } else if (data.type === 'folder') {\n if (Array.isArray(item.children) && item.children.length > 0) {\n folders.push(item);\n filterFoldersAndFilesInSelectedItems(item.children);\n } else {\n folders.push(item);\n }\n }\n });\n\n return {\n folders,\n files,\n };\n};\n\nconst findFileExistInAnyFolders = (folders, file) => {\n return folders.some((item) => {\n if (item.key === file.key) {\n return true;\n } else if (item.children) {\n return findFileExistInAnyFolders(item.children, file);\n }\n return false;\n });\n};\n\n// A file will be sent to the server when folder that contains the file does not check\nexport const getFilesPath = (folders, files) => {\n let result = [];\n\n files.forEach((file) => {\n const isExist = findFileExistInAnyFolders(folders, file);\n\n if (!isExist) {\n result.push(file.data.path);\n }\n });\n\n return result;\n};\n\nconst findFolderExistInAnyFolders = (folders, findFolder) => {\n return folders.some((folder) => {\n if (folder.key === findFolder.key) {\n return true;\n } else if (folder.children) {\n return findFolderExistInAnyFolders(folder.children, findFolder);\n }\n return false;\n });\n};\n\n// A folder will be sent to the server when folder that contains the file does not check\nexport const getFoldersPath = (folders) => {\n let result = [];\n\n folders.forEach((folder) => {\n const filteredFolders = folders.filter((f) => f.key !== folder.key);\n\n const isExist = findFolderExistInAnyFolders(filteredFolders, folder);\n\n if (!isExist) {\n result.push(folder.data.path);\n }\n });\n\n return result;\n};\n\nlet foundNode = null;\nexport const findNodeTree = (treeData, itemId) => {\n for (let index = 0; index < treeData.length; index++) {\n const node = treeData[index];\n if (node.data.itemId === itemId) {\n foundNode = node;\n break;\n }\n\n if (node?.children) {\n findNodeTree(node.children, itemId);\n }\n }\n return foundNode;\n};\n\nexport const getChildNodesInFolder = (treeData) => {\n let children = [];\n const flattenMembers = treeData.map((m) => {\n if (m.children && m.children.length) {\n children = [...children, ...m.children];\n }\n return m;\n });\n\n return flattenMembers.concat(\n children.length ? getChildNodesInFolder(children) : children\n );\n};\n\nexport const filterArrayInAnotherArray = (arr1, arr2) => {\n return arr1.filter((item) => !arr2.includes(item));\n};\n\nexport const findAncestorsOfChildNode = (treeData, childNode) => {\n if (Array.isArray(treeData) && treeData.length > 0) {\n for (let i = 0; i < treeData.length; i++) {\n if (treeData[i].key === childNode.key) return [];\n\n let result = findAncestorsOfChildNode(treeData[i].children, childNode);\n if (result !== null) {\n result = result.concat(treeData[i]);\n return result;\n }\n }\n }\n return null;\n};\n\nexport const filterArrayObjectInAnotherArrayObject = (\n array1 = [],\n array2 = []\n) => {\n let result = [];\n\n array1.forEach((item1) => {\n const foundItem = array2.find((item2) => item1.key === item2.key);\n\n if (!foundItem) {\n result.push(item1);\n }\n });\n\n return result;\n};\n\nexport const getOnlySelectedParentItems = (treeData, items, keys) => {\n let result = [];\n items.forEach((item) => {\n const ancestorNodes = findAncestorsOfChildNode(treeData, item);\n const ancestorKeys = ancestorNodes.map((node) => node.key);\n const isParentSelected = findSelectedKeyInAnotherKeys(keys, ancestorKeys);\n\n if (!isParentSelected) {\n result.push(item);\n }\n });\n return result;\n};\n\nexport const findSelectedKeyInAnotherKeys = (keys, selectedKeys) => {\n return selectedKeys.find((key) => {\n return keys.includes(key);\n });\n};\n\nexport const getOnlyFilesInTree = (treeData = []) => {\n let result = [];\n\n treeData.forEach((treeNode) => {\n // file\n if (treeNode.isLeaf) {\n result.push(treeNode);\n } else {\n if (treeNode?.children?.length > 0) {\n const allChild = getChildNodesInFolder(treeNode.children);\n const files = allChild.filter((child) => child.data.type === 'file');\n result = result.concat(files);\n }\n }\n });\n\n return result;\n};\n\nexport const findListNodeInTree = (treeData, folders) => {\n let result = [];\n\n folders.forEach((folder) => {\n const node = findNodeTree(treeData, folder.data.itemId);\n if (node) {\n result.push(node);\n }\n });\n\n return result;\n};\n\nexport const getAllFilesInFolders = (folders = []) => {\n let result = [];\n\n folders.forEach((folder) => {\n if (folder?.children?.length > 0) {\n const nodes = getChildNodesInFolder(folder.children);\n result = result.concat(nodes);\n }\n });\n\n return result.filter((item) => item.data.type === 'file');\n};\n\nexport const getFormValues = (form) => {\n const {\n effectivePeriod,\n defaultStatus,\n isCreateThumbs,\n autoApplyOrReplaceOnProducts,\n } = form.getFieldsValue();\n\n const startTime = formatRangeDateTime(effectivePeriod?.[0]);\n const endTime = formatRangeDateTime(effectivePeriod?.[1]);\n\n const formValues = {\n EffectedDate: startTime ? startTime.toISOString() : null,\n ExpirationDate: endTime ? endTime.toISOString() : null,\n defaultStatus,\n isCreateThumbs,\n autoApplyOrReplaceOnProducts,\n };\n\n return formValues;\n};\n\nexport const getVirtualScrollHeight = (largeScreen, multipleImport) => {\n return largeScreen\n ? multipleImport\n ? ASSET_VIRTUAL_SCROLL_HEIGHT.multiImport\n : ASSET_VIRTUAL_SCROLL_HEIGHT.singleImport\n : ASSET_VIRTUAL_SCROLL_HEIGHT.xlHeight;\n};\n\nconst getExpandedNodeData = async ({\n pathInfo,\n id,\n storageServiceType,\n multipleImport,\n}) => {\n const items = await getExpandedData({ id, pathInfo, storageServiceType });\n if (items) {\n return mappingInteropItemsToTreeData(items, multipleImport);\n }\n\n return [];\n};\n\nconst getNodesAfterExpandingAll = async ({\n folderNodes,\n id,\n storageServiceType,\n multipleImport,\n}) => {\n let result = [];\n\n for (const node of folderNodes) {\n if (node.data.type === 'folder') {\n const expandedNodes = await getExpandedNodeData({\n pathInfo: node.data.path,\n id,\n storageServiceType,\n multipleImport,\n });\n\n result.push({\n ...node,\n children: await getNodesAfterExpandingAll({\n folderNodes: expandedNodes,\n id,\n storageServiceType,\n multipleImport,\n }),\n selectable: false,\n checkable: multipleImport ? true : false,\n });\n } else {\n result.push(node);\n }\n }\n\n return result;\n};\n\nexport const getTreeDataAfterExpandingAll = async ({\n treeData,\n id,\n storageServiceType,\n multipleImport,\n}) => {\n const folderNodes = treeData.filter(\n (folder) => folder.data.type === 'folder'\n );\n const fileNodes = treeData.filter((folder) => folder.data.type === 'file');\n\n const expandedNodes = await getNodesAfterExpandingAll({\n folderNodes,\n id,\n storageServiceType,\n multipleImport,\n });\n\n return expandedNodes.concat(fileNodes);\n};\n\nexport const getAllFoldersInTreeData = (treeData) => {\n let childNodes = [];\n const folders = treeData.filter((folder) => folder.data.type === 'folder');\n\n folders.forEach((folder) => {\n if (folder?.children?.length > 0) {\n const nodes = getChildNodesInFolder(folder.children);\n childNodes = childNodes.concat(nodes);\n }\n });\n\n const childFolders = childNodes.filter((item) => item.data.type === 'folder');\n\n return folders.concat(childFolders);\n};\n\nexport const getAllExpandedKeys = (treeData) => {\n return getAllFoldersInTreeData(treeData).map((folder) => folder.key);\n};\n\nexport const getFilesAfterExpandingAll = async ({\n folderNodes,\n id,\n storageServiceType,\n multipleImport,\n}) => {\n const expandedNodes = await getNodesAfterExpandingAll({\n folderNodes,\n id,\n storageServiceType,\n multipleImport,\n });\n\n return getAllFilesInFolders(expandedNodes);\n};\n\nexport const generateDestinationFolderPath = async (fullPathIds) => {\n let result = '';\n\n const promises = fullPathIds.map((id) =>\n getFolderShortDetail({\n id,\n IsLoadContent: false,\n })\n );\n\n const detailFolderResponses = await Promise.all(promises);\n\n detailFolderResponses.forEach((resp) => {\n const path = resp?.data?.folderName ?? resp?.data?.description;\n result = result + `/${path}`;\n });\n\n return result;\n};\n\nexport const getDestinationFolderParams = async (selectedFolder = {}) => {\n if (selectedFolder) {\n const {\n hierarchy,\n id: selectedId,\n folderName,\n description,\n } = selectedFolder;\n const isRootFolder = hierarchy === '/';\n\n if (isRootFolder)\n return {\n destinationPath: `/${folderName ?? description}`,\n destinationFolderId: selectedId,\n };\n\n const parentIds = hierarchy\n ? hierarchy\n .split('/')\n .filter(Boolean)\n .map((id) => parseInt(id))\n : [];\n const fullPathIds = parentIds.concat(selectedId);\n\n const destinationPath = await generateDestinationFolderPath(fullPathIds);\n\n return {\n destinationPath,\n destinationFolderId: selectedId,\n };\n }\n\n return {};\n};\n","import { useState, useEffect } from 'react';\nimport { useSelector } from 'react-redux';\n\nimport { CustomNotification } from 'common/components';\nimport { NodeTree } from 'common/components/folder/FolderTree';\nimport { IconFolderAsset } from '../shared/components';\n\nimport * as selectorNav from '@redux/branding/selectors';\n\nimport {\n getDestinationFolderParams,\n mappingInteropItemsToTreeData,\n} from './utils';\nimport {\n mappingFolderToTreeData,\n filterParams,\n} from 'common/components/folder/utils';\nimport { updateTreeData } from '../shared/utils';\nimport { sleep } from 'utils/delay';\n\nimport { useCheckPermissions, useUserInfo } from 'hooks';\n\nimport { getInteropListItems } from 'services/interoperability';\nimport { getFolderList, getItemsOfFolder } from 'services/new-folder';\nimport { getFolderShortDetail } from 'services/folder';\n\nimport emptyFolderIcon from 'assets/folder/empty-folder.png';\nimport folderIcon from 'assets/folder/folder.png';\n\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\n\nconst fileParam = {\n renderFile: () => {\n return {\n checkable: true,\n selectable: false,\n };\n },\n};\n\nconst folderParam = {\n renderFolder: (node) => {\n const { subFolderCount } = node ?? {};\n\n const isEmptyContents = subFolderCount === 0;\n\n if (isEmptyContents) {\n return {\n title: (\n \n {node.folderName ?? node.description ?? ''}\n \n }\n />\n ),\n icon: ,\n isLeaf: true,\n selectable: true,\n };\n }\n return {\n title: (\n \n {node.folderName ?? node.description ?? ''}\n \n }\n />\n ),\n icon: ,\n selectable: true,\n };\n },\n};\n\nexport const useGetTreeData = ({ multipleImport, storageServiceType }) => {\n const [treeData, setTreeData] = useState([]);\n const [status, setStatus] = useState('idle');\n\n useEffect(() => {\n setStatus('loading');\n getInteropListItems({\n pathInfo: null,\n storageServiceType,\n })\n .then((res) => {\n if (res.isSuccess) {\n setStatus('success');\n\n const mappedTreeData = mappingInteropItemsToTreeData(\n sortInteropData(res?.data?.interopItems),\n multipleImport\n );\n setTreeData(mappedTreeData);\n } else {\n setStatus('error');\n }\n })\n .catch((err) => {\n setStatus('error');\n CustomNotification.error(err?.message ?? 'Something went wrong');\n });\n }, [multipleImport, storageServiceType]);\n\n const handleSetTreeData = (treeData) => setTreeData(treeData);\n\n return {\n treeData,\n handleSetTreeData,\n isExpanding: status === 'loading',\n };\n};\n\nexport const useImportToFolder = ({ isEnabled: isEnabledProp, searchText }) => {\n const { userInfo } = useUserInfo();\n\n const [folder, setFolder] = useState({\n data: [],\n status: 'idle',\n });\n\n const [importFolder, setImportFolder] = useState({\n isEnabled: false,\n selectedFolder: null,\n importedFolderParams: {},\n });\n\n const [isCreateSubfolder, setIsCreateSubfolder] = useState(true);\n\n const removeSelectedFolder = () => {\n setImportFolder((prevVal) => ({\n ...prevVal,\n selectedFolder: null,\n importedFolderParams: {},\n }));\n };\n\n useEffect(() => {\n if (isEnabledProp && importFolder?.isEnabled) {\n setFolder((prevVal) => ({\n ...prevVal,\n status: 'loading',\n }));\n\n const params = {\n pageIndex: 1,\n pageSize: 9999,\n sort: [{ fieldName: 'id', isAscending: false }],\n search: { searchText },\n filters: searchText\n ? [\n {\n fieldName: 'ownerId',\n filterType: 'Equal',\n value: userInfo?.companyId,\n },\n ]\n : [\n {\n fieldName: 'ownerId',\n filterType: 'Equal',\n value: userInfo?.companyId,\n },\n {\n fieldName: 'level',\n filterType: 'Equal',\n value: '1',\n },\n ],\n };\n\n getFolderList(params)\n .then((res) => {\n if (res.isSuccess) {\n const mappedTreeData = mappingFolderToTreeData(\n res?.data?.gridData,\n folderParam,\n fileParam\n );\n setFolder((prevVal) => ({\n ...prevVal,\n status: 'success',\n data: mappedTreeData,\n }));\n } else {\n setFolder((prevVal) => ({\n ...prevVal,\n status: 'error',\n data: [],\n }));\n CustomNotification.error(res.message ?? 'Something went wrong');\n }\n })\n .catch((err) => {\n setFolder((prevVal) => ({\n ...prevVal,\n status: 'error',\n data: [],\n }));\n CustomNotification.error(err.message ?? 'Something went wrong');\n });\n }\n }, [isEnabledProp, searchText, userInfo?.companyId, importFolder?.isEnabled]);\n\n const handleUpdateFolder = async (_, info) => {\n if (!info?.selected) {\n setImportFolder((prevVal) => ({\n ...prevVal,\n selectedFolder: null,\n importedFolderParams: {},\n }));\n } else {\n const importedFolderParams = await getDestinationFolderParams(\n info?.node?.data\n );\n setImportFolder((prevVal) => ({\n ...prevVal,\n selectedFolder: info?.node?.data,\n importedFolderParams,\n }));\n }\n };\n\n const handleToggleImportFolder = (value) => {\n if (!value) {\n setImportFolder((prevVal) => ({\n ...prevVal,\n isEnabled: value,\n selectedFolder: null,\n importedFolderParams: {},\n }));\n } else {\n setImportFolder((prevVal) => ({\n ...prevVal,\n isEnabled: value,\n }));\n }\n };\n\n const handleLoadMoreItem = async ({ key, children, data }) => {\n // if (loadedKeys.includes(key)) return;\n\n const { id: folderId } = data;\n\n const params = {\n folderId,\n pageIndex: 1, // change later\n pageSize: 9999,\n filters: filterParams['folder'],\n sort: [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ], // new first,\n };\n\n const response = await getItemsOfFolder(params);\n\n return new Promise(async (resolve) => {\n if (children || response === null) {\n resolve();\n return;\n }\n\n const mappedTreeData = mappingFolderToTreeData(\n response?.data?.gridData,\n folderParam,\n fileParam\n );\n const newData = updateTreeData(folder?.data, key, mappedTreeData);\n await sleep(500); // sleep a little bit to update tree (get idea from antd :))\n\n setFolder((prevVal) => ({\n ...prevVal,\n data: newData,\n }));\n\n resolve();\n });\n };\n\n const handleToggleCreateSubfolder = (value) => setIsCreateSubfolder(value);\n\n /**\n *\n * @param {} nodeId\n * @param {*} currentTree\n * @param {*} modData\n * @returns //! return new tree after modify one node\n */\n const modifyNodeOnTree = (nodeId, currentTree, modData) => {\n const { data, children, isLeaf } = modData || {};\n\n return currentTree.map((currentNode) => {\n const {\n data: currentData,\n children: currentChildren,\n isLeaf: currentIsLeaf,\n } = currentNode;\n\n const { id: currentId } = currentData || {};\n\n if (currentId === nodeId) {\n return {\n ...currentNode,\n data: data ? data(currentData) : currentData,\n children: children ? children(currentChildren) : currentChildren,\n isLeaf: isLeaf ? isLeaf(currentIsLeaf) : currentIsLeaf,\n icon: ,\n };\n } else if (currentChildren && currentChildren.length > 0) {\n return {\n ...currentNode,\n children: modifyNodeOnTree(nodeId, currentChildren, modData),\n };\n }\n return currentNode;\n });\n };\n\n const onLoadingCreateFolder = async (ms) => {\n setFolder((prevVal) => ({\n ...prevVal,\n status: 'loading',\n }));\n\n await sleep(ms);\n };\n\n const onCreateNewFolderSuccess = async (nodeData) => {\n await onLoadingCreateFolder(3000);\n\n const { id: folderId } = nodeData || {};\n\n let params = {};\n let itemList = [];\n let shortDetailFolder = [];\n let newTree;\n\n if (folderId) {\n params = {\n folderId,\n pageIndex: 1, // change later\n pageSize: 9999,\n filters: filterParams['folder'],\n sort: [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ], // new first,\n };\n } else {\n params = {\n pageIndex: 1,\n pageSize: 9999,\n sort: [{ fieldName: 'id', isAscending: false }],\n search: { searchText },\n filters: searchText\n ? []\n : [\n {\n fieldName: 'level',\n filterType: 'Equal',\n value: '1',\n },\n ],\n };\n }\n\n itemList = await getFolderList(params);\n if (folderId) {\n shortDetailFolder = await getFolderShortDetail({\n id: folderId,\n IsLoadContent: false,\n });\n }\n\n const mappedListItemToTreeFormat = mappingFolderToTreeData(\n itemList?.data?.gridData,\n folderParam,\n fileParam\n );\n\n if (!folderId) {\n const rootListHaveChildren = folder?.data.filter(\n (dataItem) => dataItem?.children\n );\n\n if (rootListHaveChildren?.length > 0) {\n newTree = mappedListItemToTreeFormat.map((dataItem) => {\n let newDataItem = dataItem;\n\n for (const rootListItem in rootListHaveChildren) {\n if (\n dataItem?.data?.id &&\n rootListItem?.data?.id === dataItem?.data?.id\n ) {\n newDataItem = rootListItem;\n break;\n }\n }\n return newDataItem;\n });\n } else {\n newTree = mappedListItemToTreeFormat;\n }\n\n setFolder((prevVal) => ({\n ...prevVal,\n data: newTree,\n status: 'success',\n }));\n } else {\n newTree = modifyNodeOnTree(folderId, folder?.data, {\n data: (nodeData) => ({\n ...nodeData,\n subFolderCount: shortDetailFolder?.data?.subFolderCount,\n }),\n children: () => mappedListItemToTreeFormat,\n isLeaf: () => false,\n });\n await sleep(500); // sleep a little bit to update tree (get idea from antd :))\n\n setFolder((prevVal) => ({\n ...prevVal,\n data: newTree,\n status: 'success',\n }));\n }\n };\n\n return {\n folderData: folder?.data ?? [],\n isEnabledImportFolder: Boolean(importFolder?.isEnabled),\n importedFolderParams: {\n ...importFolder.importedFolderParams,\n },\n isCreateSubfolder,\n selectedFolder: importFolder?.selectedFolder,\n isLoading: folder?.status === 'idle' || folder?.status === 'loading',\n handleLoadMoreItem,\n handleUpdateFolder,\n handleToggleCreateSubfolder,\n handleToggleImportFolder,\n onCreateNewFolderSuccess,\n removeSelectedFolder,\n };\n};\n\nexport const useCheckAllowImportToFolder = () => {\n const PERMISSION_VIEW_FOLDER = [\n {\n action: ABILITY_ACTION.VIEW,\n subject: ABILITY_SUBJECT.FOLDER,\n },\n ];\n\n const hasPermissionViewFolder = useCheckPermissions(PERMISSION_VIEW_FOLDER);\n\n const { canAccessFolders } = useSelector(selectorNav.getBranding()) ?? {};\n\n return hasPermissionViewFolder && canAccessFolders;\n};\n\nexport const useCheckAllowCreateFolder = () => {\n const PERMISSION_CREATE_FOLDER = [\n {\n action: ABILITY_ACTION.CREATE,\n subject: ABILITY_SUBJECT.FOLDER,\n },\n ];\n\n const hasPermissionCreateFolder = useCheckPermissions(\n PERMISSION_CREATE_FOLDER\n );\n\n const { canAccessFolders } = useSelector(selectorNav.getBranding()) ?? {};\n\n return hasPermissionCreateFolder && canAccessFolders;\n};\n\n// move folders to top\nconst sortInteropData = (data = []) => {\n const folders = data.filter((item) => item.type === 'folder');\n const files = data.filter((item) => item.type === 'file');\n return folders.concat(files);\n};\n","import React, { useState, useEffect, useCallback } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport PropTypes from 'prop-types';\n\nimport { Row, Typography, Col, Switch } from 'antd';\n\nimport * as _ from 'lodash';\nimport classnames from 'classnames';\n\n//* SAGA\nimport * as assetActions from 'pages/asset-full-view/controllers/actions';\nimport * as assetSelectors from 'pages/asset-full-view/controllers/selectors';\nimport * as homeActions from 'pages/home/ribbon/asset-full/controllers/actions';\n\n//* COMPONENTS\nimport UploadFile from 'common/components/uploadFile/UploadFile';\nimport {\n AssetFtpList,\n IframeAsset,\n AssetDropboxUpload,\n AssetUploadSelect,\n AssetToFolder,\n ConfirmContent,\n} from 'pages/asset-full-view/components';\n\n//* UTILS\nimport { forwardTo } from 'utils/common/route';\n\n//* DEFINDE\nimport {\n ASSET_UPLOAD_TYPE,\n ASSET_UPLOAD_METHOD_DEFINE,\n} from 'static/Constants';\n\n//* STYLING\nimport './AssetUpload.less';\nimport { useCheckAllowImportToFolder, useImportToFolder } from './shared/hooks';\n\nimport { TYPE_VIEW_ASSET } from 'static/Constants';\n\nconst { Title } = Typography;\n\nfunction AssetUpload(props) {\n const {\n isBase64,\n apiUrl,\n ftpApiUrl,\n getLocalFileResponse,\n getFtpFileResponse,\n onlyAcceptImage,\n manualUpload,\n showMultiple,\n multiple = false,\n base64UploadKey,\n multipleImport,\n callbackDataList,\n customRequestFtp,\n maxSize,\n getFileChange,\n showList,\n additionalBodyPayload,\n showUploadSuccessMsg,\n showXlsTemplate,\n templateUrl,\n confirmBeforeUpload,\n methodList = ASSET_UPLOAD_METHOD_DEFINE.DEFAULT,\n isShowCancelButton,\n handleCancel = () => {},\n showServerMessage,\n formInstance,\n uploadType,\n setUploadType,\n idSelectionDropbox,\n setIdSelectionDropbox,\n typeViewAsset,\n } = props;\n\n const isCreateAssetView = typeViewAsset === TYPE_VIEW_ASSET.CREATE_ASSET;\n\n const [searchText, setSearchText] = useState('');\n\n const {\n isEnabledImportFolder,\n importedFolderParams,\n folderData,\n isLoading,\n selectedFolder,\n isCreateSubfolder,\n handleLoadMoreItem,\n handleUpdateFolder,\n handleToggleCreateSubfolder,\n handleToggleImportFolder,\n onCreateNewFolderSuccess,\n removeSelectedFolder,\n } = useImportToFolder({\n isEnabled: Boolean(isCreateAssetView),\n searchText,\n });\n\n const isAllowImportToFolder = useCheckAllowImportToFolder();\n\n const dispatch = useDispatch();\n const ftpList = useSelector(assetSelectors.makeSelectFtpFileList());\n\n const getFtpListIfNeed = useCallback((uploadType) => {\n if (\n uploadType !== ASSET_UPLOAD_TYPE.UPLOAD_LOCAL_FILE.name &&\n ASSET_UPLOAD_TYPE[uploadType].params\n ) {\n dispatch(\n assetActions.getFtpFileList(ASSET_UPLOAD_TYPE[uploadType].params)\n );\n }\n }, []);\n\n useEffect(() => {\n getFtpListIfNeed(uploadType);\n }, [uploadType, dispatch, getFtpListIfNeed]);\n\n const onCreateIframeSuccess = (id, metaData) => {\n dispatch(assetActions.cancelUpdateSuccess());\n dispatch(assetActions.createDigitalAssetFullSuccess(metaData));\n dispatch(homeActions.editAsset());\n dispatch(homeActions.creatingAsset());\n forwardTo(`/asset/${id}`);\n };\n\n const destinationFolder = {\n destinationFolder: selectedFolder,\n isCreateSubfolder,\n };\n\n const {\n isUploadFromLocal,\n isUploadFromFtp,\n isUploadFromUrl,\n isUploadFromDropbox,\n } = getTypeUpload(uploadType);\n\n const UploadTypeToArray = _.toArray(ASSET_UPLOAD_TYPE);\n\n const includeSubFolders =\n isEnabledImportFolder && (isUploadFromFtp || isUploadFromDropbox)\n ? { includeSubFolders: isCreateSubfolder }\n : null;\n\n const AdditionalBodyPayloadFolder = {\n ...additionalBodyPayload,\n ...importedFolderParams,\n ...includeSubFolders,\n };\n\n const importToFolderParams = {\n ...importedFolderParams,\n ...includeSubFolders,\n };\n\n const uploadInLocalParams = {\n ...AdditionalBodyPayloadFolder,\n StorageServiceType: 'local',\n };\n\n if (isUploadFromUrl)\n return (\n \n );\n\n return (\n
\n
\n \n \n {!multipleImport\n ? UploadTypeToArray.map((uploadOption) => (\n <React.Fragment key={'upload-titlle-' + uploadOption.name}>\n {uploadType === uploadOption.name &&\n uploadOption.title &&\n uploadOption.title}\n </React.Fragment>\n ))\n : 'Choose Files To Import'}\n \n\n {isCreateAssetView && isAllowImportToFolder && (\n handleToggleImportFolder(check)}\n checked={isEnabledImportFolder}\n />\n )}\n\n \n
\n\n
\n
\n {isUploadFromLocal && (\n {\n getLocalFileResponse && getLocalFileResponse(result);\n }}\n manualUpload={manualUpload}\n multiple={multiple}\n onlyAcceptImage={onlyAcceptImage}\n showMultiple={showMultiple}\n base64UploadKey={base64UploadKey}\n multipleImport={multipleImport}\n callbackDataList={callbackDataList}\n maxSize={maxSize}\n getFileChange={getFileChange}\n showList={showList}\n additionalBodyPayload={uploadInLocalParams}\n showUploadSuccessMsg={showUploadSuccessMsg}\n showXlsTemplate={showXlsTemplate}\n templateUrl={templateUrl}\n confirmBeforeUpload={\n \n }\n isShowCancelButton={isShowCancelButton}\n handleCancel={handleCancel}\n showServerMessage={showServerMessage}\n />\n }\n destinationFolder={\n {\n removeSelectedFolder();\n setSearchText(searchText);\n }}\n onUpdateFolder={handleUpdateFolder}\n loadData={handleLoadMoreItem}\n onToggleCreateSubfolder={handleToggleCreateSubfolder}\n subFolderParams={{\n isShow: isUploadFromFtp || isUploadFromDropbox,\n isCreateSubfolder,\n }}\n selectedItem={selectedFolder}\n onCreateNewFolderSuccess={onCreateNewFolderSuccess}\n />\n }\n />\n )}\n {isUploadFromFtp && (\n {\n getFtpFileResponse && getFtpFileResponse(result);\n }}\n showUploadSuccessMsg={showUploadSuccessMsg}\n showXlsTemplate={showXlsTemplate}\n templateUrl={templateUrl}\n // confirmBeforeUpload={\n // \n // }\n destinationFolder={destinationFolder}\n formInstance={formInstance}\n handleCloseModal={handleCancel}\n typeViewAsset={typeViewAsset}\n multiImportFormValue={additionalBodyPayload}\n importedFolderParams={AdditionalBodyPayloadFolder}\n isEnabledImportFolder={isEnabledImportFolder}\n />\n }\n destinationFolder={\n setSearchText(searchText)}\n onUpdateFolder={handleUpdateFolder}\n loadData={handleLoadMoreItem}\n onToggleCreateSubfolder={handleToggleCreateSubfolder}\n subFolderParams={{\n isShow: isUploadFromFtp || isUploadFromDropbox,\n isCreateSubfolder,\n }}\n selectedItem={selectedFolder}\n onCreateNewFolderSuccess={onCreateNewFolderSuccess}\n />\n }\n />\n )}\n\n {isUploadFromDropbox && (\n \n }\n destinationFolder={\n setSearchText(searchText)}\n onUpdateFolder={handleUpdateFolder}\n loadData={handleLoadMoreItem}\n onToggleCreateSubfolder={handleToggleCreateSubfolder}\n subFolderParams={{\n isShow: isUploadFromFtp || isUploadFromDropbox,\n isCreateSubfolder,\n }}\n selectedItem={selectedFolder}\n onCreateNewFolderSuccess={onCreateNewFolderSuccess}\n />\n }\n />\n )}\n
\n
\n
\n \n );\n}\n\nconst ImportAssetSection = ({\n isEnabledImportFolder,\n assetUpload,\n destinationFolder,\n ...rest\n}) => {\n return (\n <>\n \n {assetUpload}\n {isEnabledImportFolder ? (\n {destinationFolder}\n ) : null}\n \n \n );\n};\n\nconst getTypeUpload = (uploadType) => {\n const isUploadFromDropbox =\n uploadType === ASSET_UPLOAD_TYPE.UPLOAD_DROP_BOX_FILE.name;\n const isUploadFromFtp =\n uploadType === ASSET_UPLOAD_TYPE.UPLOAD_ADV_FTP_FILE.name;\n const isUploadFromLocal =\n uploadType === ASSET_UPLOAD_TYPE.UPLOAD_LOCAL_FILE.name;\n const isUploadFromUrl = uploadType === ASSET_UPLOAD_TYPE.UPLOAD_URL.name;\n\n return {\n isUploadFromDropbox,\n isUploadFromFtp,\n isUploadFromLocal,\n isUploadFromUrl,\n };\n};\n\nAssetUpload.propTypes = {\n //? isBase64 - base64 upload for local file upload\n isBase64: PropTypes.bool,\n //? apiUrl - api to upload file\n apiUrl: PropTypes.string,\n //? ftpApiUrl - api to upload ftp file\n ftpApiUrl: PropTypes.string,\n //? getLocalFileResponse - get reponse to handle\n getLocalFileResponse: PropTypes.func,\n //? getFtpFileResponse - get reponse to handle\n getFtpFileResponse: PropTypes.func,\n //? onlyAccepImage - only accept raster image that allow Preview\n onlyAcceptImage: PropTypes.bool,\n //? manualUpload - upload by click upload button instead of auto upload\n manualUpload: PropTypes.bool,\n //todo - showMultiple - show multiple file or signle file - in development\n showMultiple: PropTypes.bool,\n //? multiple: accept multiple files or not\n multiple: PropTypes.bool,\n //? ftpList - ftp files returned from server\n ftpList: PropTypes.object,\n //todo - base64 upload key - pass key as id of thumbnail\n base64UploadKey: PropTypes.string,\n //? customRequestFtp - get selected files and custom request of ftp upload\n customRequestFtp: PropTypes.func,\n //? maxSize: max file size\n maxSize: PropTypes.number,\n multipleImport: PropTypes.bool,\n callbackDataList: PropTypes.func,\n};\n\nexport default AssetUpload;\n","import React, { useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { Select } from 'antd';\nimport * as _ from 'lodash';\nimport { useSelector, useDispatch } from 'react-redux';\n\nimport gridSelector from 'common/components/grid-view/controllers/selectors';\nimport * as selectors from 'pages/company-profile/controllers/selectors';\nimport * as memberActions from 'pages/company-profile/controllers/actions';\nimport userSelectors from '@redux/user/selectors';\n\nimport { WrapperSelect } from 'common/components';\n\nimport { ASSET_UPLOAD_TYPE, TYPE_VIEW_ASSET } from 'static/Constants';\n\nimport { useCheckIsSuperAdmin } from 'hooks';\n\nconst { Option } = Select;\n\nconst AssetUploadOption = (props) => {\n const {\n setUploadType,\n uploadType,\n methodList = [],\n isMultipleImport = false,\n typeViewAsset,\n } = props;\n\n const dispatch = useDispatch();\n const isSuperAdmin = useCheckIsSuperAdmin();\n\n const memberInfo = useSelector(selectors.selectMemberProfile());\n\n const userInfo = useSelector(userSelectors.makeSelectUserInfo());\n\n const itemCurrentSelection = useSelector(\n gridSelector.makeSelectItemCurrentSelection()\n );\n useEffect(() => {\n if (_.isEmpty(memberInfo)) {\n dispatch(memberActions.getMemberProfileHeader(userInfo?.member?.id));\n }\n }, [dispatch, userInfo?.member?.id]);\n\n const disabledBtnUpload = ({\n itemCurrentSelection,\n isMultipleImport,\n uploadOption,\n memberInfo,\n methodList,\n typeViewAsset,\n }) => {\n if (!methodList.includes(uploadOption.name)) return true;\n\n if (\n uploadOption.name === 'UPLOAD_URL' &&\n (typeViewAsset === TYPE_VIEW_ASSET.REPLACE_ASSET ||\n typeViewAsset === TYPE_VIEW_ASSET.REPLACE_THUMBNAIL) &&\n (isMultipleImport || !itemCurrentSelection?.isIFrame)\n )\n return true;\n\n if (uploadOption.disabled) return true;\n\n if (\n uploadOption.name === 'UPLOAD_ADV_FTP_FILE' &&\n !memberInfo?.ftpEnabled &&\n !isSuperAdmin\n )\n return true;\n\n if (\n uploadOption.name === 'UPLOAD_DROP_BOX_FILE' &&\n !memberInfo?.canAccessInterops &&\n !isSuperAdmin\n )\n return true;\n\n return false;\n };\n\n return (\n {\n setUploadType(value);\n }}\n value={uploadType}\n allowClear={false}\n >\n {_.toArray(ASSET_UPLOAD_TYPE).map((uploadOption) => {\n return (\n \n {uploadOption.optionName}\n \n );\n })}\n \n );\n};\n\nAssetUploadOption.propTypes = {\n setUploadType: PropTypes.func,\n uploadType: PropTypes.string,\n disableOptions: PropTypes.arrayOf(PropTypes.string),\n};\n\nexport default AssetUploadOption;\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { useDispatch, useSelector } from 'react-redux';\nimport {\n SendOutlined,\n FileExcelOutlined,\n LinkOutlined,\n CloseOutlined,\n LoadingOutlined,\n} from '@ant-design/icons';\nimport {\n Typography,\n Button,\n Skeleton,\n Empty,\n Row,\n Col,\n Tooltip,\n Image,\n Result,\n} from 'antd';\nimport Messages from 'i18n/messages/messageAssetUpload';\nimport { FormattedMessage } from 'react-intl';\nimport classnames from 'classnames';\nimport * as _ from 'lodash';\nimport { useMedia } from 'react-media';\n\n//* COMPONENT\nimport { CustomNotification, dialogFunction } from 'common/components';\nimport { SelectedFile, TreeFiles } from './shared/components';\nimport { ConfirmContent } from 'pages/asset-full-view/components';\nimport xls from 'assets/file-formats/xls.png';\n\n//* UTILS\nimport * as api from 'config/axios';\nimport { DataToMsOffice } from 'utils/dataToMSoffice';\nimport * as globalActions from '@redux/global/actions';\n\nimport {\n mappingInteropItemsToTreeData,\n getExpandedData,\n updateTreeData,\n findNodeTree,\n getChildNodesInFolder,\n filterArrayInAnotherArray,\n filterArrayObjectInAnotherArrayObject,\n findAncestorsOfChildNode,\n getOnlySelectedParentItems,\n getFormDataParams,\n filterFoldersAndFilesInSelectedItems,\n getFormValues,\n getFilesPath,\n getFoldersPath,\n findListNodeInTree,\n getAllFilesInFolders,\n getFilesAfterExpandingAll,\n} from './shared/utils';\n\nimport { useCheckAllowCreateFolder, useGetTreeData } from './shared/hooks';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\n\n//* MAPPERS\n// import mapFtpListToAntTree from './mappers/mapFtpListToAntTree';\n// import mapFtpListFile from './mappers/mapFtpListFile';\n\nimport {\n createReplacedAsset,\n importAssetsFromInterop,\n} from 'services/interoperability';\n\nimport * as homeActions from 'pages/home/ribbon/asset-full/controllers/actions';\nimport * as assetActions from 'pages/asset-full-view/controllers/actions';\nimport gridSelector from 'common/components/grid-view/controllers/selectors';\nimport * as ribbonSelector from '@redux/ribbon/selectors';\nimport * as brandingActions from '@redux/branding/actions';\nimport * as assetSelectors from 'pages/asset-full-view/controllers/selectors';\n\nimport CreateFolderModal from 'pages/home/ribbon/components/controls/folders/CreateFolderModal';\n\nimport { forwardTo, navigateToRouteAsset } from 'utils/common/route';\nimport { sleep } from 'utils/delay';\nimport { isImageType } from 'utils/fileType';\nimport { getVirtualScrollHeight } from './shared/utils';\n\nimport { GLOBAL_MEDIA_QUERIES } from 'static/MediaQuery';\nimport { RIBBON_VIEW, ROUTE } from 'static/Constants';\n\n//* STYLING\n\nimport * as damServices from 'services/digitalAsset';\n\nimport './AssetFtpList.less';\n\nconst { Title, Text } = Typography;\n\nfunction AssetFtpList(props) {\n const {\n ftpListFile,\n multiple,\n multipleImport = false,\n callbackDataList,\n templateUrl,\n formInstance,\n typeViewAsset,\n handleCloseModal,\n confirmBeforeUpload,\n importedFolderParams = {},\n isEnabledImportFolder,\n destinationFolder,\n multiImportFormValue,\n } = props;\n\n const reloadPage = useDispatchReloadPage();\n\n const [selectedFile, setSelectedFile] = useState(null);\n const [xlsList, setXlsList] = useState(undefined);\n const [statusLoading, setStatusLoading] = useState('idle');\n const [visibleModal, setVisibleModal] = useState(false);\n\n const isHasDestinationFolder = Boolean(\n importedFolderParams?.destinationFolderId\n );\n\n const dispatch = useDispatch();\n\n const replacedGridAsset = useSelector(\n gridSelector.makeSelectItemCurrentSelection()\n );\n\n const replacedFullView = useSelector(assetSelectors.assetDataLoading());\n\n const isAllowCreateFolder = useCheckAllowCreateFolder();\n\n const isAssetFullView =\n useSelector(ribbonSelector.selectRibbon()) ===\n RIBBON_VIEW.ASSET_FULL_VIEW.NAME;\n\n const assetId = isAssetFullView\n ? replacedFullView?.id\n : replacedGridAsset?.id;\n\n const matches = useMedia({ queries: GLOBAL_MEDIA_QUERIES });\n\n const largeScreen = matches.lg || matches.md || matches.xl;\n\n const updateProgressBar = (selectedItems = [], status, percent) => {\n if (status === 'error' || status === 'done' || status === 'uploading') {\n selectedItems.forEach((fileItem) => {\n dispatch(\n globalActions.updateProgressBar({\n type: 'upload',\n name: fileItem.data.path,\n percent,\n status,\n uid: fileItem.data.itemId,\n })\n );\n });\n }\n };\n\n const virtualScrollHeight = getVirtualScrollHeight(\n largeScreen,\n multipleImport\n );\n\n const handleReplaceSingleAsset = async () => {\n const singleItem = selectedItems[0];\n const params = {\n storageServiceType: 'ftp',\n filePath: [singleItem.data.path],\n };\n\n const formData = getFormDataParams(params);\n\n updateProgressBar(selectedItems, 'uploading', 0);\n\n try {\n const response = await createReplacedAsset(formData, assetId);\n\n if (response?.isSuccess) {\n const metaData = response.data;\n\n handleCreateSingleAssetSuccess(metaData);\n updateProgressBar(selectedItems, 'done', 100);\n } else {\n updateProgressBar(selectedItems, 'error', 0);\n }\n } catch (error) {\n updateProgressBar(selectedItems, 'error', 0);\n }\n };\n\n const handleCreateSingleAsset = async () => {\n const singleItem = selectedItems[0];\n\n const params = {\n storageServiceType: 'ftp', // I don't know why BE does not use 'advFTP'. I cried so much in here, good luck to me\n filePaths: [singleItem.data.path],\n isCreateThumbs: true,\n };\n const formData = getFormDataParams(params);\n\n updateProgressBar(selectedItems, 'uploading', 0);\n\n try {\n const response = await importAssetsFromInterop(formData);\n\n if (response.isSuccess) {\n const metaData = response.data;\n handleCreateSingleAssetSuccess(metaData);\n updateProgressBar(selectedItems, 'done', 100);\n } else {\n CustomNotification.error(response?.message ?? 'Something went wrong');\n updateProgressBar(selectedItems, 'error', 0);\n }\n } catch (error) {\n CustomNotification.error(error?.message ?? 'Something went wrong');\n updateProgressBar(selectedItems, 'error', 0);\n }\n };\n\n const handleCreateSingleAssetSuccess = (metaData) => {\n const id = metaData.id;\n\n handleCloseModal();\n dispatch(assetActions.cancelUpdateSuccess());\n dispatch(assetActions.createDigitalAssetFullSuccess(metaData));\n dispatch(homeActions.editAsset());\n dispatch(homeActions.creatingAsset());\n dispatch(brandingActions.getBrandingNoLoading());\n\n navigateToRouteAsset({\n typeViewAsset,\n id,\n isMultipleImport: multipleImport,\n });\n };\n\n const handleCreateMultipleAssets = async (otherParams = {}) => {\n const formValues = getFormValues(formInstance);\n const { folders, files } =\n filterFoldersAndFilesInSelectedItems(selectedItems);\n const filePaths = getFilesPath(folders, files);\n const folderPaths = getFoldersPath(folders);\n const params = {\n id: null,\n storageServiceType: 'ftp',\n filePaths,\n folderPaths,\n templateFile: xlsList,\n ...importedFolderParams,\n ...formValues,\n ...otherParams,\n };\n let formData = getFormDataParams(params);\n updateProgressBar(selectedItems, 'uploading', 0);\n try {\n const response = await importAssetsFromInterop(formData);\n if (response?.isSuccess) {\n handleCloseModal();\n navigateToRouteAsset({\n isMultipleImport: multipleImport,\n });\n dispatch(brandingActions.getBrandingNoLoading());\n updateProgressBar(selectedItems, 'done', 100);\n CustomNotification.success('Create successfully');\n } else {\n CustomNotification.error(response?.message ?? 'Something went wrong');\n }\n } catch (error) {\n CustomNotification.error(error?.message ?? 'Something went wrong');\n updateProgressBar(selectedItems, 'error', 0);\n }\n };\n\n const handleAttachTemplate = () => {\n const $input = document.createElement('input');\n $input.setAttribute('type', 'file');\n const handleSelectFile = (event) => {\n let file = event.target.files[0];\n if (file) {\n if (\n file.type ===\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n ) {\n setXlsList(file);\n CustomNotification.success('The file is attached successfully');\n } else {\n CustomNotification.error('Only accept xls file');\n setXlsList(undefined);\n }\n }\n };\n $input.onchange = handleSelectFile;\n $input.click();\n };\n\n const handleDownloadTemplate = () => {\n api.sendDownload({\n url: templateUrl || '/unknown',\n });\n };\n\n const handleCopyFileNameToExcel = async () => {\n setStatusCopy('loading');\n\n let copyItems = [];\n\n const selectedFiles = selectedItems.filter(\n (item) => item.data.type === 'file'\n );\n const selectedFolders = selectedItems.filter(\n (item) => item.data.type === 'folder'\n );\n\n if (expandAll.status === 'success') {\n const folderNodes = findListNodeInTree(treeData, selectedFolders);\n const filesInFolder = getAllFilesInFolders(folderNodes);\n\n copyItems = selectedFiles.concat(filesInFolder);\n } else {\n const expandedFiles = await getFilesAfterExpandingAll({\n folderNodes: selectedFolders,\n id: null,\n storageServiceType: 'advFTP',\n multipleImport,\n });\n\n copyItems = selectedFiles.concat(expandedFiles);\n }\n\n DataToMsOffice().copy2DArrayClipboardToExcel(\n copyItems.map((fileItem) => [fileItem.data.name])\n );\n\n setStatusCopy('success');\n };\n\n const replaceThumbnail = async () => {\n const singleItem = selectedItems[0];\n const isImgType = isImageType(singleItem?.data?.path);\n if (!isImgType) {\n CustomNotification.error('Only support image type');\n return;\n }\n const params = {\n assetId,\n storageServiceType: 'ftp',\n filePath: singleItem?.data?.path,\n };\n const formData = getFormDataParams(params);\n setStatusLoading('loading');\n try {\n const response = await damServices.replaceDigitalAssetsThumbnails(\n formData\n );\n if (response?.isSuccess) {\n setStatusLoading('success');\n handleCloseModal();\n reloadPage({ clearSelection: true });\n CustomNotification.success('Replace Preview successfully');\n } else {\n CustomNotification.error(response?.message ?? 'Something went wrong');\n setStatusLoading('error');\n }\n } catch (error) {\n CustomNotification.error(error?.message ?? 'Something went wrong');\n setStatusLoading('error');\n }\n };\n\n const modalConfirmImportAsset = (otherParams = {}) => {\n const newDestinationFolder = otherParams?.destinationFolderId\n ? { ...destinationFolder, destinationFolder: { ...otherParams } }\n : destinationFolder;\n\n dialogFunction({\n type: 'warn',\n content: (\n \n ),\n onOk: async () => {\n await sleep(1000);\n CustomNotification.warning(\n 'Please wait while the import process is being completed. This may require additional time, especially for larger datasets. We appreciate your understanding and patience during this process',\n 30\n );\n handleCreateMultipleAssets(otherParams);\n forwardTo(ROUTE.DIGITAL_MEDIA);\n },\n okText: 'Upload',\n width: 450,\n });\n };\n\n const handleClickSend = () => {\n // If user doesn't have create folder permission, we won't show modal for creating destination folder\n const isIgnoreShowModalCreate = !isAllowCreateFolder;\n\n if (multipleImport) {\n if (isIgnoreShowModalCreate) {\n modalConfirmImportAsset();\n } else if (isEnabledImportFolder && !isHasDestinationFolder) {\n setVisibleModal(true);\n } else {\n modalConfirmImportAsset();\n }\n return;\n } else {\n if (typeViewAsset === 'replace-asset') {\n handleReplaceSingleAsset();\n } else if (typeViewAsset === 'create-asset') {\n handleCreateSingleAsset();\n } else {\n replaceThumbnail();\n return;\n }\n }\n };\n\n useEffect(() => {\n setSelectedFile(null);\n if (typeof callbackDataList === 'function') callbackDataList([], true);\n }, [ftpListFile, callbackDataList]);\n\n const { treeData, handleSetTreeData } = useGetTreeData({\n multipleImport,\n storageServiceType: 'advFTP',\n });\n\n const [{ selectedItems, selectedKeys, expandedKeys }, setSelectedFtp] =\n useState({\n selectedItems: [],\n selectedKeys: [],\n expandedKeys: [],\n });\n\n /*\n status === 'loading': treeData is loading data inside\n status === 'success': treeData is already loaded data\n */\n const [expandAll, setExpandAll] = useState({\n value: false,\n status: 'idle',\n });\n\n const [statusCopy, setStatusCopy] = useState('idle');\n\n const handleLoadData = async ({ key, children, data }) => {\n if (expandAll.status === 'success') return;\n\n const { path } = data;\n const expandedData = await getExpandedData({\n pathInfo: path,\n storageServiceType: 'advFTP',\n });\n\n return new Promise((resolve) => {\n if (children) {\n resolve();\n return;\n }\n const mappedTreeData = mappingInteropItemsToTreeData(\n expandedData,\n multipleImport\n );\n const newData = updateTreeData(treeData, key, mappedTreeData);\n\n handleSetTreeData(newData);\n resolve();\n });\n };\n\n const handleSelectItems = (keys, { selectedNodes: items }) => {\n if (multipleImport) {\n const parentSelectedItems = getOnlySelectedParentItems(\n treeData,\n items,\n keys\n );\n\n setSelectedFtp((prevItems) => ({\n ...prevItems,\n selectedItems: parentSelectedItems,\n selectedKeys: keys,\n }));\n } else {\n setSelectedFtp((prevItems) => ({\n ...prevItems,\n selectedItems: items,\n selectedKeys: keys,\n }));\n }\n };\n\n const handleCheckItems = (keys, { checkedNodes: items }) => {\n if (multipleImport) {\n const parentSelectedItems = getOnlySelectedParentItems(\n treeData,\n items,\n keys\n );\n\n setSelectedFtp((prevItems) => ({\n ...prevItems,\n selectedItems: parentSelectedItems,\n selectedKeys: keys,\n }));\n } else {\n setSelectedFtp((prevItems) => ({\n ...prevItems,\n selectedItems: items,\n selectedKeys: keys,\n }));\n }\n };\n\n const handleDeleteItem = (itemId) => {\n if (!multipleImport) {\n setSelectedFtp((prevItems) => ({\n ...prevItems,\n selectedItems: [],\n selectedKeys: [],\n }));\n } else {\n const foundNode = findNodeTree(treeData, itemId);\n const isHaveChildren = foundNode?.children?.length > 0;\n\n const ancestorNodes = findAncestorsOfChildNode(treeData, foundNode);\n const ancestorKeys = ancestorNodes.map((node) => node.key);\n\n if (isHaveChildren) {\n const childNodes = getChildNodesInFolder(foundNode.children);\n const childKeys = childNodes.map((node) => node.key);\n\n const allKeys = [foundNode.key].concat(ancestorKeys).concat(childKeys); // include select key and ancestor keys\n const allNodes = [foundNode].concat(ancestorNodes).concat(childNodes);\n\n const filteredSelectedKeys = filterArrayInAnotherArray(\n selectedKeys,\n allKeys\n );\n const filteredSelectedItems = filterArrayObjectInAnotherArrayObject(\n selectedItems,\n allNodes\n );\n\n setSelectedFtp((prevItems) => ({\n ...prevItems,\n selectedItems: filteredSelectedItems,\n selectedKeys: filteredSelectedKeys,\n }));\n } else {\n const allKeys = [foundNode.key].concat(ancestorKeys); // include select key and ancestor keys\n const allNodes = [foundNode].concat(ancestorNodes);\n\n const filteredSelectedKeys = filterArrayInAnotherArray(\n selectedKeys,\n allKeys\n );\n const filteredSelectedItems = filterArrayObjectInAnotherArrayObject(\n selectedItems,\n allNodes\n );\n\n setSelectedFtp((prevItems) => ({\n ...prevItems,\n selectedItems: filteredSelectedItems,\n selectedKeys: filteredSelectedKeys,\n }));\n }\n }\n };\n // after 30 days if the function is not restored please delete this code, thanks\n\n // const handleExpandAllFiles = async (event) => {\n // const checked = event.target.checked;\n\n // if (checked) {\n // setExpandAll((prevVal) => ({ ...prevVal, value: checked }));\n\n // // If treeData loaded data, then does not need to call api again.\n // if (expandAll.status !== 'success') {\n // setExpandAll((prevVal) => ({ ...prevVal, status: 'loading' }));\n\n // const newTreeData = await getTreeDataAfterExpandingAll({\n // treeData,\n // id: null,\n // storageServiceType: 'advFTP',\n // multipleImport,\n // });\n\n // const expandedKeys = getAllExpandedKeys(newTreeData);\n\n // setSelectedFtp((prevItems) => ({\n // ...prevItems,\n // expandedKeys,\n // }));\n\n // handleSetTreeData(newTreeData);\n // setExpandAll((prevVal) => ({ ...prevVal, status: 'success' }));\n // } else {\n // const expandedKeys = getAllExpandedKeys(treeData);\n\n // setSelectedFtp((prevItems) => ({\n // ...prevItems,\n // expandedKeys,\n // }));\n // }\n // } else {\n // setExpandAll((prevVal) => ({ ...prevVal, value: checked }));\n // setSelectedFtp((prevItems) => ({\n // ...prevItems,\n // expandedKeys: [],\n // }));\n // }\n // };\n\n const handleExpandItems = (expandedKeys) => {\n setSelectedFtp((prevItems) => ({\n ...prevItems,\n expandedKeys,\n }));\n };\n\n const ftpListError = _.get(ftpListFile, 'error');\n\n const disabledBtn = selectedItems.length === 0;\n\n return (\n <>\n \n
\n
\n
\n \n <FormattedMessage {...Messages.ftpHeader} />\n \n {/* \n Expand All\n */}\n
\n\n \n {ftpListError ? (\n \n ) : treeData?.length ? (\n \n ) : (\n \n )}\n
\n
\n \n \n Selected Items\n {xlsList && multipleImport && (\n <Row className='asset-ftp__sub-title-xls'>\n <Col>\n <Tooltip title={xlsList.name}>\n <Image\n className='asset-ftp__sub-title-xls-img'\n height={28}\n width={23}\n src={xls}\n placeholder={\n <LoadingOutlined\n style={{ fontSize: 27, backgroundColor: 'white' }}\n />\n }\n preview={false}\n />\n </Tooltip>\n </Col>\n <Col\n className='asset-ftp__sub-title-xls-delete'\n style={{ paddingLeft: 4 }}\n >\n <CloseOutlined onClick={() => setXlsList(undefined)} />\n </Col>\n </Row>\n )}\n \n\n \n \n \n {selectedItems.map((item) => (\n \n ))}\n \n \n \n \n \n {multipleImport && (\n \n }\n onClick={handleDownloadTemplate}\n disabled\n >\n Download xls Template\n \n\n }\n onClick={handleCopyFileNameToExcel}\n disabled\n >\n Copy All Selected Items\n \n\n }\n onClick={handleAttachTemplate}\n disabled\n >\n Attach file (.xls)\n \n \n )}\n }\n loading={statusLoading === 'loading'}\n disabled={disabledBtn}\n onClick={() => handleClickSend()}\n >\n Send\n {multipleImport &&\n selectedFile &&\n selectedFile?.length > 0 && (\n \n {selectedFile.length}\n \n )}\n \n \n \n \n \n \n \n
\n\n {isAllowCreateFolder && (\n {\n modalConfirmImportAsset({\n destinationFolderId: responseData?.id,\n });\n }}\n additionalButton={() => {\n return (\n \n modalConfirmImportAsset()}\n >\n Continue without destination folder\n \n \n );\n }}\n />\n )}\n \n );\n}\n\nAssetFtpList.propTypes = {\n //? ftpListFile - ftp files list\n ftpListFile: PropTypes.object,\n //? apiUrl - to post Ftp File\n apiUrl: PropTypes.string,\n //? getResponse - send response to prarent to process\n getResponse: PropTypes.func,\n //? onlyAccpetImage - only show image ftp file\n onlyAccpetImage: PropTypes.bool,\n //? customRequestFtp - custom request of ftp method\n customRequestFtp: PropTypes.func,\n multipleImport: PropTypes.bool,\n callbackDataList: PropTypes.func,\n};\n\nexport default AssetFtpList;\n","import React, { useState, useEffect, useCallback } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useHistory } from 'react-router-dom';\n\nimport {\n Input,\n Checkbox,\n Select,\n Tabs,\n Col,\n Row,\n Tag,\n InputNumber,\n DatePicker,\n} from 'antd';\nimport classnames from 'classnames';\n\nimport {\n Form,\n dialogFunction,\n WrapperSelect,\n AssetTypeEdit,\n} from 'common/components';\nimport AssetCreator from '../metadata-panel/AssetCreator';\nimport iconList from 'common/components/icon-list/assets';\nimport { ConfirmContentAsEdit } from 'pages/asset-full-view/components';\n\nimport * as globalSelectors from '@redux/global/selectors';\nimport * as actionsGlobal from '@redux/global/actions';\nimport userSelectors from '@redux/user/selectors';\nimport * as actionsRibbon from 'pages/home/ribbon/asset-full/controllers/actions';\nimport * as companySelectors from 'pages/company-profile/controllers/selectors';\nimport memberReducer from 'pages/company-profile/controllers/reducer';\nimport saga from 'pages/company-profile/controllers/saga';\nimport * as memberActions from 'pages/company-profile/controllers/actions';\n\nimport assetSelectors from 'pages/home/ribbon/asset-full/controllers/selectors';\nimport * as actions from '../../controllers/actions';\nimport * as selectors from '../../controllers/selectors';\n\nimport * as constants from 'static/Constants';\n\nimport { FormattedMessage, injectIntl } from 'react-intl';\nimport Messages from 'i18n/messages/asset-full-view.js';\nimport messages from 'i18n/messages/assetDetail';\n\nimport sortByKey from 'utils/sortByKey';\nimport {\n exportFormDateWithoutTime,\n formatRangeDateTime,\n} from 'utils/formatDate';\nimport { getDateFormat } from 'utils/formatDate';\nimport { formatSizeUnits } from 'utils/formatSizeUnits';\nimport { getParameterFromQuery } from 'utils/common/route';\n\nimport { useInjectSaga } from 'utils/common/injectSaga';\nimport { useInjectReducer } from 'utils/common/injectedReducers';\nimport { useValidateStatusField } from 'hooks/useValidateStatusField';\nimport { useGetMemberHeaderFromMemberId } from 'common/queries/member-module';\n\nimport './AssetEdit.less';\n\nconst { RangePicker } = DatePicker;\n\nconst formItemOverView = {\n labelCol: { span: 12 },\n wrapperCol: { span: 12 },\n};\n\nconst AssetEdit = (props) => {\n const history = useHistory();\n const dispatch = useDispatch();\n\n useInjectReducer({ key: 'member', reducer: memberReducer });\n useInjectSaga({ key: 'member', saga });\n\n const [form] = Form.useForm();\n\n const { assetData, openItemFormData, intl } = props;\n const [typeData, setTypeData] = useState({\n assetType: assetData?.assetType,\n assetSubType: assetData?.assetSubType,\n packageLevel: assetData?.metadata?.packageLevel || assetData?.packageLevel,\n packagingDisposition:\n assetData?.metadata?.packagingDisposition ||\n assetData?.packagingDisposition,\n angle: assetData?.metadata?.angle || assetData?.angle,\n facing: assetData?.metadata?.facing || assetData?.facing,\n language: assetData?.metadata?.language || assetData?.language,\n panelType: assetData?.metadata?.panelType || assetData?.panelType,\n logoType: assetData?.metadata?.logoType || assetData?.logoType,\n certificateType:\n assetData?.metadata?.certificateType || assetData?.certificateType,\n documentType: assetData?.metadata?.documentType || assetData?.documentType,\n });\n const [tagsMode, setTagsMode] = useState('tags');\n const [tags, setTags] = useState([]);\n\n const saving = useSelector(assetSelectors.selectAssetSaving());\n const requiredFields = useSelector(selectors.selectRequiredFields());\n const authorizedTagsInfo = useSelector(selectors.selectAuthorizedTags());\n const isEdit = useSelector(assetSelectors.selectAssetEdit);\n const isAddingOpenItemFormData = useSelector(\n globalSelectors.selectIsAddingOpenItemFormData()\n );\n const userInfo = useSelector(userSelectors.makeSelectUserInfo());\n const memberInfo = useSelector(companySelectors.selectMemberProfile());\n\n const isCreating = Boolean(getParameterFromQuery('draft'));\n\n const { enforceTagRestrictions, authorizedTags } = authorizedTagsInfo;\n\n const { statusValidateProps } = useValidateStatusField({\n form,\n entityType: 'Asset',\n entityId: assetData?.id,\n placement: 'bottomRight',\n });\n\n const { data: memberHeaderOfAssetOwner } = useGetMemberHeaderFromMemberId({\n memberId: assetData?.ownerId,\n enabled: Boolean(assetData && assetData?.ownerId),\n });\n\n const isPrivateVisibilityAsset =\n memberHeaderOfAssetOwner?.digitalAssets?.toLowerCase() === 'private';\n\n useEffect(() => {\n dispatch(memberActions.getMemberProfileHeader(userInfo?.member?.id));\n }, [dispatch, userInfo?.member?.id]);\n\n useEffect(() => {\n let classifications = [];\n assetData?.classifications?.length > 0 &&\n assetData.classifications.forEach((val) => {\n let segmentFilter = iconList.filter(\n (item) => item.segmentId === val.segmentId\n );\n if (segmentFilter?.length > 0 && segmentFilter[0]?.segmentDescription) {\n classifications.push(segmentFilter[0].segmentDescription);\n }\n });\n let additionalSearchTags = assetData?.additionalSearchTags\n ? assetData?.additionalSearchTags\n .toString()\n .split(',')\n .filter((tag) => tag !== '')\n : [];\n let exifData = assetData?.metadata?.exifData === 'Yes' ? true : false;\n\n !openItemFormData &&\n form.setFieldsValue({\n assetName: assetData?.assetName,\n //TODO: DATETIME\n effectiveTime: [\n getDateFormat(assetData?.effectedDate),\n getDateFormat(assetData?.expirationDate),\n ],\n ...typeData,\n assetDescription: assetData?.assetDescription,\n additionalSearchTags: additionalSearchTags,\n status: assetData?.status,\n classifications: classifications,\n channelOutput:\n assetData?.metadata?.channelOutput || assetData?.channelOutput,\n clippingPath:\n assetData?.metadata?.clippingPath || assetData?.clippingPath,\n colorDepth: assetData?.metadata?.colorDepth || assetData?.colorDepth,\n colorModel: assetData?.metadata?.colorModel || assetData?.colorModel,\n cropRange: assetData?.metadata?.cropRange || assetData?.cropRange,\n duration: assetData?.metadata?.duration || assetData?.duration,\n exifData: assetData?.metadata?.exifData || assetData?.exifData,\n fileName: assetData?.metadata?.fileName || assetData?.fileName,\n fileSize: formatSizeUnits(\n assetData?.metadata?.fileSize || assetData?.fileSize\n ),\n fileType: assetData?.metadata?.fileType || assetData?.fileExtension,\n fps: assetData?.metadata?.fps || assetData?.fps,\n bitRate: assetData?.metadata?.bitRate || assetData?.bitRate,\n frameRate: assetData?.metadata?.frameRate || assetData?.frameRate,\n frameSize: assetData?.metadata?.frameSize || assetData?.frameSize,\n sampleRate: assetData?.metadata?.sampleRate || assetData?.sampleRate,\n chanelOutput:\n assetData?.metadata?.chanelOutput || assetData?.chanelOutput,\n height: assetData?.metadata?.height || assetData?.height,\n lastModified:\n assetData?.metadata?.lastModified || assetData?.lastModified,\n loadedDate: assetData?.metadata?.loadedDate || assetData?.loadedDate,\n mediaFormat: assetData?.metadata?.mediaFormat || assetData?.mediaFormat,\n owner: assetData?.metadata?.owner || assetData?.owner,\n pageCount: assetData?.metadata?.pageCount || assetData?.pageCount,\n resolution: assetData?.metadata?.resolution || assetData?.resolution,\n width: assetData?.metadata?.width || assetData?.width,\n isShowcase: assetData?.isShowcase,\n visibility: assetData?.visibility || constants.ASSET_VISIBILITY[2],\n });\n openItemFormData && form.setFieldsValue(openItemFormData);\n }, [assetData, openItemFormData]);\n\n const handleSubmitForm = useCallback(\n (formInstance) => {\n const formData = formInstance.getFieldsValue();\n const effDate = formatRangeDateTime(formData?.effectiveTime?.[0]);\n const expDate = formatRangeDateTime(formData?.effectiveTime?.[1]);\n\n if (effDate > new Date()) {\n dialogFunction({\n type: 'warn',\n content: ,\n onOk: () => {\n formInstance.submit();\n },\n onCancel: () => {\n dispatch(actionsRibbon.cancelSavingAsset());\n },\n okText: 'Ok',\n width: 465,\n });\n } else {\n formInstance.submit();\n }\n },\n [dispatch]\n );\n\n useEffect(() => {\n if (saving) {\n handleSubmitForm(form);\n }\n }, [saving, form, handleSubmitForm, dispatch]);\n\n const getFormData = (form) => {\n dispatch(actionsGlobal.updateOpenItemForm(form.getFieldsValue()));\n };\n\n useEffect(() => {\n if (isAddingOpenItemFormData) getFormData(form);\n }, [isAddingOpenItemFormData]);\n\n useEffect(() => {\n if (assetData?.ownerId) {\n dispatch(actions.getAuthorizedTags(assetData?.ownerId));\n }\n }, [assetData?.ownerId, dispatch]);\n\n useEffect(() => {\n if (enforceTagRestrictions) {\n setTagsMode('multiple');\n }\n }, [enforceTagRestrictions]);\n\n useEffect(() => {\n if (enforceTagRestrictions) {\n setTags(onSetFilterTags());\n } else {\n setTags([]);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n enforceTagRestrictions,\n authorizedTagsInfo,\n typeData?.assetType,\n typeData?.assetSubType,\n ]);\n\n const onSetFilterTags = () => {\n return (\n authorizedTags &&\n authorizedTags.filter((tag) => {\n if (tag?.assetType) {\n if (tag?.assetSubType) {\n return (\n tag.assetType === typeData?.assetType &&\n tag.assetSubType === typeData?.assetSubType\n );\n } else {\n return tag.assetType === typeData?.assetType;\n }\n } else {\n return tag;\n }\n })\n );\n };\n\n const onFinishFailed = (errorInfo) => {\n dispatch(actionsRibbon.cancelSavingAsset());\n };\n\n const onFinish = (values) => {\n // update additionalSearchTags from string to list string\n\n let classifications = [];\n values?.classifications?.length > 0 &&\n values.classifications.forEach((val) => {\n let segmentId = iconList.filter(\n (item) => item.segmentDescription === val\n );\n if (segmentId?.length > 0 && segmentId[0]?.segmentId) {\n classifications.push({ segmentId: segmentId[0].segmentId });\n }\n });\n let params = Object.assign(values, {\n id: assetData.id,\n draftAssetId: assetData?.pendingAssetId, // After deleting draft status, draftAssetId is got from pendingAssetId\n assetType: assetData.assetType,\n ...typeData,\n });\n params.classifications = classifications;\n //? set effective date\n if (params.effectiveTime) {\n const startTime = formatRangeDateTime(params.effectiveTime?.[0]);\n const endTime = formatRangeDateTime(params.effectiveTime?.[1]);\n // params.effectedDate = startTime ? startTime.toISOString() : null;\n // params.expirationDate = endTime ? endTime.toISOString() : null;\n params.effectedDate = startTime\n ? exportFormDateWithoutTime(startTime)\n : null;\n params.expirationDate = endTime\n ? exportFormDateWithoutTime(endTime)\n : null;\n }\n delete params.effectiveTime;\n if (assetData?.metadata?.fileSize || assetData?.fileSize) {\n params.fileSize = assetData?.metadata?.fileSize || assetData?.fileSize;\n }\n if (assetData?.isIFrame) params.isIFrame = true;\n if (history.location.search.indexOf('?replace-asset') > -1) {\n dispatch(actions.updateDigitalReplaceAsset(params));\n } else {\n dispatch(actions.updateDigitalAsset(params));\n }\n };\n useEffect(() => {\n if (requiredFields?.length) {\n const isReplaceAsset =\n history.location.search.indexOf('?replace-asset') > -1;\n const status = isReplaceAsset\n ? 'Replace'\n : isCreating\n ? 'Create'\n : 'Edit';\n validateStatusField();\n dispatch(actions.updateRequiredField([]));\n }\n }, [requiredFields, dispatch]);\n\n const validateStatusField = () => {\n const event = new CustomEvent(constants.EVENT.VALIDATE_STATUS_FIELD);\n document.dispatchEvent(event);\n };\n\n const assetStatus = isCreating\n ? constants.ASSET_CREATE_STATUS_OPTIONS\n : constants.ASSET_STATUS_OPTIONS;\n\n const assetOverview = (data) => {\n let assetFieldOverview;\n let type = data?.fileType || data?.fileExtension;\n if (type === 'zip' || type === 'rar' || type === '7z') {\n assetFieldOverview = constants.ASSET_FIELD_ZIP;\n } else if (\n type === 'mkv' ||\n type === 'mp4' ||\n type === 'avi' ||\n type === 'mov' ||\n type === 'flv' ||\n type === 'wav'\n ) {\n assetFieldOverview = constants.ASSET_FIELD_VIDEO;\n } else if (type === 'mp3' || type === 'ogg') {\n assetFieldOverview = constants.ASSET_FIELD_AUDIO;\n } else if (\n type === 'jpg' ||\n type === 'jpeg' ||\n type === 'png' ||\n type === 'gif' ||\n type === 'tiff' ||\n type === 'psd' ||\n type === 'bmp' ||\n type === 'ico' ||\n type === 'tga'\n ) {\n assetFieldOverview = constants.ASSET_FIELD_IMAGE;\n } else {\n assetFieldOverview = constants.ASSET_FIELD_DOCUMENT;\n }\n\n return (\n <>\n {assetFieldOverview?.length > 0 &&\n assetFieldOverview.map((val, i) => {\n if (val.element === 'text') {\n if (val.type === 'checkbox') {\n return (\n \n }\n valuePropName='checked'\n >\n \n \n \n );\n } else {\n return (\n \n }\n >\n \n \n \n );\n }\n }\n if (val.element === 'input' && val.type === 'string') {\n if (val.field === 'fileName') {\n return (\n \n }\n rules={[\n {\n required: true,\n message: 'Please input file name',\n },\n ]}\n >\n \n \n \n );\n } else {\n return (\n \n }\n >\n \n \n \n );\n }\n }\n if (val.element === 'input' && val.type === 'checkbox') {\n return (\n \n }\n valuePropName='checked'\n >\n \n \n \n );\n }\n if (val.element === 'input' && val.type === 'number') {\n return (\n \n }\n >\n \n \n \n );\n }\n if (val.element === 'textarea') {\n return (\n \n }\n >\n \n \n \n );\n }\n })}\n \n );\n };\n\n const tagRender = (props) => {\n const { label, value, closable, onClose } = props;\n const src = iconList.filter((val) => val.segmentDescription === value);\n return (\n \n \n \n );\n };\n\n // bp 12/13/2020 - fix data subtype is required but is not validated\n const onValuesChange = (changedValues, allValues) => {\n setTypeData(allValues);\n };\n\n return (\n \n \n \n \n \n }\n rules={[\n {\n required: true,\n message: intl.formatMessage(\n messages.assetNameRequiredMessage\n ),\n },\n {\n whitespace: true,\n message: intl.formatMessage(\n messages.assetNameWhiteSpaceMessage\n ),\n },\n ]}\n >\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n }\n >\n \n \n \n \n \n \n }\n {...statusValidateProps}\n >\n document.getElementById('asset-edit')}\n allowClear={false}\n >\n {assetStatus\n ?.slice()\n .sort()\n .map((status, index) => {\n return (\n \n {status}\n \n );\n })}\n \n \n\n }\n labelCol={{ span: 5 }}\n wrapperCol={{ span: 19 }}\n >\n \n \n }\n >\n document.getElementById('asset-edit')}\n >\n {tags &&\n tags.length > 0 &&\n sortByKey(tags, 'tagName')?.map((tag, index) => {\n return (\n \n {tag?.tagName}\n \n );\n })}\n \n \n\n \n \n \n
\n \n onValuesChange(changedValues, allValues)\n }\n />\n
\n {!assetData?.isIFrame && assetOverview(assetData)}\n \n }\n >\n \n document.getElementById('asset-edit')\n }\n >\n {isPrivateVisibilityAsset\n ? constants.PRIVATE_VISIBILITY_ASSET?.slice()\n .sort()\n .map((item, index) => {\n let visibilityValue = item === 'None' ? null : item;\n return (\n \n {item}\n \n );\n })\n : constants.ASSET_VISIBILITY?.slice()\n .sort()\n .map((item, index) => {\n let visibilityValue = item === 'None' ? null : item;\n return (\n \n {item}\n \n );\n })}\n \n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n document.getElementById('asset-edit')}\n >\n {sortByKey(iconList, 'segmentDescription')?.map((val) => {\n return (\n \n \n {val.segmentDescription}\n \n );\n })}\n \n \n
\n
\n \n );\n};\n\nexport default injectIntl(AssetEdit);\n","import React from 'react';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport {\n TitleFolderAsset,\n IconFolderAsset,\n TitleFileAsset,\n IconFileAsset,\n} from '../shared/components';\n\nimport { getInteropListItems } from 'services/interoperability';\nimport { formatRangeDateTime } from 'utils/formatDate';\n\nconst getUuidKey = () => uuidv4();\n\nconst getNodeTreeData = (interop, multipleImport) => {\n if (interop.type === 'folder') {\n return {\n key: getUuidKey(),\n title: ,\n icon: ,\n data: interop,\n selectable: false,\n checkable: multipleImport ? true : false,\n };\n }\n return {\n key: getUuidKey(),\n title: ,\n icon: ,\n data: interop,\n selectable: multipleImport ? false : true,\n isLeaf: true,\n };\n};\n\nexport const updateTreeData = (list, key, children) => {\n return list.map((node) => {\n if (node.key === key) {\n return { ...node, children };\n }\n\n if (node.children) {\n return {\n ...node,\n children: updateTreeData(node.children, key, children),\n };\n }\n\n return node;\n });\n};\n\nexport const mappingInteropItemsToTreeData = (\n interopItems = [],\n multipleImport = false\n) => {\n let treeData = [];\n\n interopItems.forEach((interop) => {\n if (interop.type === 'folder') {\n let node = getNodeTreeData(interop, multipleImport);\n treeData.push(node);\n } else {\n let node = getNodeTreeData(interop, multipleImport);\n treeData.push(node);\n }\n });\n\n return treeData;\n};\n\nexport const getExpandedData = async (params) => {\n const response = await getInteropListItems(params);\n if (response?.isSuccess) {\n if (response?.data?.interopItems) {\n return response?.data?.interopItems;\n }\n }\n return null;\n};\n\nexport const getFormDataParams = (params = {}) => {\n let formData = new FormData();\n\n Object.entries(params).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((item) => {\n formData.append(key, item);\n });\n } else {\n formData.append(key, value);\n }\n });\n\n return formData;\n};\n\nexport const filterFoldersAndFilesInSelectedItems = (selectedItems = []) => {\n let folders = [];\n let files = [];\n\n selectedItems.forEach((item) => {\n const { data } = item;\n\n if (data.type === 'file') {\n files.push(item);\n } else if (data.type === 'folder') {\n if (Array.isArray(item.children) && item.children.length > 0) {\n folders.push(item);\n filterFoldersAndFilesInSelectedItems(item.children);\n } else {\n folders.push(item);\n }\n }\n });\n\n return {\n folders,\n files,\n };\n};\n\nconst findFileExistInAnyFolders = (folders, file) => {\n return folders.some((item) => {\n if (item.key === file.key) {\n return true;\n } else if (item.children) {\n return findFileExistInAnyFolders(item.children, file);\n }\n return false;\n });\n};\n\n// A file will be sent to the server when folder that contains the file does not check\nexport const getFilesPath = (folders, files) => {\n let result = [];\n\n files.forEach((file) => {\n const isExist = findFileExistInAnyFolders(folders, file);\n\n if (!isExist) {\n result.push(file.data.path);\n }\n });\n\n return result;\n};\n\nconst findFolderExistInAnyFolders = (folders, findFolder) => {\n return folders.some((folder) => {\n if (folder.key === findFolder.key) {\n return true;\n } else if (folder.children) {\n return findFolderExistInAnyFolders(folder.children, findFolder);\n }\n return false;\n });\n};\n\n// A folder will be sent to the server when folder that contains the file does not check\nexport const getFoldersPath = (folders) => {\n let result = [];\n\n folders.forEach((folder) => {\n const filteredFolders = folders.filter((f) => f.key !== folder.key);\n\n const isExist = findFolderExistInAnyFolders(filteredFolders, folder);\n\n if (!isExist) {\n result.push(folder.data.path);\n }\n });\n\n return result;\n};\n\nlet foundNode = null;\nexport const findNodeTree = (treeData, itemId) => {\n for (let index = 0; index < treeData.length; index++) {\n const node = treeData[index];\n if (node.data.itemId === itemId) {\n foundNode = node;\n break;\n }\n\n if (node?.children) {\n findNodeTree(node.children, itemId);\n }\n }\n return foundNode;\n};\n\nexport const getChildNodesInFolder = (treeData) => {\n let children = [];\n const flattenMembers = treeData.map((m) => {\n if (m.children && m.children.length) {\n children = [...children, ...m.children];\n }\n return m;\n });\n\n return flattenMembers.concat(\n children.length ? getChildNodesInFolder(children) : children\n );\n};\n\nexport const filterArrayInAnotherArray = (arr1, arr2) => {\n return arr1.filter((item) => !arr2.includes(item));\n};\n\nexport const findAncestorsOfChildNode = (treeData, childNode) => {\n if (Array.isArray(treeData) && treeData.length > 0) {\n for (let i = 0; i < treeData.length; i++) {\n if (treeData[i].key === childNode.key) return [];\n\n let result = findAncestorsOfChildNode(treeData[i].children, childNode);\n if (result !== null) {\n result = result.concat(treeData[i]);\n return result;\n }\n }\n }\n return null;\n};\n\nexport const filterArrayObjectInAnotherArrayObject = (\n array1 = [],\n array2 = []\n) => {\n let result = [];\n\n array1.forEach((item1) => {\n const foundItem = array2.find((item2) => item1.key === item2.key);\n\n if (!foundItem) {\n result.push(item1);\n }\n });\n\n return result;\n};\n\nexport const getOnlySelectedParentItems = (treeData, items, keys) => {\n let result = [];\n items.forEach((item) => {\n const ancestorNodes = findAncestorsOfChildNode(treeData, item);\n const ancestorKeys = ancestorNodes.map((node) => node.key);\n const isParentSelected = findSelectedKeyInAnotherKeys(keys, ancestorKeys);\n\n if (!isParentSelected) {\n result.push(item);\n }\n });\n return result;\n};\n\nexport const findSelectedKeyInAnotherKeys = (keys, selectedKeys) => {\n return selectedKeys.find((key) => {\n return keys.includes(key);\n });\n};\n\nexport const getFormValues = (form) => {\n const {\n effectivePeriod,\n defaultStatus,\n isCreateThumbs,\n autoApplyOrReplaceOnProducts,\n } = form.getFieldsValue();\n\n const startTime = formatRangeDateTime(effectivePeriod?.[0]);\n const endTime = formatRangeDateTime(effectivePeriod?.[1]);\n\n const formValues = {\n EffectedDate: startTime ? startTime.toISOString() : null,\n ExpirationDate: endTime ? endTime.toISOString() : null,\n defaultStatus,\n isCreateThumbs,\n autoApplyOrReplaceOnProducts,\n };\n\n return formValues;\n};\n","import React from 'react';\n\nimport { Typography, Select, Empty } from 'antd';\n\nimport classnames from 'classnames';\n\nimport { WithLoading } from 'common/components';\nimport { TreeFiles } from '../shared/components';\n\nimport {\n getExpandedData,\n mappingInteropItemsToTreeData,\n updateTreeData,\n} from './utils';\nimport { sleep } from 'utils/delay';\n\nimport { GLOBAL_MEDIA_QUERIES } from 'static/MediaQuery';\nimport { getVirtualScrollHeight } from '../shared/utils';\n\nimport { useMedia } from 'react-media';\n\nexport const DropboxFiles = (props) => {\n const {\n idConnection,\n multipleImport,\n treeData,\n isExpanding,\n expandAll,\n selectedDropbox,\n onSetTreeData,\n onSelectItems,\n onExpandItems,\n } = props;\n\n const matches = useMedia({ queries: GLOBAL_MEDIA_QUERIES });\n const largeScreen = matches.lg || matches.md || matches.xl;\n\n const { selectedKeys, expandedKeys } = selectedDropbox;\n\n const virtualScrollHeight = getVirtualScrollHeight(\n largeScreen,\n multipleImport\n );\n\n const handleSelectItems = (key, info) => {\n onSelectItems(key, info.selectedNodes);\n };\n\n const handleCheckItems = (key, { checkedNodes }) => {\n onSelectItems(key, checkedNodes);\n };\n\n const handleLoadData = async ({ key, children, data }) => {\n // Tree data is already loaded data inside.\n if (expandAll.status === 'success') return;\n\n const { path } = data;\n\n const expandedData = await getExpandedData({\n id: idConnection,\n pathInfo: path,\n getFile: true,\n getFolder: true,\n storageServiceType: 'dropbox',\n });\n\n return new Promise(async (resolve) => {\n if (children || expandedData === null) {\n resolve();\n return;\n }\n\n const mappedTreeData = mappingInteropItemsToTreeData(\n expandedData,\n multipleImport\n );\n\n await sleep(500);\n\n onSetTreeData((prevData) =>\n updateTreeData(prevData, key, mappedTreeData)\n );\n resolve();\n });\n };\n\n const isLoading = isExpanding || expandAll.status === 'loading';\n\n return (\n \n \n {treeData?.length > 0 ? (\n \n ) : (\n \n )}\n \n \n );\n};\n\nexport const DropboxSelection = ({\n valueIdSelection,\n checked,\n interoperabilities,\n onChangeIdConnection,\n // onChangeExpandAll,\n}) => {\n return (\n \n \n Connection:\n \n \n {interoperabilities.map((interop) => (\n \n {interop.storageServiceName}\n \n ))}\n \n\n {/* \n Expand All\n
*/}\n \n );\n};\n","import React, { useState } from 'react';\n\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport classnames from 'classnames';\n\nimport { Typography, Tag, Button, Upload, Image, Tooltip, Col } from 'antd';\nimport {\n SendOutlined,\n FileExcelOutlined,\n LinkOutlined,\n CloseOutlined,\n LoadingOutlined,\n} from '@ant-design/icons';\n\nimport {\n CustomNotification,\n dialogFunction,\n FormButton,\n} from 'common/components';\nimport { ConfirmContent } from 'pages/asset-full-view/components';\nimport { IconFileAsset, IconFolderAsset } from '../shared/components';\nimport CreateFolderModal from 'pages/home/ribbon/components/controls/folders/CreateFolderModal';\n\nimport * as homeActions from 'pages/home/ribbon/asset-full/controllers/actions';\nimport * as assetActions from 'pages/asset-full-view/controllers/actions';\nimport * as assetSelectors from 'pages/asset-full-view/controllers/selectors';\nimport gridSelector from 'common/components/grid-view/controllers/selectors';\nimport * as ribbonSelector from '@redux/ribbon/selectors';\nimport * as brandingActions from '@redux/branding/actions';\nimport * as globalActions from '@redux/global/actions';\n\nimport { forwardTo, navigateToRouteAsset } from 'utils/common/route';\nimport {\n getFormDataParams,\n filterFoldersAndFilesInSelectedItems,\n getFilesPath,\n getFoldersPath,\n getFormValues,\n} from '../shared/utils.js';\nimport { sleep } from 'utils/delay';\n\nimport { isImageType } from 'utils/fileType';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\nimport { useCheckAllowCreateFolder } from '../shared/hooks';\n\nimport {\n importAssetsFromInterop,\n createReplacedAsset,\n} from 'services/interoperability';\n\nimport xlsFile from 'assets/file-formats/xls.png';\n\nimport { RIBBON_VIEW, ROUTE } from 'static/Constants';\n\nimport * as endpointAsset from 'services/digitalAsset/endpoints';\nimport * as damServices from 'services/digitalAsset';\n\nimport * as api from 'config/axios';\n\nimport './DropboxActions.less';\n\nconst typeExcel =\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';\n\nconst DropboxActions = (props) => {\n const {\n idConnection,\n formInstance,\n selectedItems,\n multipleImport,\n typeViewAsset,\n // statusCopy,\n importedFolderParams,\n onDeleteItem,\n handleCloseModal,\n onCopyFileNameExcel,\n destinationFolder,\n isEnabledImportFolder,\n } = props;\n\n const dispatch = useDispatch();\n\n const [status, setStatus] = useState('idle');\n const [file, setFile] = useState(null);\n const [visibleModal, setVisibleModal] = useState(false);\n\n const replacedGridAsset = useSelector(\n gridSelector.makeSelectItemCurrentSelection()\n );\n\n const replacedFullView = useSelector(assetSelectors.assetDataLoading());\n\n const isAssetFullView =\n useSelector(ribbonSelector.selectRibbon()) ===\n RIBBON_VIEW.ASSET_FULL_VIEW.NAME;\n\n const isAllowCreateFolder = useCheckAllowCreateFolder();\n\n const assetId = isAssetFullView\n ? replacedFullView?.id\n : replacedGridAsset?.id;\n\n const reloadPage = useDispatchReloadPage();\n\n const isHasDestinationFolder = Boolean(\n importedFolderParams?.destinationFolderId\n );\n\n const handleReplaceSingleAsset = async () => {\n const singleItem = selectedItems[0];\n const params = {\n id: idConnection,\n storageServiceType: 'dropbox',\n filePath: [singleItem.data.path],\n };\n\n const formData = getFormDataParams(params);\n\n setStatus('loading');\n updateProgressBar(selectedItems, 'uploading', 0);\n\n try {\n const response = await createReplacedAsset(formData, assetId);\n\n if (response?.isSuccess) {\n const metaData = response.data;\n\n setStatus('success');\n handleCreateSingleAssetSuccess(metaData);\n updateProgressBar(selectedItems, 'done', 100);\n } else {\n setStatus('error');\n updateProgressBar(selectedItems, 'error', 0);\n }\n } catch (error) {\n setStatus('error');\n updateProgressBar(selectedItems, 'error', 0);\n }\n };\n\n const handleCreateSingleAsset = async () => {\n const singleItem = selectedItems[0];\n const params = {\n id: idConnection,\n storageServiceType: 'dropbox',\n filePaths: [singleItem.data.path],\n isCreateThumbs: true,\n };\n const formData = getFormDataParams(params);\n\n setStatus('loading');\n updateProgressBar(selectedItems, 'uploading', 0);\n\n try {\n const response = await importAssetsFromInterop(formData);\n if (response.isSuccess) {\n const metaData = response.data;\n setStatus('success');\n handleCreateSingleAssetSuccess(metaData);\n updateProgressBar(selectedItems, 'done', 100);\n } else {\n setStatus('error');\n updateProgressBar(selectedItems, 'error', 0);\n }\n } catch (error) {\n setStatus('error');\n updateProgressBar(selectedItems, 'error', 0);\n }\n };\n\n const handleCreateSingleAssetSuccess = (metaData) => {\n const id = metaData.id;\n\n handleCloseModal();\n dispatch(assetActions.cancelUpdateSuccess());\n dispatch(assetActions.createDigitalAssetFullSuccess(metaData));\n dispatch(homeActions.editAsset());\n dispatch(homeActions.creatingAsset());\n dispatch(brandingActions.getBrandingNoLoading());\n\n navigateToRouteAsset({\n typeViewAsset,\n id,\n isMultipleImport: multipleImport,\n });\n };\n\n const handleCloseCreateFolder = () => setVisibleModal(false);\n\n const handleCreateMultipleAssets = async (otherParams = {}) => {\n const formValues = getFormValues(formInstance);\n\n const { folders, files } =\n filterFoldersAndFilesInSelectedItems(selectedItems);\n\n const filePaths = getFilesPath(folders, files);\n const folderPaths = getFoldersPath(folders);\n\n const params = {\n id: idConnection,\n storageServiceType: 'dropbox',\n filePaths,\n folderPaths,\n templateFile: file,\n ...importedFolderParams,\n ...formValues,\n ...otherParams,\n };\n\n let formData = getFormDataParams(params);\n\n setStatus('loading');\n updateProgressBar(selectedItems, 'uploading', 0);\n\n try {\n await sleep(1000);\n const response = await importAssetsFromInterop(formData);\n\n if (response?.isSuccess) {\n setStatus('success');\n handleCloseModal();\n handleCloseCreateFolder();\n\n dispatch(brandingActions.getBrandingNoLoading());\n\n updateProgressBar(selectedItems, 'done', 100);\n\n CustomNotification.success('Create asset successfully');\n } else {\n CustomNotification.error(response?.message ?? 'Something went wrong');\n setStatus('error');\n }\n } catch (error) {\n CustomNotification.error(error?.message ?? 'Something went wrong');\n setStatus('error');\n updateProgressBar(selectedItems, 'error', 0);\n }\n };\n\n const handleReplaceThumbnail = async () => {\n const singleItem = selectedItems[0];\n const isImage = isImageType(singleItem?.data?.path);\n if (!isImage) {\n CustomNotification.error('Only support image type');\n return;\n }\n const params = {\n assetId,\n id: idConnection,\n storageServiceType: 'dropbox',\n filePath: singleItem?.data?.path,\n };\n const formData = getFormDataParams(params);\n setStatus('loading');\n try {\n const response = await damServices.replaceDigitalAssetsThumbnails(\n formData\n );\n if (response?.isSuccess) {\n setStatus('success');\n handleCloseModal();\n reloadPage({ clearSelection: true });\n CustomNotification.success('Replace Preview successfully');\n } else {\n CustomNotification.error(response?.message ?? 'Something went wrong');\n setStatus('error');\n }\n } catch (error) {\n CustomNotification.error(error?.message ?? 'Something went wrong');\n setStatus('error');\n }\n };\n\n const modalConfirmImportAsset = (otherParams = {}) => {\n const multiImportFormValue = getFormValues(formInstance);\n\n const newDestinationFolder = otherParams?.destinationFolderId\n ? { ...destinationFolder, destinationFolder: { ...otherParams } }\n : destinationFolder;\n\n dialogFunction({\n type: 'warn',\n content: (\n \n ),\n onOk: async () => {\n CustomNotification.warning(\n 'Please wait while the import process is being completed. This may require additional time, especially for larger datasets. We appreciate your understanding and patience during this process',\n 30\n );\n handleCreateMultipleAssets(otherParams);\n forwardTo(ROUTE.DIGITAL_MEDIA);\n },\n okText: 'Upload',\n width: 450,\n });\n };\n\n const handleCreateAssetFromInterop = () => {\n // If user doesn't have create folder permission, we won't show modal for creating destination folder\n const isIgnoreShowModalCreate = !isAllowCreateFolder;\n\n if (multipleImport) {\n if (isIgnoreShowModalCreate) {\n modalConfirmImportAsset();\n } else if (isEnabledImportFolder && !isHasDestinationFolder) {\n setVisibleModal(true);\n } else {\n modalConfirmImportAsset();\n }\n } else {\n if (typeViewAsset === 'replace-asset') {\n handleReplaceSingleAsset();\n } else if (typeViewAsset === 'create-asset') {\n handleCreateSingleAsset();\n } else {\n handleReplaceThumbnail();\n return;\n }\n }\n };\n\n const handleUploadFile = (file) => {\n if (file?.type === typeExcel) {\n CustomNotification.success('The file is attached successfully');\n setFile(file);\n } else {\n CustomNotification.error('Only accept xls file');\n setFile(null);\n }\n return false;\n };\n\n const updateProgressBar = (selectedItems = [], status, percent) => {\n if (status === 'error' || status === 'done' || status === 'uploading') {\n selectedItems.forEach((fileItem) => {\n dispatch(\n globalActions.updateProgressBar({\n type: 'upload',\n name: fileItem.data.path,\n percent,\n status,\n uid: fileItem.data.itemId,\n })\n );\n });\n }\n };\n\n const disabledBtn = selectedItems.length === 0;\n\n return (\n \n
\n Selected Items\n\n {file && (\n
\n \n \n }\n />\n \n }\n style={{\n marginLeft: 4,\n border: 'none',\n }}\n onClick={() => setFile(null)}\n />\n
\n )}\n
\n\n \n \n {selectedItems.map((item) => (\n \n ))}\n \n \n {multipleImport && (\n <>\n }\n onClick={() => {\n api.sendDownload({\n url: endpointAsset.GET_IMPORT_ASSET_TEMPLATE || '/unknown',\n });\n }}\n type='default '\n text='Download xls Template'\n disabled\n />\n }\n type='default'\n text='Copy All Selected Items'\n onClick={onCopyFileNameExcel}\n disabled\n />\n \n }\n type='default'\n text='Attach file (.xls)'\n disabled\n />\n \n \n )}\n }\n text='Send'\n // loading={status === 'loading'}\n onClick={handleCreateAssetFromInterop}\n style={{ width: '100%' }}\n disabled={disabledBtn}\n />\n \n \n\n {isAllowCreateFolder && (\n {\n modalConfirmImportAsset({\n destinationFolderId: responseData?.id,\n });\n }}\n additionalButton={() => {\n return (\n \n modalConfirmImportAsset()}\n >\n Continue without destination folder\n \n \n );\n }}\n />\n )}\n \n );\n};\n\nconst SelectedFile = ({ name, itemId, type, onDeleteItem }) => {\n return (\n \n ) : (\n \n )\n }\n color='success'\n className='dropbox-asset__result-tag'\n >\n \n {name}\n \n }\n style={{\n marginLeft: 4,\n border: 'none',\n }}\n onClick={() => onDeleteItem(itemId)}\n />\n \n );\n};\n\nexport default DropboxActions;\n","import { CustomNotification } from 'common/components';\nimport { useState, useEffect } from 'react';\n\nimport { getInteropListItems } from 'services/interoperability';\n\nimport { mappingInteropItemsToTreeData } from './utils';\n\nexport const useGetTreeData = ({ id, multipleImport, storageServiceType }) => {\n const [treeData, setTreeData] = useState([]);\n const [status, setStatus] = useState('idle');\n\n useEffect(() => {\n if (id) {\n setStatus('loading');\n\n getInteropListItems({\n id,\n pathInfo: null,\n storageServiceType,\n getFile: true,\n getFolder: true,\n })\n .then((res) => {\n if (res.isSuccess) {\n setStatus('success');\n\n const mappedTreeData = mappingInteropItemsToTreeData(\n res?.data?.interopItems,\n multipleImport\n );\n setTreeData(mappedTreeData);\n } else {\n setStatus('error');\n setTreeData([]);\n CustomNotification.error(res.message ?? 'Something went wrong');\n }\n })\n .catch((err) => {\n setStatus('error');\n setTreeData([]);\n CustomNotification.error(err.message ?? 'Something went wrong');\n });\n }\n }, [id, multipleImport, storageServiceType]);\n\n const handleSetTreeData = (treeData) => setTreeData(treeData);\n\n return {\n treeData,\n handleSetTreeData,\n setTreeData,\n isExpanding: status === 'loading',\n };\n};\n","import React, { useState, useMemo } from 'react';\n\nimport { DropboxFiles, DropboxSelection } from './DropboxFiles';\nimport DropboxActions from './DropboxActions';\n\nimport { useGetTreeData } from './hooks';\nimport { useGetListConnections } from 'pages/company-profile/components/tabs/system/interoperability/hooks';\n\nimport {\n findNodeTree,\n getChildNodesInFolder,\n filterArrayInAnotherArray,\n filterArrayObjectInAnotherArrayObject,\n findAncestorsOfChildNode,\n getOnlySelectedParentItems,\n} from './utils';\n\nimport {\n findListNodeInTree,\n getAllFilesInFolders,\n getFilesAfterExpandingAll,\n} from '../shared/utils';\n\nimport { DataToMsOffice } from 'utils/dataToMSoffice';\n\nimport './AssetDropboxUpload.less';\n\nconst AssetDropboxUpload = (props) => {\n const {\n isEnabledImportFolder,\n multipleImport,\n formInstance,\n handleCloseModal,\n idSelectionDropbox,\n setIdSelectionDropbox,\n typeViewAsset,\n importedFolderParams,\n destinationFolder,\n } = props;\n\n const { interoperabilities } = useGetListConnections({\n storageServiceType: 'dropbox',\n });\n\n // Default connection is first connection. I can't find any better name. Naming is so hard.\n const valueIdSelection = useMemo(() => {\n if (idSelectionDropbox) return idSelectionDropbox;\n\n if (interoperabilities.length > 0) return interoperabilities[0].id;\n\n return null;\n }, [idSelectionDropbox, interoperabilities]);\n\n const { treeData, isExpanding, setTreeData } = useGetTreeData({\n id: valueIdSelection,\n multipleImport,\n storageServiceType: 'dropbox',\n });\n\n const [selectedDropbox, setSelectedDropbox] = useState({\n selectedItems: [],\n selectedKeys: [],\n expandedKeys: [],\n });\n\n /* \n status === 'loading': treeData is loading data inside\n status === 'success': treeData is already loaded data\n */\n const [expandAll, setExpandAll] = useState({\n value: false,\n status: 'idle',\n });\n\n const [statusCopy, setStatusCopy] = useState('idle');\n\n const handleSelectItems = (keys, items) => {\n if (multipleImport) {\n const parentSelectedItems = getOnlySelectedParentItems(\n treeData,\n items,\n keys\n );\n\n setSelectedDropbox((prevItems) => ({\n ...prevItems,\n selectedItems: parentSelectedItems,\n selectedKeys: keys,\n }));\n } else {\n setSelectedDropbox((prevItems) => ({\n ...prevItems,\n selectedItems: items,\n selectedKeys: keys,\n }));\n }\n };\n\n const handleDeleteItem = (itemId) => {\n if (!multipleImport) {\n setSelectedDropbox((prevItems) => ({\n ...prevItems,\n selectedItems: [],\n selectedKeys: [],\n }));\n } else {\n const { selectedItems, selectedKeys } = selectedDropbox;\n\n const foundNode = findNodeTree(treeData, itemId);\n const isHaveChildren = foundNode?.children?.length > 0;\n\n const ancestorNodes = findAncestorsOfChildNode(treeData, foundNode);\n const ancestorKeys = ancestorNodes.map((node) => node.key);\n\n if (isHaveChildren) {\n const childNodes = getChildNodesInFolder(foundNode.children);\n const childKeys = childNodes.map((node) => node.key);\n\n const allKeys = [foundNode.key].concat(ancestorKeys).concat(childKeys); // include select key and ancestor keys\n const allNodes = [foundNode].concat(ancestorNodes).concat(childNodes);\n\n const filteredSelectedKeys = filterArrayInAnotherArray(\n selectedKeys,\n allKeys\n );\n const filteredSelectedItems = filterArrayObjectInAnotherArrayObject(\n selectedItems,\n allNodes\n );\n\n setSelectedDropbox((prevItems) => ({\n ...prevItems,\n selectedItems: filteredSelectedItems,\n selectedKeys: filteredSelectedKeys,\n }));\n } else {\n const allKeys = [foundNode.key].concat(ancestorKeys); // include select key and ancestor keys\n const allNodes = [foundNode].concat(ancestorNodes);\n\n const filteredSelectedKeys = filterArrayInAnotherArray(\n selectedKeys,\n allKeys\n );\n const filteredSelectedItems = filterArrayObjectInAnotherArrayObject(\n selectedItems,\n allNodes\n );\n\n setSelectedDropbox((prevItems) => ({\n ...prevItems,\n selectedItems: filteredSelectedItems,\n selectedKeys: filteredSelectedKeys,\n }));\n }\n }\n };\n\n const handleCopyFileNameToExcel = async () => {\n setStatusCopy('loading');\n\n let copyItems = [];\n\n const { selectedItems } = selectedDropbox;\n\n const selectedFiles = selectedItems.filter(\n (item) => item.data.type === 'file'\n );\n const selectedFolders = selectedItems.filter(\n (item) => item.data.type === 'folder'\n );\n\n if (expandAll.status === 'success') {\n const folderNodes = findListNodeInTree(treeData, selectedFolders);\n const filesInFolder = getAllFilesInFolders(folderNodes);\n\n copyItems = selectedFiles.concat(filesInFolder);\n } else {\n const expandedFiles = await getFilesAfterExpandingAll({\n folderNodes: selectedFolders,\n id: idSelectionDropbox,\n storageServiceType: 'dropbox',\n multipleImport,\n });\n\n copyItems = selectedFiles.concat(expandedFiles);\n }\n\n DataToMsOffice().copy2DArrayClipboardToExcel(\n copyItems.map((fileItem) => [fileItem.data.name])\n );\n\n setStatusCopy('success');\n };\n\n // after 30 days if the function is not restored please delete this code, thanks\n\n // const handleExpandAllFiles = async (event) => {\n // const checked = event.target.checked;\n\n // if (checked) {\n // setExpandAll((prevVal) => ({ ...prevVal, value: checked }));\n\n // // If treeData loaded data, then does not need to call api again.\n // if (expandAll.status !== 'success') {\n // setExpandAll((prevVal) => ({ ...prevVal, status: 'loading' }));\n\n // const newTreeData = await getTreeDataAfterExpandingAll({\n // treeData,\n // id: valueIdSelection,\n // storageServiceType: 'dropbox',\n // multipleImport,\n // });\n // const expandedKeys = getAllExpandedKeys(newTreeData);\n\n // setSelectedDropbox((prevItems) => ({\n // ...prevItems,\n // expandedKeys,\n // }));\n\n // handleSetTreeData(newTreeData);\n // setExpandAll((prevVal) => ({ ...prevVal, status: 'success' }));\n // } else {\n // const expandedKeys = getAllExpandedKeys(treeData);\n\n // setSelectedDropbox((prevItems) => ({\n // ...prevItems,\n // expandedKeys,\n // }));\n // }\n // } else {\n // setExpandAll((prevVal) => ({ ...prevVal, value: checked }));\n // setSelectedDropbox((prevItems) => ({\n // ...prevItems,\n // expandedKeys: [],\n // }));\n // }\n // };\n\n const handleExpandItems = (expandedKeys) => {\n setSelectedDropbox((prevItems) => ({\n ...prevItems,\n expandedKeys,\n }));\n };\n\n return (\n
\n {\n setIdSelectionDropbox(id);\n setExpandAll(false);\n setSelectedDropbox((prevItems) => ({\n ...prevItems,\n selectedItems: [],\n selectedKeys: [],\n expandedKeys: [],\n }));\n setExpandAll((prevVal) => ({ ...prevVal, status: 'idle' }));\n }}\n // onChangeExpandAll={handleExpandAllFiles}\n checked={expandAll.value}\n />\n \n \n
\n );\n};\n\nexport default AssetDropboxUpload;\n","import React from 'react';\nimport { Space } from 'antd';\nimport { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons';\n\nconst AssociationIconRenderer = (props) => {\n const { item } = props;\n return (\n \n {item &&\n item.data &&\n (item.data.isInBound ? (\n \n ) : (\n \n ))}\n \n );\n};\nexport default AssociationIconRenderer;\n","import React from 'react';\nimport { Space } from 'antd';\nimport {\n CodeSandboxOutlined,\n FileImageOutlined,\n FileUnknownOutlined,\n FolderOpenOutlined,\n} from '@ant-design/icons';\n\nconst AssociationIconRenderer = (props) => {\n const { item } = props;\n return (\n \n {item &&\n item.data &&\n (item.data.type === 'DigitalAssets' ? (\n \n ) : item.data.type === 'Folder' ? (\n \n ) : item.data.type === 'Product' ? (\n \n ) : (\n \n ))}\n \n );\n};\nexport default AssociationIconRenderer;\n","import React from 'react';\nimport { Row, Col } from 'antd';\nimport classnames from 'classnames';\n\nimport './ConfirmResult.less';\n\nconst AssetUploadConfirmResult = ({\n value,\n iconsRender,\n isDateRender,\n placeholderValue,\n}) => {\n if (!isDateRender) {\n return iconsRender.map((item) => {\n const isRender = item?.conditionCheck(value);\n const Icon = item.icon;\n return (\n <>\n {isRender && (\n \n \n \n {item.text}\n \n \n )}\n \n );\n });\n }\n\n let ActiveIcon = iconsRender?.[0]?.icon ? iconsRender[0].icon :
;\n let InActiveIcon = iconsRender?.[1]?.icon ? iconsRender[1].icon :
;\n\n return (\n \n \n {value ? (\n \n ) : (\n \n )}\n {value || placeholderValue}\n \n \n );\n};\n\nexport default AssetUploadConfirmResult;\n","import React from 'react';\nimport { Row, Col, Typography } from 'antd';\nimport {\n CheckCircleOutlined,\n ExclamationCircleOutlined,\n CheckSquareOutlined,\n CloseSquareOutlined,\n ScheduleOutlined,\n WarningOutlined,\n} from '@ant-design/icons';\nimport ConfirmResult from './ConfirmResult';\nimport { cloneDeep } from 'lodash';\nimport { formatMDY } from 'utils/formatDate';\n\nconst { Text } = Typography;\n\nconst ConfirmContent = (props) => {\n const {\n multiImportFormValue,\n destinationFolder,\n isUploadFromLocal,\n isEnabledImportFolder,\n } = props;\n\n const { destinationFolder: folder, isCreateSubfolder } =\n destinationFolder ?? {};\n\n const importConfirmContent = [\n {\n label: 'Default status',\n rerult: (\n value.toLowerCase() === 'active',\n },\n {\n status: 'inactive',\n icon: WarningOutlined,\n text: 'Inactive',\n conditionCheck: (value) => value.toLowerCase() === 'inactive',\n },\n {\n status: 'pending',\n icon: ExclamationCircleOutlined,\n text: 'Pending',\n conditionCheck: (value) => value.toLowerCase() === 'pending',\n },\n ]}\n />\n ),\n },\n {\n label: 'Create thumbs',\n rerult: (\n value === true,\n },\n {\n status: 'inactive',\n icon: CloseSquareOutlined,\n text: 'No',\n conditionCheck: (value) => value === false,\n },\n ]}\n />\n ),\n },\n {\n label: 'Auto apply/replace on product',\n rerult: (\n value === true,\n },\n {\n status: 'inactive',\n icon: CloseSquareOutlined,\n text: 'No',\n conditionCheck: (value) => value === false,\n },\n ]}\n />\n ),\n },\n {\n label: 'Effective Date',\n rerult: (\n \n ),\n },\n {\n label: 'Expiration Date',\n rerult: (\n \n ),\n },\n ];\n\n const showCreateSubFolder = {\n label: 'Create subfolder',\n rerult: (\n value === true,\n },\n {\n status: 'inactive',\n icon: CloseSquareOutlined,\n text: 'No',\n conditionCheck: (value) => value === false,\n },\n ]}\n />\n ),\n };\n\n const folderName = folder?.folderName || folder?.description;\n\n const showDestinationFolder = {\n label: 'Destination folder',\n rerult: (\n value === true,\n },\n {\n status: 'inactive',\n icon: CloseSquareOutlined,\n text: 'No',\n conditionCheck: (value) => value === false,\n },\n ]}\n />\n ),\n };\n\n const addEntityToConfirmModal = ((content) => {\n const showList = cloneDeep(content);\n if (!isEnabledImportFolder) return showList;\n\n showList.splice(2, 0, showDestinationFolder);\n if (!isUploadFromLocal) showList.splice(2, 0, showCreateSubFolder);\n\n return showList;\n })(importConfirmContent);\n\n return (\n
\n
\n \n Please confirm your setting before uploading\n \n
\n {addEntityToConfirmModal.map((rowItem, idx) => {\n return (\n \n \n {rowItem.label}:\n \n {rowItem.rerult}\n \n );\n })}\n
\n );\n};\n\nexport default ConfirmContent;\n","import React, { useMemo } from 'react';\nimport { Row, Col, Typography } from 'antd';\nimport { ScheduleOutlined } from '@ant-design/icons';\nimport ConfirmResult from './ConfirmResult';\nimport { DATE_FORMAT } from 'static/Constants';\nimport moment from 'moment';\n\nconst { Text } = Typography;\n\nconst ConfirmContent = (props) => {\n const { effDate, expDate } = props;\n\n const dateFormat = useMemo(() => DATE_FORMAT.SYSTEM_FORMAT, []);\n\n const convertEffDate = useMemo(\n () => (effDate ? moment(effDate).format(dateFormat) : null),\n [effDate, dateFormat]\n );\n const convertExpDate = useMemo(\n () => (expDate ? moment(expDate).format(dateFormat) : null),\n [expDate, dateFormat]\n );\n\n const importConfirmContent = useMemo(\n () => [\n {\n label: 'Effective Date',\n rerult: (\n \n ),\n },\n {\n label: 'Expiration Date',\n rerult: (\n \n ),\n },\n ],\n [convertExpDate, convertEffDate]\n );\n\n return (\n
\n
\n \n Do you want to set effective date as a future date?\n \n
\n {importConfirmContent.map((rowItem) => {\n return (\n \n \n {rowItem.label}:\n \n {rowItem.rerult}\n \n );\n })}\n
\n );\n};\n\nexport default ConfirmContent;\n","import React, { useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport { FormAddButton, CustomNotification } from 'common/components';\n\nimport CreateFolderModal from 'pages/home/ribbon/components/controls/folders/CreateFolderModal';\nimport Messages from 'i18n/messages/folder';\n\nimport { useCheckAllowCreateFolder } from '../shared/hooks';\n\nconst AssetToFolderTool = (props) => {\n const { selectedItem, onCreateNewFolderSuccess } = props;\n\n const intl = useIntl();\n\n const createFolderModalVisibleHook = useState(false);\n\n const isAllowCreateFolder = useCheckAllowCreateFolder();\n\n const [, setCreateNewFolderModalVisible] = createFolderModalVisibleHook;\n\n const toggleCreateNewFolderModal = () => {\n setCreateNewFolderModalVisible((prev) => !prev);\n };\n\n const onReloadWhenSaveSuccess = () => {\n CustomNotification.success(\n intl.formatMessage(Messages.createFolderSuccess)\n );\n onCreateNewFolderSuccess(selectedItem);\n };\n\n return (\n
\n \n\n \n \n \n
\n );\n};\n\nexport default AssetToFolderTool;\n","import React from 'react';\n\nimport { Typography, Input, Tree, Checkbox, Row, Col } from 'antd';\n\nimport classnames from 'classnames';\n\nimport { WithLoading } from 'common/components';\nimport AssetToFolderTool from './AssetToFolderTool';\n\nimport './AssetToFolder.less';\n\nconst AssetToFolder = (props) => {\n const {\n loadingTree,\n subFolderParams = {},\n treeData,\n onSearch,\n onUpdateFolder,\n onToggleCreateSubfolder,\n selectedItem,\n onCreateNewFolderSuccess,\n ...rest\n } = props;\n\n const { isShow, isCreateSubfolder } = subFolderParams;\n\n return (\n
\n \n \n \n Destination Folder:\n \n \n \n \n \n\n {isShow && (\n \n {\n onToggleCreateSubfolder(event.target.checked);\n }}\n checked={isCreateSubfolder}\n >\n Create subfolders\n \n \n )}\n \n \n \n \n\n \n \n \n
\n \n
\n );\n};\n\nexport default AssetToFolder;\n","import React from 'react';\nimport { Row } from 'antd';\nimport './AssetAssociations.less';\nimport AgGrid from 'common/components/ag-grid/AgGrid';\nimport * as endpoints from 'services/digitalAsset/endpoints';\n\nconst AssetAssociations = (props) => {\n const { associationColumn, assetData } = props;\n return (\n \n \n \n );\n};\n\nAssetAssociations.propTypes = {};\n\nexport default AssetAssociations;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Checkbox } from 'antd';\nimport { formatMDY } from 'utils/formatDate';\nimport { injectIntl } from 'react-intl';\nimport './AssetCreator.less';\n\nconst AssetHeaderInformation = (props) => {\n const { loaded, modified, isShowcase, intl } = props;\n return (\n \n \n {intl.formatMessage({\n id: `Taco.digitalAsset.headerInformation.loaded`,\n })}\n \n \n {loaded && formatMDY(loaded)}\n \n \n {intl.formatMessage({\n id: `Taco.digitalAsset.headerInformation.modified`,\n })}\n \n \n {modified && formatMDY(modified)}\n \n {isShowcase && (\n <>\n \n {intl.formatMessage({\n id: `Taco.digitalAsset.headerInformation.showcased`,\n })}\n \n \n \n \n \n )}\n \n );\n};\n\nAssetHeaderInformation.propTypes = {\n loaded: PropTypes.string,\n modified: PropTypes.string,\n isShowcase: PropTypes.bool,\n};\n\nexport default injectIntl(AssetHeaderInformation);\n","import React, { useEffect, useState } from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\nimport PropTypes, { oneOfType } from 'prop-types';\nimport {\n Row,\n Col,\n Radio,\n Select,\n Button,\n notification,\n Tooltip,\n Typography,\n Divider,\n InputNumber,\n Checkbox,\n} from 'antd';\nimport { Form, TypePicker, ColorPicker } from 'common/components';\nimport { PlusOutlined } from '@ant-design/icons';\nimport {\n RESOLUTION_OPTIONS,\n CROP_SIZE_OPTIONS,\n IMAGE_SIZE_OPTIONS,\n BACKGROUND_OPTIONS,\n IMAGE_SIZE_OPTIONS_SINGLE_DIGIT,\n} from 'static/Constants';\nimport {\n downloadDigitalAsset,\n downloadDigitalAssetByEmail,\n} from 'services/digitalAsset';\nimport { dialogFunction, WrapperSelect } from 'common/components';\nimport DigitalRight from 'assets/DRM.png';\nimport { DIGITAL_ASSET_DOWNLOAD } from 'services/digitalAsset/endpoints';\nimport { setAssetType } from 'utils/fileType';\nimport { injectIntl } from 'react-intl';\nimport * as api from 'config/axios';\nimport { EmailSelection } from 'common/components';\nimport userSelectors from '@redux/user/selectors';\nimport * as companySelectors from 'pages/company-profile/controllers/selectors';\nimport * as memberActions from 'pages/company-profile/controllers/actions';\n\nimport * as _ from 'lodash';\n\nimport './AssetDownload.less';\n\nconst { Option } = Select;\nconst { Title } = Typography;\n\nconst formItemFormatLayout = { labelCol: { span: 24 } };\n\nconst formItemConfigLayout = {\n labelCol: { xxl: { span: 8 }, xl: { span: 9 } },\n wrapperCol: { xxl: { span: 15 }, xl: { span: 13 } },\n};\n\nconst addButtonStyle = {\n flex: 'none',\n padding: '8px',\n display: 'block',\n cursor: 'pointer',\n};\n\nconst customSetupStyle = {\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'nowrap',\n padding: 8,\n};\n\nconst AssetDownload = (props) => {\n const {\n assetId,\n metadata,\n downloadFormats: listFormatType,\n intl,\n drm,\n } = props;\n\n const dispatch = useDispatch();\n\n const alternativeEmail = useSelector(\n userSelectors.makeSelectUserAlternativeEmail()\n );\n\n const assetDownloadPreference = useSelector(\n userSelectors.makeSelectAssetDownloadPreference()\n );\n\n const primaryEmail = useSelector(userSelectors.makeSelectUserEmail());\n const [form] = Form.useForm();\n const [downloadType, setDownloadType] = useState('');\n const [visibleEmailSelection, setVisibleEmailSelection] = useState(false);\n const [resolutionOptions, setResolution] = useState(RESOLUTION_OPTIONS);\n const [cropSizeOptions, setCropSize] = useState(CROP_SIZE_OPTIONS);\n const [imageSizeOptions, setImageSize] = useState(IMAGE_SIZE_OPTIONS);\n const [backgroundOptions, setBackground] = useState(BACKGROUND_OPTIONS);\n const [customResolution, setCustomResolution] = useState('');\n const [customCropSize, setCustomCropSize] = useState('');\n const [customImageSize, setCustomImageSize] = useState('');\n const [allowAdding, setAllowAdding] = useState(true);\n const [downloadFormat, setDownloadFormat] = useState('');\n\n const downloadFormats = [\n ...new Set([...(listFormatType ?? []), metadata?.fileType?.toUpperCase()]),\n ].sort();\n\n const memberInfo = useSelector(companySelectors.selectMemberProfile());\n\n const userInfo = useSelector(userSelectors.makeSelectUserInfo());\n\n useEffect(() => {\n if (_.isEmpty(memberInfo)) {\n dispatch(memberActions.getMemberProfileHeader(userInfo?.member?.id));\n }\n }, [dispatch, userInfo?.member?.id]);\n\n const onOptionChange = (type, value) => {\n switch (type) {\n case 'resolution':\n setCustomResolution(value);\n\n break;\n case 'cropSize':\n setCustomCropSize(value);\n break;\n case 'imageSize':\n setCustomImageSize(value);\n break;\n default:\n break;\n }\n };\n\n const addResolutionItem = () => {\n if (!customResolution)\n openNotification(\n 'error',\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.resolution.customize',\n }),\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.resolution.missing',\n })\n );\n else if (resolutionOptions.includes(customResolution))\n openNotification(\n 'error',\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.resolution.customize',\n }),\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.resolution.duplicated',\n })\n );\n else setResolution([...resolutionOptions, customResolution]);\n };\n\n const addCropSizeItem = () => {\n if (!customCropSize)\n openNotification(\n 'error',\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.cropSize.customize',\n }),\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.cropSize.missing',\n })\n );\n else if (cropSizeOptions.includes(customCropSize))\n openNotification(\n 'error',\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.cropSize.customize',\n }),\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.cropSize.duplicated',\n })\n );\n else setCropSize([...cropSizeOptions, customCropSize]);\n };\n\n const confirmRender = (key) => {\n return (\n
\n {intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.imageSize.pixilation',\n })}\n
\n {\n notification.close(key);\n setImageSize([...imageSizeOptions, key]);\n setAllowAdding(true);\n }}\n >\n Continue\n \n {\n notification.close(key);\n setAllowAdding(true);\n }}\n >\n Cancel\n \n
\n
\n );\n };\n\n const addImageSizeItem = () => {\n if (!customImageSize)\n openNotification(\n 'error',\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.imageSize.customize',\n }),\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.imageSize.missing',\n })\n );\n else if (\n imageSizeOptions.includes(customImageSize) ||\n IMAGE_SIZE_OPTIONS_SINGLE_DIGIT.includes(customImageSize)\n )\n openNotification(\n 'error',\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.imageSize.customize',\n }),\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.imageSize.duplicated',\n })\n );\n else if (\n metadata?.width < customImageSize ||\n metadata?.height < customImageSize\n ) {\n openNotification(\n 'warning',\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.imageSize.customize.warning',\n }),\n confirmRender(customImageSize),\n customImageSize,\n () => setAllowAdding(true)\n );\n setAllowAdding(false);\n } else setImageSize([...imageSizeOptions, customImageSize]);\n };\n\n const addBackgroundItem = (color) => {\n if (!backgroundOptions.includes(color)) {\n setBackground([...backgroundOptions, color]);\n } else {\n openNotification(\n 'error',\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.background.customize',\n }),\n intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.background.duplicated',\n })\n );\n }\n };\n\n const openNotification = (result, message, description, key, close) => {\n let type;\n switch (result) {\n case true:\n type = 'success';\n break;\n case false:\n type = 'error';\n break;\n default:\n type = result;\n break;\n }\n type\n ? notification[type]({\n message: message,\n description: description,\n duration: type === 'warning' ? 0 : 4.5,\n key: key,\n onClose: close,\n })\n : notification.error({\n message: intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.notification.oops',\n }),\n description: intl.formatMessage({\n id: 'Taco.digitalAsset.assetDownload.notification.fail',\n }),\n duration: type === 'warning' ? 0 : 4.5,\n });\n };\n\n async function onAssetDownload(type) {\n setDownloadType(type);\n const paramsConfig = onConfigParams(type);\n if (type === 'direct') {\n await onAssetDownloadDirect(paramsConfig);\n } else if (type === 'ftp') {\n await onAssetDownloadFTP(paramsConfig);\n } else {\n await onAssetDownloadEmail(paramsConfig, primaryEmail);\n }\n setDownloadType('');\n }\n\n const onConfigParams = (type) => {\n const formData = form.getFieldsValue();\n return {\n AssetId: assetId,\n Resolution: formData.resolution,\n ImageSize: formData.imageSize,\n CropSize: formData.cropSize,\n Background: formData.background,\n DownloadFormat: formData.format,\n DownloadMethod: type,\n square: formData.square,\n };\n };\n\n const onAssetDownloadDirect = async (params) => {\n await api\n .requestToDownload({\n method: 'POST',\n apiEndpoint: DIGITAL_ASSET_DOWNLOAD,\n payload: params,\n })\n .then((response) => {\n openNotification(\n response?.isSuccess,\n 'Direct Download',\n response?.message || 'Something went wrong! Please try again'\n );\n });\n };\n\n function handleDownload(type) {\n dialogFunction({\n type: 'warn',\n content: (\n
\n \n {intl.formatMessage({\n id: `Taco.home.ribbon.dialogDeleteDRMsingle`,\n })}\n
\n ),\n\n okText: 'Cancel',\n onCancel: () => {\n if (type === 'direct') {\n onAssetDownload('direct');\n } else if (type === 'email') {\n setFuncForSendEmail();\n } else onAssetDownload('ftp');\n },\n cancelText: 'Download',\n });\n }\n\n const onAssetDownloadFTP = async (params) => {\n await downloadDigitalAsset(params).then((response) => {\n openNotification(response?.isSuccess, 'FTP Download', response?.message);\n });\n };\n\n const onAssetDownloadEmail = async (params, emails) => {\n let submitEmails = Array.isArray(emails) ? emails : [emails];\n await downloadDigitalAssetByEmail({ ...params, Emails: submitEmails }).then(\n (response) => {\n openNotification(\n response?.isSuccess,\n 'Email Download',\n response?.message\n );\n }\n );\n };\n\n const onSendMultiEmail = async (emails) => {\n setDownloadType('email');\n const paramsConfig = onConfigParams('email');\n setVisibleEmailSelection(false);\n await onAssetDownloadEmail(paramsConfig, emails);\n setDownloadType('');\n };\n\n const setFuncForSendEmail = () => {\n if (alternativeEmail && alternativeEmail.length > 0) {\n setVisibleEmailSelection(true);\n } else {\n onAssetDownload('email'); // default sending for primary email if alter email is empty\n }\n };\n\n const setDefaultValuesDownloadForm = () => {\n let background = null;\n let cropSize = null;\n const defaultDownloadFormat = assetDownloadPreference?.downloadFormat;\n\n const format = downloadFormats?.includes(\n defaultDownloadFormat?.toUpperCase()\n )\n ? defaultDownloadFormat\n : metadata?.fileType?.toLowerCase();\n\n if (metadata?.clippingPath) {\n background = assetDownloadPreference?.background\n ? assetDownloadPreference?.background\n : 'Original';\n cropSize = assetDownloadPreference?.cropSize;\n } else {\n background = 'Original';\n }\n\n const mappingAssetDownloadPreference = {\n ...assetDownloadPreference,\n format,\n background,\n cropSize,\n resolution: assetDownloadPreference?.resolution ?? null,\n };\n form.setFieldsValue(mappingAssetDownloadPreference);\n };\n\n useEffect(() => {\n setDefaultValuesDownloadForm();\n setDownloadFormat(metadata?.fileType);\n }, [metadata]);\n\n const imageSizeCustomRender = (value) => {\n if (IMAGE_SIZE_OPTIONS.includes(value)) return value;\n else return `${value}x${value}`;\n };\n\n const checkDisableImageSize = (value) => {\n // If value == Full-size\n if (value === IMAGE_SIZE_OPTIONS[IMAGE_SIZE_OPTIONS.length - 1])\n return false;\n\n const size = typeof value === 'string' ? value?.split('x')[0] : value;\n\n if (+size > +metadata?.width && +size > +metadata?.height) {\n return true;\n }\n\n return false;\n };\n\n const renderResolutionNameByNumber = (number) => {\n switch (number) {\n case 72:\n return 'DPI - Low Resolution';\n\n case 300:\n return 'DPI - High Resolution';\n\n default:\n break;\n }\n };\n\n return (\n \n \n \n \n {intl.formatMessage({\n id: `Taco.digitalAsset.assetDownload.step1`,\n })}\n \n \n \n \n \n {downloadFormats?.length > 0 &&\n [...downloadFormats]?.map((option) => {\n return (\n \n {\n setDownloadFormat(e?.target?.value);\n }}\n >\n \n \n \n );\n })}\n \n \n \n \n\n {setAssetType(metadata?.fileType) === 'Image' && (\n \n \n \n {intl.formatMessage({\n id: `Taco.digitalAsset.assetDownload.step2`,\n })}\n \n \n \n \n document.getElementById('form-id')}\n >\n {resolutionOptions.map((option, index) => {\n return (\n \n );\n })}\n \n \n \n \n \n \n {/* crop size input */}\n document.getElementById('form-id')}\n disabled={!metadata?.clippingPath}\n >\n {cropSizeOptions.map((option, index) => {\n return (\n \n );\n })}\n \n \n \n \n \n \n document.getElementById('form-id')}\n dropdownRender={(menu) => (\n
\n {menu}\n \n
\n
\n onOptionChange('imageSize', e)}\n />\n
\n \n \n \n
\n
\n )}\n >\n {imageSizeOptions.map((option, index) => {\n return (\n \n {imageSizeCustomRender(option)}\n \n );\n })}\n \n \n \n \n \n \n document.getElementById('form-id')}\n dropdownRender={(menu) => (\n
\n {menu}\n \n
\n \n
\n
\n )}\n disabled={!metadata?.clippingPath}\n >\n {backgroundOptions.map((option, index) => {\n return (\n \n {option}\n \n );\n })}\n \n \n \n \n \n \n \n \n \n
\n )}\n \n \n {setAssetType(metadata?.fileType) === 'Image' ? (\n \n {intl.formatMessage({\n id: `Taco.digitalAsset.assetDownload.step3`,\n })}\n \n ) : (\n \n {intl.formatMessage({\n id: `Taco.digitalAsset.assetDownload.step2method`,\n })}\n \n )}\n \n \n \n \n \n document.getElementById('download-method')\n }\n title={intl.formatMessage({\n id: `Taco.digitalAsset.assetDownload.downloadMethod.direct`,\n })}\n >\n
\n \n drm ? handleDownload('direct') : onAssetDownload('direct')\n }\n disabled={['email', 'ftp'].includes(downloadType)}\n value='direct'\n >\n \n \n
\n \n \n document.getElementById('download-method')\n }\n title={intl.formatMessage({\n id: `Taco.digitalAsset.assetDownload.downloadMethod.email`,\n })}\n >\n
\n \n drm ? handleDownload('email') : setFuncForSendEmail()\n }\n value='email'\n >\n \n \n setVisibleEmailSelection(false)}\n visible={visibleEmailSelection}\n onSendEmail={onSendMultiEmail}\n primaryEmail={primaryEmail}\n alternativeEmail={alternativeEmail}\n >\n
\n \n {memberInfo?.ftpEnabled && (\n \n document.getElementById('download-method')\n }\n title={intl.formatMessage({\n id: `Taco.digitalAsset.assetDownload.downloadMethod.ftp`,\n })}\n >\n
\n \n drm ? handleDownload('ftp') : onAssetDownload('ftp')\n }\n disabled={['direct', 'email'].includes(downloadType)}\n value='ftp'\n >\n \n \n
\n \n )}\n
\n
\n \n
\n \n );\n};\n\nAssetDownload.propTypes = {\n assetId: oneOfType([PropTypes.number, PropTypes.string]),\n metadata: PropTypes.object,\n downloadFormats: oneOfType([PropTypes.array, PropTypes.object]),\n};\n\nexport default injectIntl(AssetDownload);\n","import React from 'react';\nimport { LabelValueWrapper } from 'common/components';\nimport { Row, Col } from 'antd';\n\nimport { FACING, ANGLE, PACKAGING_DISPOSITION } from 'static/Constants';\n\nconst AssetType = (props) => {\n const {\n assetType,\n assetSubType,\n packageLevel,\n packagingDisposition,\n angle,\n facing,\n language,\n panelType,\n logoType,\n certificateType,\n documentType,\n } = props;\n\n let objectData = { assetType, assetSubType };\n\n const getFieldLabel = ({ constant, value }) => {\n return constant.find((constItem) => {\n return constItem.value?.toLowerCase() === value?.toLowerCase();\n })?.label;\n };\n\n if (assetSubType === 'Planogram') {\n objectData = {\n ...objectData,\n packageLevel,\n packagingDisposition: getFieldLabel({\n constant: PACKAGING_DISPOSITION,\n value: packagingDisposition,\n }),\n angle: getFieldLabel({ constant: ANGLE, value: angle }),\n facing: getFieldLabel({ constant: FACING, value: facing }),\n language,\n };\n } else if (assetSubType === 'Panel') {\n objectData = {\n ...objectData,\n panelType,\n };\n } else if (assetSubType === 'Logo') {\n objectData = {\n ...objectData,\n logoType,\n };\n } else if (assetSubType === 'Certificate') {\n objectData = {\n ...objectData,\n certificateType,\n };\n } else if (assetSubType === 'Company') {\n objectData = {\n ...objectData,\n documentType,\n };\n }\n\n return (\n <>\n
\n \n \n \n \n \n
\n \n );\n};\n\nexport default AssetType;\n","import React, { useState, useEffect } from 'react';\nimport { useSelector } from 'react-redux';\nimport { Select, Row } from 'antd';\nimport * as Const from 'static/Constants';\nimport { FormattedMessage, injectIntl } from 'react-intl';\nimport messages from 'i18n/messages/assetDetail';\nimport {\n Form,\n FormSaveButton,\n FormCancelButton,\n WrapperSelect,\n FlagCountrySelectionFieldInput,\n} from 'common/components';\nimport { DownOutlined } from '@ant-design/icons';\nimport './style.less';\nimport * as assetSelectors from 'pages/branded-assets/controllers/selectors';\n\nconst AssetEdit = (props) => {\n const { onSubmit, onCancel, typeData } = props;\n const [form] = Form.useForm();\n const [type, setType] = useState(typeData?.assetType);\n const [subType, setSubType] = useState(typeData?.assetSubType);\n const { Option } = Select;\n const initialForm = {\n assetType: null,\n assetSubType: null,\n packageLevel: null,\n packagingDisposition: null,\n angle: null,\n facing: null,\n language: null,\n panelType: null,\n logoType: null,\n certificateType: null,\n documentType: null,\n };\n\n const assetLoading = useSelector(assetSelectors.selectEditTypeLoading());\n\n const getCodeByCountry = (values) => {\n return Object.keys(customLabels).find(\n (key) => customLabels[key] === values\n );\n };\n const enableCountry = [\n 'US',\n 'FR',\n 'ES',\n 'PT',\n 'DE',\n 'IN',\n 'IT',\n 'RU',\n 'IR',\n 'CN',\n ];\n const customLabels = {\n US: 'English',\n FR: 'French',\n ES: 'Spanish',\n PT: 'Portuguese',\n DE: 'German',\n IN: 'Hindil',\n IT: 'Italian',\n RU: 'Russian',\n IR: 'Persian',\n CN: 'Chinese',\n };\n\n useEffect(() => {\n form.setFieldsValue(typeData);\n setType(typeData?.assetType);\n setSubType(typeData?.assetSubType);\n }, [typeData]);\n\n return (\n <>\n onSubmit(value)}\n >\n
\n \n form.submit()}\n />\n {\n form.setFieldsValue(initialForm);\n setType(null);\n setSubType(null);\n onCancel();\n }}\n />\n \n
\n \n {\n setType(value);\n setSubType(null);\n form.setFieldsValue({ ...initialForm, assetType: value });\n }}\n >\n {Const.ASSET_TYPE?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n );\n })}\n \n \n {type && (\n \n {\n setSubType(value);\n form.setFieldsValue({\n ...initialForm,\n assetSubType: value,\n assetType: type,\n });\n }}\n >\n {type === 'Asset'\n ? Const.ASSET_SUBTYPE?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n );\n })\n : type === 'Company'\n ? Const.COMPANY_SUBTYPE.sort().map((item, index) => {\n return (\n \n );\n })\n : type === 'Document'\n ? Const.DOCUMENT_SUBTYPE.sort().map((item, index) => {\n return (\n \n );\n })\n : type === 'Multimedia'\n ? Const.MULTIMEDIA_SUBTYPE.sort().map((item, index) => {\n return (\n \n );\n })\n : null}\n \n \n )}\n\n {subType === 'Planogram' ? (\n <>\n }\n >\n \n document.getElementById('asset-type-form')\n }\n >\n {Const.PACKAGE_LEVEL?.map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n }\n >\n \n document.getElementById('asset-type-form')\n }\n >\n {Const.PACKAGING_DISPOSITION?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n }\n >\n \n document.getElementById('asset-type-form')\n }\n >\n {Const.ANGLE?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n }\n >\n \n document.getElementById('asset-type-form')\n }\n >\n {Const.FACING?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n }\n >\n {/* \n document.getElementById('asset-type-form')\n }>\n {Const.LANGUAGE_LIST.map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n */}\n\n {\n form.setFieldsValue({\n ...form.getFieldValue(),\n language: customLabels[value],\n });\n }}\n />\n \n \n \n ) : subType === 'Panel' ? (\n <>\n \n \n document.getElementById('asset-type-form')\n }\n >\n {Const.ASSET_PANEL_FIELD?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n \n ) : subType === 'Logo' ? (\n \n \n document.getElementById('asset-type-form')\n }\n >\n {Const.COMPANY_LOGO_FIELD?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n ) : subType === 'Certificate' ? (\n \n \n document.getElementById('asset-type-form')\n }\n >\n {Const.DOCUMENT_CERTIFICATE_FIELD?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n ) : subType === 'Company' ? (\n \n \n document.getElementById('asset-type-form')\n }\n >\n {Const.DOCUMENT_COMPANY_FIELD?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n ) : null}\n \n \n );\n};\n\nexport default injectIntl(AssetEdit);\n","import React, { useState } from 'react';\nimport { Tooltip, Button } from 'antd';\nimport { EditOutlined } from '@ant-design/icons';\nimport { injectIntl } from 'react-intl';\nimport './style.less';\nimport AssetType from './AssetType';\nimport AssetEdit from './AssetEdit';\n\nconst AssetTypeEdit = (props) => {\n const { onSubmit, typeData, canEdit } = props;\n const [isEdit, setIsEdit] = useState(false);\n\n return (\n <>\n
\n {isEdit ? (\n setIsEdit(false)}\n typeData={typeData}\n />\n ) : (\n <>\n {canEdit && (\n \n }\n type='link'\n onClick={() => setIsEdit(true)}\n />\n \n )}\n\n \n \n )}\n
\n \n );\n};\n\nexport default injectIntl(AssetTypeEdit);\n","import React, { useState } from 'react';\nimport { useSelector } from 'react-redux';\n\nimport {\n Space,\n Collapse,\n Row,\n Col,\n Input,\n InputNumber,\n Checkbox,\n DatePicker,\n Tooltip,\n} from 'antd';\nimport { InfoCircleOutlined } from '@ant-design/icons';\n\nimport {\n Form,\n InfoWithLabel,\n FormSaveButton,\n FormCancelButton,\n EditButton,\n TextTooltip,\n} from 'common/components';\n\nimport userSelectors from '@redux/user/selectors';\n\nimport * as digitalAssetServices from 'services/digitalAsset';\nimport {\n parseToString,\n parseToNumber,\n parseToBoolean,\n parseToDate,\n parseToDateObject,\n} from 'utils/parser';\nimport { apiHandler } from 'utils/api';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/asset-full-view';\n\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\n\nimport { OPEN_ITEM_CLASS } from 'static/Constants';\n\nimport {\n useCheckPermissions,\n useCheckAllowEditAssets,\n useCheckIsSuperAdmin,\n} from 'hooks';\n\nimport classnames from 'classnames';\nimport './MemberDefinedPropertiesPanel.less';\n\nconst { Panel } = Collapse;\n\nconst MemberDefinedPropertiesPanel = (props) => {\n const {\n assetId,\n memberDefinedProperties,\n isEditable,\n isActive,\n isOwner,\n isHiddenEditSection = false,\n } = props;\n\n const [form] = Form.useForm();\n const intl = useIntl();\n const reloadPage = useDispatchReloadPage();\n\n const configData = useSelector(\n userSelectors.makeSelectUserDefinedProperties()\n );\n\n const { isSuperMember } = useSelector(userSelectors.makeSelectUserInfo());\n const isSuperAdmin = useCheckIsSuperAdmin();\n\n const [isNoRenderData, setNoRenderData] = useState(false);\n const [isEditMode, setEditMode] = useState(false);\n const [btnLoading, setBtnLoading] = useState(false);\n\n const valueData = memberDefinedProperties;\n const hasMemberDefinedProperties = Boolean(valueData?.length);\n\n const hiddenMemberDefinedProperties =\n (isSuperMember && !isOwner && !hasMemberDefinedProperties) ||\n (isSuperAdmin && !isOwner && !hasMemberDefinedProperties) ||\n (!isOwner && !hasMemberDefinedProperties);\n\n const hasPermissionMemberDefinedProperties = useCheckPermissions([\n { action: ABILITY_ACTION.EDIT, subject: ABILITY_SUBJECT.ASSET },\n { action: ABILITY_ACTION.DELETE, subject: ABILITY_SUBJECT.ASSET },\n ]);\n\n const { checkAllowEditAssetFull } = useCheckAllowEditAssets();\n const isAllowEdit = checkAllowEditAssetFull();\n\n const allowEditMemberDefinedProperties =\n hasPermissionMemberDefinedProperties || isAllowEdit;\n\n const mapValueWithConfig = () => {\n if (isSuperAdmin && !isOwner) {\n return (\n !!valueData?.length &&\n valueData.map((propertyValue) => {\n return {\n ...propertyValue,\n fieldType: propertyValue?.fieldType,\n };\n })\n );\n }\n\n return (\n !!valueData?.length &&\n valueData.map((propertyValue) => {\n const matchedPropertyConfig = configData.find(\n (propertyConfig) =>\n propertyConfig.fieldName === propertyValue.fieldName\n );\n\n return {\n ...propertyValue,\n fieldType: matchedPropertyConfig?.fieldType,\n };\n })\n );\n };\n\n const mapConfigWithValue = () => {\n if (isSuperAdmin && !isOwner) {\n return (\n !!valueData?.length &&\n valueData.map((propertyValue) => {\n return {\n ...propertyValue,\n value: propertyValue?.value,\n };\n })\n );\n }\n\n return (\n !!configData?.length &&\n configData.map((propertyConfig) => {\n const matchedPropertyValue = valueData.find(\n (propertyValue) =>\n propertyConfig.fieldName === propertyValue.fieldName\n );\n\n return {\n ...propertyConfig,\n value: matchedPropertyValue?.value,\n };\n })\n );\n };\n\n const mapConfigWithFormValue = (value) => {\n const formKeyArray = Object.keys(value);\n\n if (isSuperAdmin && !isOwner) {\n return formKeyArray.map((propertyKey) => {\n const matchedPropertyConfig = valueData.find(\n (propertyConfig) => propertyConfig.fieldName === propertyKey\n );\n\n return {\n ...matchedPropertyConfig,\n value: value[propertyKey],\n };\n });\n }\n\n return formKeyArray.map((propertyKey) => {\n const matchedPropertyConfig = configData.find(\n (propertyConfig) => propertyConfig.fieldName === propertyKey\n );\n\n return {\n ...matchedPropertyConfig,\n value: value[propertyKey],\n };\n });\n };\n\n const generateRenderProperties = () => {\n const mappedProperties = mapValueWithConfig();\n\n return (\n !!mappedProperties?.length &&\n mappedProperties?.reduce((renderProperties, property) => {\n const wrongFieldTypeNotice = renderWrongFiledTypeNotice(property);\n const { fieldType, value } = property;\n //* if fieldType === undefined ==> this property has been removed\n if (fieldType && value) {\n renderProperties.push({\n label: property.fieldName,\n info: parseValue({ property }),\n infoAppend: wrongFieldTypeNotice,\n });\n }\n return renderProperties;\n }, [])\n );\n };\n\n const parseValue = ({ property, toDateObject }) => {\n const { value, fieldType } = property;\n\n const parser = {\n string: parseToString,\n numeric: parseToNumber,\n boolean: parseToBoolean,\n date: toDateObject ? parseToDateObject : parseToDate,\n };\n\n return parser[fieldType] ? parser[fieldType](value) : value;\n };\n\n const onEditClick = () => {\n setEditMode(true);\n };\n\n const onCancelClick = () => {\n setEditMode(false);\n };\n\n const onSaveClick = () => {\n form.validateFields().then((value) => {\n callApiEditMemberDefinedProperties(value);\n });\n };\n\n const callApiEditMemberDefinedProperties = (value) => {\n setBtnLoading(true);\n\n const memberDefinedProperties = mapConfigWithFormValue(value);\n\n const params = {\n digitalAssetId: assetId,\n memberDefinedProperties,\n };\n const successMessage = intl.formatMessage(\n Messages.editMemberDefinedPropertiesValueSuccess\n );\n const errorMessage = intl.formatMessage(\n Messages.editMemberDefinedPropertiesValueError\n );\n\n apiHandler({\n service: digitalAssetServices.editMemberDefinedPropertiesValue,\n params,\n successMessage,\n errorMessage,\n successCallback: editSuccessCallback,\n onFinally: hideBtnLoading,\n });\n };\n\n const editSuccessCallback = () => {\n reloadPage();\n };\n\n const hideBtnLoading = () => {\n setBtnLoading(false);\n };\n\n const setFormInitialValue = () => {\n const mappedProperties = mapConfigWithValue();\n\n const formValue =\n mappedProperties &&\n mappedProperties?.reduce((accumulator, propertyConfig) => {\n //* get field value from memberDefinedProperties\n accumulator[propertyConfig.fieldName] = propertyConfig.value\n ? parseValue({\n property: propertyConfig,\n toDateObject: true,\n })\n : null;\n\n return accumulator;\n }, {});\n\n return formValue;\n };\n\n //* render\n const renderViewMode = () => {\n const renderData = generateRenderProperties();\n\n if (!renderData?.length && !isNoRenderData) {\n setNoRenderData(true);\n return;\n }\n\n return (\n !!renderData &&\n renderData.map((item, index) => {\n return (\n item.info !== null && (\n \n )\n );\n })\n );\n };\n\n const renderEditMode = () => {\n const layout = { labelCol: { span: 8 }, wrapperCol: { span: 12 } };\n\n let newConfigData =\n isSuperAdmin && !isOwner ? memberDefinedProperties : configData;\n\n // TODO: Maybe bad data fieldName is null\n // newConfigData = newConfigData.filter((config) => Boolean(config.fieldName));\n\n return (\n \n {newConfigData?.map((property) => {\n return renderFormField(property);\n })}\n \n );\n };\n\n const renderFormField = (property) => {\n const { fieldType, fieldName } = property;\n const isCheckBox = fieldType === 'boolean';\n const inputs = {\n string: Input,\n numeric: InputNumber,\n boolean: Checkbox,\n date: DatePicker,\n };\n const FieldComponent = inputs[fieldType] ?? null;\n\n const formItemProps = {\n label: ,\n name: fieldName,\n key: fieldName,\n };\n\n if (isCheckBox) formItemProps.valuePropName = 'checked';\n\n return (\n \n \n \n );\n };\n\n const renderMemberDefinedPropertiesActions = () => {\n return isEditMode ? (\n \n \n \n \n \n \n ) : (\n allowEditMemberDefinedProperties && (\n \n )\n );\n };\n\n const renderWrongFiledTypeNotice = (property) => {\n const { fieldType, value } = property;\n\n const isBooleanType = fieldType === 'boolean';\n const isBooleanValue = value === 'true' || value === 'false';\n const shouldShow = isBooleanType && !isBooleanValue;\n\n const noticeText = intl.formatMessage(\n Messages.memberDefinedPropertiesWrongFiledTypeNoticeText,\n { value }\n );\n\n return (\n shouldShow && (\n \n \n \n )\n );\n };\n\n const viewable = !!valueData && !isNoRenderData && isActive;\n const isOwnerEditable = isEditable && isAllowEdit;\n\n const shouldShowCollapse =\n !hiddenMemberDefinedProperties && (viewable || isOwnerEditable);\n\n return shouldShowCollapse ? (\n \n \n {!isHiddenEditSection && renderMemberDefinedPropertiesActions()}\n \n \n {isEditMode ? renderEditMode() : renderViewMode()}\n \n \n \n \n ) : null;\n};\n\nexport default MemberDefinedPropertiesPanel;\n","import React from 'react';\n\nimport { Row, Col, Form, Typography, Empty } from 'antd';\n\nimport { SearchEntityBtn, FormCancelButton } from 'common/components';\n\nimport {\n ArrowRightOutlined,\n CloseOutlined,\n CloseCircleFilled,\n} from '@ant-design/icons';\n\nimport * as productEndpoints from 'services/product/endpoints';\n\nimport ThumbnailItem from 'common/components/thumb/ThumbnailItem';\n\nimport './SearchProductForm.less';\n\nconst { Text } = Typography;\n\nconst tagTextStyle = { maxWidth: '100%', display: 'block', color: 'white' };\n\nconst SearchProductForm = (props) => {\n const {\n assetId,\n getSelectedProduct,\n selectedProduct,\n refSelectGridItem,\n setSelectedProduct,\n handleMoveToLinkAsset,\n isMultipleSelection,\n } = props;\n\n const defaultProductParams = {\n digitalAssetId: assetId,\n filters: [],\n pageIndex: 1,\n pageSize: 20,\n search: { searchText: '' },\n sort: [{ fieldName: 'id', isAscending: false }],\n };\n\n const handleRemoveTag = (itemData) => {\n refSelectGridItem?.current?.removeItem(itemData);\n };\n\n const handleRemoveProduct = (itemData) => {\n setSelectedProduct((prev) => {\n return prev?.filter((product) => product?.id !== itemData?.id);\n });\n\n handleRemoveTag(itemData);\n };\n\n return (\n
\n \n \n \n {\n return (\n
\n handleRemoveTag(itemData)}\n >\n \n
\n
\n
\n \n Product Name: {itemData?.productName}\n \n \n GTIN: {itemData?.gtin || 'N/A'}\n \n \n UPC12: {itemData?.upc12 || 'N/A'}\n \n
\n
\n
\n );\n }}\n onOk={getSelectedProduct}\n onCancel={getSelectedProduct}\n savedSelected\n isMultiple={isMultipleSelection}\n mapSearch={(searchText) => ({ search: { searchText } })}\n />\n \n \n \n \n \n {selectedProduct?.length > 0 ? (\n
\n {selectedProduct.map((item) => (\n \n {\n e.stopPropagation();\n handleRemoveProduct(item);\n }}\n >\n \n
\n
\n \n
\n \n ))}\n
\n ) : (\n
\n \n
\n )}\n \n \n \n \n \n }\n text='Move to link step'\n disabled={selectedProduct?.length <= 0}\n onClick={handleMoveToLinkAsset}\n />\n \n \n \n );\n};\n\nexport default SearchProductForm;\n","import React, { useState, useRef } from 'react';\nimport PropTypes from 'prop-types';\nimport { useParams } from 'react-router-dom';\n\n//? COMPONENT\nimport { Row, Col, Steps } from 'antd';\nimport { StyledModal, StepForm } from 'common/components';\nimport AssetGS1Edit from 'pages/asset-full-view/components/add-link-product/AssetGS1Edit';\nimport SearchProductForm from './SearchProductForm';\n\n//? REDUX\n// import * as productFullViewSelectors from 'pages/product-full-view/controllers/selectors';\n\n//? UTILS\nimport { PIM_ASSET_TYPE_DEFINE } from 'static/Constants';\n\nimport classnames from 'classnames';\n\nimport './LinkAssetToPimModal.less';\n\nconst currentStepDefine = [0, 1];\nconst stepDefault = currentStepDefine[0];\n\nconst { Step } = Steps;\n\nconst LinkAssetToPimModal = (props) => {\n const {\n gs1ImageData,\n addType,\n onCloseModal,\n assetId,\n isAssetImport,\n isAssetImportEdit,\n assetData,\n selectedEditLink,\n onReloadPage,\n } = props;\n\n const [currentStep, setCurrentStep] = useState(stepDefault);\n const [selectedProduct, setSelectedProduct] = useState([]);\n\n const [PLANO] = PIM_ASSET_TYPE_DEFINE;\n\n const refSelectGridItem = useRef();\n\n const { id } = useParams();\n\n const handleBackToCreateAsset = () => setCurrentStep(0);\n\n const handleMoveToLinkAsset = () => setCurrentStep(1);\n\n const getSelectedProduct = (itemList) => {\n refSelectGridItem.current.closeModal();\n setSelectedProduct(itemList);\n };\n\n /**\n * ? Duy Nguyen - 12/22/2021\n * * we will need to convert this into an array when support link multiple product\n */\n const selectedProductInfo = selectedProduct?.[0];\n\n //!- RENDER\n const stepDefine = !isAssetImportEdit\n ? [\n {\n step: 0,\n component: (\n \n ),\n },\n {\n step: 1,\n component: (\n
\n {\n onReloadPage && onReloadPage();\n onCloseModal && onCloseModal();\n }}\n isLinkMultiple\n selectedProduct={selectedProduct}\n />\n
\n ),\n },\n ]\n : [\n {\n step: 0,\n component: (\n
\n {\n onReloadPage && onReloadPage();\n onCloseModal && onCloseModal();\n }}\n addType='unknown'\n assetData={assetData}\n isAssetImportEdit={isAssetImportEdit}\n isAssetImport={isAssetImport}\n linkInfo={selectedEditLink}\n associationTypeDisabledOnEdit\n />\n
\n ),\n },\n ];\n\n const onlyShowAssetGs1Edit = isAssetImportEdit;\n\n return (\n setCurrentStep((prev) => prev + 1)}\n maskClosable={false}\n footer={null}\n centered\n visible\n destroyOnClose\n width='540px'\n bodyStyle={{ height: 460 }}\n >\n {!onlyShowAssetGs1Edit && (\n \n \n \n \n \n \n \n \n )}\n \n \n \n \n \n \n );\n};\n\nLinkAssetToPimModal.propTypes = {\n addType: PropTypes.string,\n onCloseModal: PropTypes.func,\n getImagery: PropTypes.func,\n};\n\nexport default LinkAssetToPimModal;\n","import React, { useState } from 'react';\n\nimport {\n Row,\n Col,\n Collapse,\n notification,\n Typography,\n Button,\n Space,\n} from 'antd';\n\nimport {\n LabelValueWrapper,\n dialogFunction,\n WithAbsoluteContainer,\n FormAddButton,\n} from 'common/components';\n\nimport LinkAssetToPimModal from './LinkAssetToPimModal';\n\nimport { EditOutlined, CloseOutlined } from '@ant-design/icons';\n\nimport { injectIntl } from 'react-intl';\n\nimport * as constants from 'static/Constants';\nimport { unlinkAssetToPIM } from 'services/digitalAsset';\n\nimport './AssetGS1Preview.less';\nimport { sleep } from 'utils/delay';\n\nconst { Panel } = Collapse;\n\nconst { Text } = Typography;\n\nconst AssetGS1Preview = (props) => {\n const { activeGS1, canEdit, gs1ImageData, assetId, onReloadPage, assetData } =\n props;\n\n const isShowCreateLink = canEdit && !assetData?.forMemberDocument; // because member document will not link to product\n\n const [selectedEditLink, setSelectedEditLink] = useState(null);\n\n const openNotification = (result, message) => {\n notification[result ? result : 'error']({ message: message });\n };\n\n const gs1Header = (obj) => {\n return (\n
\n \n \n {obj?.packageLevel}\n \n \n GTIN - {obj?.gtin || 'N/A'}\n \n \n {obj?.associateType || 'N/A'}\n \n \n {obj?.compliantFileName && (\n \n \n {obj?.compliantFileName}\n \n \n )}\n
\n );\n };\n\n const gs1Filter = (obj) => {\n const newObj = Object.create(Object.getPrototypeOf(obj));\n\n newObj.associationType = obj?.associateType;\n newObj.packageLevel = obj?.packageLevel;\n\n if (newObj.associationType === constants.ASSOCIATION_TYPE.DOCUMENT) {\n newObj.subtype = obj?.subtype;\n }\n\n //* if association type is PLANOGRAM or MARKETING image type field will be shown\n if (\n newObj.associationType === constants.ASSOCIATION_TYPE.PLANOGRAM &&\n newObj.associationType === constants.ASSOCIATION_TYPE.MARKETING\n ) {\n newObj.imageType = constants.IMAGE_TYPE.filter(\n (item) => item.value === obj?.imageType\n )[0]?.label;\n }\n\n //* if association type is PLANOGRAM, we should include these fields in preview\n if (newObj.associationType === constants.ASSOCIATION_TYPE.PLANOGRAM) {\n newObj.compliantFileName = obj?.compliantFileName;\n\n newObj.packagingDisposition = constants.PACKAGING_DISPOSITION.filter(\n (item) => item.value === obj?.packagingDisposition\n )[0]?.label;\n newObj.angle = constants.ANGLE.filter(\n (item) => item.value === obj?.angle\n )[0]?.label;\n newObj.facing = constants.FACING.filter(\n (item) => item.value === obj?.facing\n )[0]?.label;\n }\n newObj.gtin = obj?.gtin;\n\n return newObj;\n };\n\n const removeGS1 = async (item) => {\n const associationType = item?.associateType;\n const params =\n associationType === 'DOCUMENT'\n ? {\n linkId: item.id,\n }\n : {\n productImageLinkId: item.id,\n };\n\n const response = await unlinkAssetToPIM(params, associationType);\n\n //* BE dose not update link data instantly\n await sleep(1000);\n\n if (response.isSuccess) {\n openNotification('success', 'Remove link data successfully!');\n onReloadPage && onReloadPage();\n } else openNotification('error', 'Remove link data failed!');\n };\n\n const handleClickEditLink = (item) => {\n setSelectedEditLink(item);\n };\n\n const handleClickAddNewLink = () => setSelectedEditLink('new');\n\n const handleClickUnlink = (item) => {\n dialogFunction({\n type: 'warn',\n content: 'Do you want to remove this item?',\n okText: 'Ok',\n cancelText: 'Cancel',\n onOk: async () => {\n await removeGS1(item);\n },\n });\n };\n\n const handleCloseLinkAssetModal = () => {\n setSelectedEditLink(null);\n };\n\n if (!activeGS1) return null;\n\n return (\n \n \n \n 1\n ? []\n : activeGS1?.length !== 0 && activeGS1[0]?.id\n }\n >\n {activeGS1?.map((item) => {\n return (\n \n \n \n \n \n {canEdit && (\n \n \n }\n type='primary'\n style={{ borderRadius: 4 }}\n onClick={() => handleClickEditLink(item)}\n />\n }\n type='primary'\n danger\n style={{ borderRadius: 4 }}\n onClick={() => handleClickUnlink(item)}\n />\n \n \n )}\n \n \n );\n })}\n \n \n \n {selectedEditLink && (\n \n )}\n\n {isShowCreateLink && (\n \n )}\n \n \n );\n};\n\nexport default injectIntl(AssetGS1Preview);\n","import React from 'react';\nimport { Input, DatePicker, Spin } from 'antd';\n\nimport { Form } from 'common/components';\nimport { OPEN_ITEM_CLASS } from 'static/Constants';\n\nimport * as constants from 'static/Constants';\n\nimport classnames from 'classnames';\n\nconst { RangePicker } = DatePicker;\n\nconst AddDRMForm = (props) => {\n const { form, handleAddDRM, loading } = props;\n return (\n <>\n \n handleAddDRM(value)}\n >\n \n \n \n \n \n \n \n \n \n );\n};\n\nexport default AddDRMForm;\n","export const DOCUMENT_METADATA = {\n filetypes: ['txt', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'log'],\n metaParams: ['fileName', 'owner', 'fileSize', 'fileType', 'pageCount'],\n};\n\nexport const ZIPRAR_METADATA = {\n filetypes: ['zip', 'rar'],\n metaParams: ['fileName', 'owner', 'fileSize', 'fileType'],\n};\n\nexport const EMAIL_METADATA = {\n filetypes: ['pst', 'ost'],\n metaParams: ['fileName', 'owner', 'fileSize', 'fileType'],\n};\n\nexport const VIDEO_METADATA = {\n filetypes: ['mp4', 'mov', 'avi'],\n metaParams: [\n 'fileName',\n 'owner',\n 'fileSize',\n 'fileType',\n 'bitRate',\n 'frameRate',\n 'frameSize',\n 'colorModel',\n 'fps',\n 'mediaFormat',\n 'duration',\n ],\n};\n\nexport const AUDIO_METADATA = {\n filetypes: ['mp3'],\n metaParams: [\n 'fileName',\n 'owner',\n 'fileSize',\n 'fileType',\n 'bitRate',\n 'sampleRate',\n 'channelOutput',\n 'mediaFormat',\n 'duration',\n ],\n};\n\nexport const IMAGE_METADATA = {\n filetypes: ['jpeg', 'png', 'gif', 'tiff', 'jpg'],\n metaParams: [\n 'fileName',\n 'owner',\n 'fileSize',\n 'fileType',\n 'width',\n 'height',\n 'clippingPath',\n 'colorDepth',\n 'resolution',\n 'exifData',\n ],\n};\n\nexport const OTHER_METADATA = {\n metaParams: ['fileName', 'owner'],\n};\n\nexport const TYPEGROUP = [\n 'DOCUMENT_METADATA',\n 'ZIPRAR_METADATA',\n 'EMAIL_METADATA',\n 'VIDEO_METADATA',\n 'AUDIO_METADATA',\n 'IMAGE_METADATA',\n];\n","import React, { useState, useEffect } from 'react';\nimport PropTypes, { oneOfType } from 'prop-types';\nimport { Row, Col, Modal, notification, Collapse, Form, Spin } from 'antd';\nimport IconList from 'common/components/icon-list/IconList';\n\nimport {\n LabelValueWrapper,\n EditButton,\n FormAddButton,\n FormDeleteButton,\n FormCancelButton,\n} from 'common/components';\nimport { dialogFunction } from 'common/components';\nimport {\n CameraOutlined,\n CheckCircleOutlined,\n ExclamationCircleOutlined,\n} from '@ant-design/icons';\n\nimport DigitalRightIcon from 'common/components/digital-right-icon/DigitalRightIcon';\nimport AssetTypeEdit from 'common/components/asset-type-edit';\nimport MemberDefinedPropertiesPanel from './MemberDefinedPropertiesPanel';\n// import AssetGS1Edit from './AssetGS1Edit';\n\nimport AssetGS1Edit from '../add-link-product/AssetGS1Edit';\nimport AssetGS1Preview from '../add-link-product/AssetGS1Preview';\n\nimport { FormattedMessage, injectIntl } from 'react-intl';\nimport AddDRMForm from './AddDRMForm';\nimport messages from 'i18n/messages/asset-full-view';\nimport { formatMDY } from 'utils/formatDate';\nimport { formatSizeUnits } from 'utils/formatSizeUnits';\nimport {\n ADD_DRM_ASSET,\n DELETE_DRM_ASSET,\n} from 'services/digitalAsset/endpoints';\nimport * as metadataTypesConstant from 'static/Metadata';\nimport * as api from 'config/axios';\n\nimport './AssetOverview.less';\nimport _ from 'lodash';\n\nimport { useCheckAllowEditAssets } from 'hooks';\n\nimport { useDeepCompareEffect } from 'common/components/mapping-properties/hooks';\n\nconst { Panel } = Collapse;\n\nconst AssetOverview = (props) => {\n const {\n isFullView,\n assetData,\n classifications,\n gs1ImageData = [],\n assetId,\n typeData,\n submitAssetType,\n canEdit,\n setReloadData,\n intl,\n onReloadPage,\n memberDefinedPropertiesEditable,\n isHiddenEditSection = false,\n drm,\n } = props;\n\n const [leftCol, setLeftCol] = useState([]);\n const [isEditDRM, setIsEditDRM] = useState(false);\n const [rightCol, setRightCol] = useState([]);\n const [exifDataShow, setExifDataShow] = useState(false);\n const [loading, setLoading] = useState(false);\n const [activeGS1, setActiveGS1] = useState([]);\n const [metadataParams, setMetadataParams] = useState([]);\n const [editGS1, setEditGS1] = useState(false);\n const [isAddDRM, setIsAddDRM] = useState(false);\n const [activeCollapseKey, setActiveCollapseKey] = useState([]);\n const [form] = Form.useForm();\n\n useEffect(() => {\n form.resetFields();\n }, [isAddDRM, form]);\n\n useDeepCompareEffect(() => {\n setActiveGS1(gs1ImageData);\n }, [gs1ImageData]);\n\n const memberDefinedProperties = assetData?.memberDefinedProperties;\n\n const { checkAllowEditAssetFull } = useCheckAllowEditAssets();\n const isAllowEdit = checkAllowEditAssetFull();\n\n const allowModifyDRM = isAllowEdit;\n\n // EXIF Data Modal Relates Functions\n const showModal = () => {\n setExifDataShow(true);\n };\n\n const handleCancel = (e) => {\n setExifDataShow(false);\n };\n\n // Exif DATA Modify\n const exifDataModify = (value) => {\n if (value)\n return (\n \n );\n else return 'No';\n };\n\n // Modify Data\n const modifyData = (key, value) => {\n if (typeof value === 'boolean') {\n switch (value) {\n case true:\n return 'Yes';\n case false:\n return 'No';\n default:\n return value;\n }\n } else {\n switch (key) {\n case 'lastModified':\n case 'loadedDate':\n return formatMDY(value);\n case 'resolution':\n return value ? value + ' DPI' : '';\n case 'colorDepth':\n return value ? value + ' Bit' : '';\n case 'cropRange':\n case 'height':\n case 'width':\n return value ? value + 'px' : '';\n case 'fileSize':\n return formatSizeUnits(value);\n case 'exifData':\n return exifDataModify(value);\n default:\n return value;\n }\n }\n };\n\n // Filter Object By Value\n const filterObjectByValue = (obj, filter, direction) => {\n let newObj = Object.entries(obj)\n .map(([key, value]) => {\n return [\n key,\n value && typeof value === 'object'\n ? filterObjectByValue(value, filter)\n : value,\n ];\n })\n .reduce((newObj, [key, value]) => {\n if (!filter.includes(value)) {\n newObj[key] = value;\n }\n return newObj;\n }, {});\n\n let objectLength = Object.keys(newObj).length;\n\n return Object.entries(newObj).reduce((newObj, [key, value], index) => {\n if (direction === 'left-col' && index < Math.ceil(objectLength / 2)) {\n newObj[key] = modifyData(key, value);\n }\n if (direction === 'right-col' && index >= Math.ceil(objectLength / 2)) {\n newObj[key] = modifyData(key, value);\n }\n return newObj;\n }, {});\n };\n\n // Filter Object By Key\n const filterObjectByKey = (obj, filter) => {\n return Object.entries(obj)\n .map(([key, value]) => {\n return [\n key,\n value && typeof value === 'object'\n ? filterObjectByValue(value, filter)\n : value,\n ];\n })\n .reduce((newObj, [key, value]) => {\n if (!filter.includes(key)) {\n newObj[key] = modifyData(key, value);\n }\n return newObj;\n }, {});\n };\n\n useEffect(() => {\n setMetadataParams(onSetMetadataType(assetData?.fileType));\n }, [assetData]);\n\n // Remove all undefined values\n useEffect(() => {\n if (assetData?.metadata) {\n let metadateNew = assetData?.isIFrame\n ? _.pick(assetData?.metadata, ['loadedDate', 'lastModified', 'owner'])\n : assetData?.metadata;\n\n setLeftCol(filterObjectByMetadataOfType(metadateNew, 'left-col'));\n setRightCol(filterObjectByMetadataOfType(metadateNew, 'right-col'));\n\n filterObjectByMetadataOfType(metadateNew, [], 'left-col');\n }\n }, [assetData, metadataParams]);\n\n const exifData = `

${\n assetData && assetData.metadata && assetData.metadata.exifData\n ? assetData?.metadata?.exifData?.replace(/;/g, '
')\n : ''\n }

`;\n\n useEffect(() => {\n if (gs1ImageData?.length) {\n let filter = gs1ImageData?.filter(\n (item) => item.status?.toLowerCase() !== 'deleted'\n );\n setActiveGS1(filter);\n }\n }, [gs1ImageData, editGS1]);\n\n useEffect(() => {\n if (activeGS1?.length >= 1) {\n setActiveCollapseKey(['1']);\n }\n }, [activeGS1]);\n\n const onSetMetadataType = (type) => {\n let params = [];\n metadataTypesConstant.TYPEGROUP.forEach((group) => {\n if (metadataTypesConstant[group].filetypes.indexOf(type) > -1) {\n params = metadataTypesConstant[group].metaParams;\n }\n });\n if (params?.length === 0) {\n params = metadataTypesConstant.OTHER_METADATA.metaParams;\n }\n return params;\n };\n\n const filterObjectByMetadataOfType = (object, direction) => {\n let paramsFilter = onFilterParamsByType(object);\n let objectLength = Object.keys(paramsFilter).length;\n\n const resultParams = Object.entries(paramsFilter).reduce(\n (newObj, [key, value], index) => {\n if (direction === 'left-col' && index < Math.ceil(objectLength / 2)) {\n newObj[key] = modifyData(key, value);\n }\n if (direction === 'right-col' && index >= Math.ceil(objectLength / 2)) {\n newObj[key] = modifyData(key, value);\n }\n return newObj;\n },\n {}\n );\n\n return resultParams;\n };\n\n const onFilterParamsByType = (object) => {\n let paramsFilter = Object.entries(object)\n .map(([key, value]) => {\n return [key, value];\n })\n .reduce((newObj, [key, value]) => {\n if (metadataParams.includes(key)) {\n newObj[key] = value;\n }\n return newObj;\n }, {});\n return paramsFilter;\n };\n\n const typeDataRender = () => {\n return (\n
\n submitAssetType(value)}\n typeData={typeData}\n canEdit={false}\n />\n
\n );\n };\n\n const isEditDrmAsset = isAllowEdit && !isHiddenEditSection;\n\n const drmAssetRender = () => {\n return (\n
\n \n \n \n \n
\n {assetData?.digitalRightsType?.toLowerCase() ===\n 'ActiveDigitalRights'.toLowerCase() ? (\n \n ) : assetData?.digitalRightsType?.toLowerCase() ===\n 'ExpiredDigitalRights'.toLowerCase() ? (\n \n ) : (\n \n )}\n
\n \n }\n key='1'\n >\n {isEditDrmAsset && assetEditDRMRender()}\n\n {assetData?.digitalRightsType?.toLowerCase() !==\n 'NoDigitalRights'.toLowerCase() && (\n \n \n \n
\n \n
\n \n \n
\n \n
\n \n
\n )}\n\n {assetData?.digitalRights?.map((item, index) => {\n return (\n \n \n {item.status === 'Active' ? (\n \n ) : (\n \n )}\n \n {item.digitalRightsName}\n {formatMDY(item.expirationDate)}\n \n {isEditDRM && (\n {\n dialogDeleteDRM(item.id);\n }}\n disabled={!allowModifyDRM}\n />\n )}\n \n \n );\n })}\n \n \n
\n
\n );\n };\n\n const digitalAssetRender = () => {\n return (\n <>\n \n \n \n \n {leftCol && (\n \n )}\n \n \n {rightCol && (\n \n )}\n \n \n {classifications?.length > 0 && classificationRender()}\n \n \n \n );\n };\n\n const addDRMModal = () => {\n return (\n setIsAddDRM(false)}\n onOk={() => form.submit()}\n className='add-drm-modal'\n >\n \n \n );\n };\n\n async function handleAddDRM(data) {\n setLoading(true);\n const submitData = {\n DigitalAssetId: assetId,\n DigitalRightsName: data?.digitalRightsName,\n EffectiveDate: data?.dateEffective[0].toISOString(),\n ExpirationDate: data?.dateEffective[1]?.toISOString(),\n };\n await api\n .sendPost(ADD_DRM_ASSET, submitData)\n .then((response) => {\n if (response.isSuccess) {\n notification.success({ message: 'Add new DRM successful!' });\n onReloadPage();\n setIsAddDRM(false);\n } else notification.error({ message: 'Add new DRM error' });\n })\n .catch((error) => {\n notification.error({ message: 'Add new DRM error' });\n })\n .finally(() => {\n setLoading(false);\n });\n }\n const dialogDeleteDRM = (data) => {\n dialogFunction({\n type: 'warn',\n content: intl.formatMessage(messages.deleteDRM),\n onOk: () => handleDeleteDRM(data),\n });\n };\n\n async function handleDeleteDRM(data) {\n setLoading(true);\n const submitData = {\n DigitalAssetId: assetId,\n DigitalRightsId: data,\n };\n await api.sendPost(DELETE_DRM_ASSET, submitData).then((response) => {\n if (response.isSuccess) {\n notification.success({ message: 'Remove DRM successful!' });\n onReloadPage();\n } else notification.error({ message: 'Remove DRM error' });\n });\n setLoading(false);\n }\n\n const assetEditDRMRender = () => {\n return (\n <>\n \n {isEditDRM ? (\n
\n setIsAddDRM(true)}\n className='asset-overview__edit-button'\n disabled={!allowModifyDRM}\n />\n {\n setIsEditDRM(false);\n }}\n className='asset-overview__edit-button'\n />\n
\n ) : (\n allowModifyDRM && (\n
\n {\n setIsEditDRM(true);\n }}\n />\n
\n )\n )}\n
\n {addDRMModal()}\n \n );\n };\n\n const classificationRender = () => {\n return (\n \n \n \n {intl.formatMessage({\n id: `Taco.digitalAsset.overview.classifications`,\n })}\n \n \n \n \n \n \n );\n };\n\n const exifDataRender = () => {\n return (\n \n \n \n );\n };\n\n const memberDefinedRender = () => {\n return (\n \n );\n };\n\n const gs1Render = () => {\n return (\n setActiveCollapseKey(key)}\n >\n \n {editGS1 && !assetData?.isIFrame ? (\n \n ) : (\n \n )}\n \n \n );\n };\n\n return (\n \n {typeDataRender()}\n {!assetData?.isIFrame && memberDefinedRender()}\n {!assetData?.isIFrame && digitalAssetRender()}\n {isFullView\n ? !assetData?.isIFrame\n ? gs1Render()\n : null\n : gs1ImageData?.length > 0\n ? gs1Render()\n : null}\n {!assetData?.isIFrame && exifDataShow && exifDataRender()}\n {isFullView && drmAssetRender()}\n \n );\n};\n\nAssetOverview.propTypes = {\n assetData: oneOfType([PropTypes.array, PropTypes.object]),\n classifications: oneOfType([PropTypes.array, PropTypes.object]),\n gs1ImageData: oneOfType([PropTypes.array, PropTypes.object]),\n assetId: oneOfType([PropTypes.string, PropTypes.number]),\n canEdit: PropTypes.bool,\n setReloadData: PropTypes.func,\n isHiddenEditSection: PropTypes.bool,\n};\n\nexport default injectIntl(AssetOverview);\n","import * as types from './constants';\n\n// Asset Data Actions\nexport function getAssetData(assetId) {\n return {\n type: types.GET_ASSET_DATA,\n assetId,\n };\n}\n\nexport function getAssetDataSuccess(data) {\n return {\n type: types.GET_ASSET_DATA_SUCCESS,\n data,\n };\n}\n\nexport function getAssetDataError(error) {\n return {\n type: types.GET_ASSET_DATA_ERROR,\n error,\n };\n}\n\nexport function updateIsActive(payload) {\n return {\n type: types.UPDATE_IS_ACTIVE,\n payload,\n };\n}\n\n//* get ftp file list\nexport function getFtpFileList(payload) {\n return {\n type: types.GET_FTP_FILE_LIST,\n payload,\n };\n}\n\nexport function getFtpFileListSuccess(payload) {\n return {\n type: types.GET_FTP_FILE_LIST_SUCCESS,\n payload,\n };\n}\n\nexport function getFtpFileListError(error) {\n return {\n type: types.GET_FTP_FILE_LIST_ERROR,\n error,\n };\n}\n\n//* create digital asset\nexport function createDigitalAssetFull(digitalAsset) {\n return {\n type: types.CREATE_DIGITAL_ASSET_FULL,\n digitalAsset,\n };\n}\n\nexport function createDigitalAssetFullSuccess(metaData) {\n return {\n type: types.CREATE_DIGITAL_ASSET_FULL_SUCCESS,\n metaData,\n };\n}\n\nexport function createDigitalAssetFullError(error) {\n return {\n type: types.CREATE_DIGITAL_ASSET_FULL_ERROR,\n error,\n };\n}\n\n//* update digital asset\nexport function updateDigitalAsset(params) {\n return {\n type: types.UPDATE_DIGITAL_ASSET,\n params,\n };\n}\nexport function updateDigitalReplaceAsset(params) {\n return {\n type: types.UPDATE_DIGITAL_REPLACE_ASSET,\n params,\n };\n}\nexport function updateDigitalAssetSuccess() {\n return {\n type: types.UPDATE_DIGITAL_ASSET_SUCCESS,\n };\n}\n\nexport function updateRequiredField(params) {\n return {\n type: types.UPDATE_REQUIRED_FIELDS,\n params,\n };\n}\n\nexport function updateDigitalAssetError(error) {\n return {\n type: types.UPDATE_DIGITAL_ASSET_ERROR,\n error,\n };\n}\nexport function gridColumnAssetAssociation(gridName) {\n return {\n type: types.GET_ASSET_ASSOCIATION_GRID_COLUMN,\n gridName,\n };\n}\n\nexport function gridColumnAssetAssociationSuccess(columns) {\n return {\n type: types.GET_ASSET_ASSOCIATION_GRID_COLUMN_SUCCESS,\n columns,\n };\n}\n\nexport function gridColumnAssetAssociationError(error) {\n return {\n type: types.GET_ASSET_ASSOCIATION_GRID_COLUMN_ERROR,\n error,\n };\n}\n\nexport function cancelUpdateSuccess() {\n return {\n type: types.CANCEL_UPDATE_SUCCESS,\n };\n}\n\nexport function updateAssetType(params) {\n return {\n type: types.UPDATE_ASSET_TYPE,\n params,\n };\n}\n\nexport function updateAssetTypeSuccess() {\n return {\n type: types.UPDATE_ASSET_TYPE_SUCCESS,\n };\n}\n\nexport function updateAssetTypeError(error) {\n return {\n type: types.UPDATE_ASSET_TYPE_ERROR,\n error,\n };\n}\n\nexport const getAuthorizedTags = (memberId) => ({\n type: types.GET_AUTHORIZED_TAGS,\n memberId,\n});\n\nexport const getAuthorizedTagsSuccess = (data) => ({\n type: types.GET_AUTHORIZED_TAGS_SUCCESS,\n data,\n});\n\nexport const getAuthorizedTagsError = (error) => ({\n type: types.GET_AUTHORIZED_TAGS_ERROR,\n error,\n});\n","// Asset Data Action Types\nexport const GET_ASSET_DATA = 'GET_ASSET_DATA';\nexport const GET_ASSET_DATA_SUCCESS = 'GET_ASSET_DATA_SUCCESS';\nexport const GET_ASSET_DATA_ERROR = 'GET_ASSET_DATA_ERROR';\n//* get ftp file list\nexport const GET_FTP_FILE_LIST = 'GET_FTP_FILE_LIST';\nexport const GET_FTP_FILE_LIST_SUCCESS = 'GET_FTP_FILE_LIST_SUCCESS';\nexport const GET_FTP_FILE_LIST_ERROR = 'GET_FTP_FILE_LIST_ERROR';\n//* create digital asset\nexport const CREATE_DIGITAL_ASSET_FULL = 'CREATE_DIGITAL_ASSET_FULL';\nexport const CREATE_DIGITAL_ASSET_FULL_SUCCESS =\n 'CREATE_DIGITAL_ASSET_FULL_SUCCESS';\nexport const CREATE_DIGITAL_ASSET_FULL_ERROR =\n 'CREATE_DIGITAL_ASSET_FULL_ERROR';\n//* edit digital asset\nexport const UPDATE_DIGITAL_ASSET = 'UPDATE_DIGITAL_ASSET';\nexport const UPDATE_DIGITAL_REPLACE_ASSET = 'UPDATE_DIGITAL_REPLACE_ASSET';\nexport const UPDATE_DIGITAL_ASSET_SUCCESS = 'UPDATE_DIGITAL_ASSET_SUCCESS';\nexport const UPDATE_REQUIRED_FIELDS = 'UPDATE_REQUIRED_FIELD';\nexport const UPDATE_DIGITAL_ASSET_ERROR = 'UPDATE_DIGITAL_ASSET_ERROR';\nexport const UPDATE_IS_ACTIVE = 'UPDATE_IS_ACTIVE';\nexport const GET_ASSET_ASSOCIATION_GRID_COLUMN =\n 'GET_ASSET_ASSOCIATION_GRID_COLUMN';\nexport const GET_ASSET_ASSOCIATION_GRID_COLUMN_SUCCESS =\n 'GET_ASSET_ASSOCIATION_GRID_COLUMN_SUCCESS';\nexport const GET_ASSET_ASSOCIATION_GRID_COLUMN_ERROR =\n 'GET_ASSET_ASSOCIATION_GRID_COLUMN_ERROR';\nexport const CANCEL_UPDATE_SUCCESS = 'CANCEL_UPDATE_SUCCESS';\nexport const RELOAD_FULL_VIEW = 'RELOAD_FULL_VIEW';\nexport const UPDATE_ASSET_TYPE = 'UPDATE_ASSET_TYPE';\nexport const UPDATE_ASSET_TYPE_SUCCESS = 'UPDATE_ASSET_TYPE_SUCCESS';\nexport const UPDATE_ASSET_TYPE_ERROR = 'UPDATE_ASSET_TYPE_ERROR';\n\nexport const GET_AUTHORIZED_TAGS = 'GET_AUTHORIZED_TAGS';\nexport const GET_AUTHORIZED_TAGS_SUCCESS = 'GET_AUTHORIZED_TAGS_SUCCESS';\nexport const GET_AUTHORIZED_TAGS_ERROR = 'GET_AUTHORIZED_TAGS_ERROR';\n","import produce from 'immer';\nimport * as types from './constants';\n\nexport const initialState = {\n loading: false,\n assetData: null,\n digitalAsset: null,\n requiredFields: [],\n isActive: false,\n metaData: null,\n error: null,\n columns: [],\n gridName: '',\n ftpFileList: {\n data: null,\n loading: false,\n error: null,\n },\n postFtpFile: {\n status: null,\n loading: false,\n error: null,\n },\n editSuccess: false,\n editError: false,\n authorizedTagsLoading: false,\n authorizedTags: {\n enforceTagRestrictions: false,\n authorizedTags: [],\n },\n authorizedTagsError: null,\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst assetDataReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_ASSET_DATA:\n draft.loading = true;\n draft.error = null;\n // draft.assetData = null;\n break;\n case types.GET_ASSET_DATA_SUCCESS:\n draft.loading = false;\n draft.editSuccess = false;\n draft.assetData = action.data;\n draft.error = null;\n break;\n case types.GET_ASSET_DATA_ERROR:\n draft.loading = false;\n draft.editSuccess = false;\n draft.error = action.error;\n draft.assetData = null;\n break;\n //* get ftp file list\n case types.GET_FTP_FILE_LIST:\n draft.ftpFileList.loading = true;\n draft.ftpFileList.error = null;\n break;\n case types.GET_FTP_FILE_LIST_SUCCESS:\n draft.ftpFileList.loading = false;\n draft.ftpFileList.data = action.payload;\n draft.ftpFileList.error = null;\n break;\n case types.GET_FTP_FILE_LIST_ERROR:\n draft.ftpFileList.loading = false;\n draft.ftpFileList.error = action.error;\n draft.ftpFileList.data = null;\n break;\n //*create asset\n case types.CREATE_DIGITAL_ASSET_FULL:\n draft.loading = true;\n break;\n case types.CREATE_DIGITAL_ASSET_FULL_SUCCESS:\n draft.loading = false;\n draft.metaData = { ...action.metaData, isOwner: true };\n break;\n case types.CREATE_DIGITAL_ASSET_FULL_ERROR:\n draft.loading = false;\n break;\n case types.UPDATE_DIGITAL_ASSET:\n draft.loading = true;\n break;\n case types.UPDATE_IS_ACTIVE:\n draft.isActive = action.payload;\n break;\n case types.UPDATE_DIGITAL_REPLACE_ASSET:\n draft.loading = true;\n draft.editError = false;\n break;\n case types.UPDATE_DIGITAL_ASSET_SUCCESS:\n draft.loading = false;\n draft.editSuccess = true;\n break;\n case types.UPDATE_REQUIRED_FIELDS:\n draft.requiredFields = action.params;\n break;\n case types.UPDATE_DIGITAL_ASSET_ERROR:\n draft.loading = false;\n draft.editError = action.error;\n draft.editSuccess = false;\n break;\n case types.GET_ASSET_ASSOCIATION_GRID_COLUMN:\n draft.loading = true;\n draft.error = false;\n draft.gridName = action.gridName;\n break;\n case types.GET_ASSET_ASSOCIATION_GRID_COLUMN_SUCCESS:\n draft.loading = false;\n draft.columns = action.columns;\n break;\n case types.GET_ASSET_ASSOCIATION_GRID_COLUMN_ERROR:\n // draft.loading = false;\n break;\n case types.CANCEL_UPDATE_SUCCESS:\n draft.editSuccess = false;\n break;\n case types.GET_AUTHORIZED_TAGS:\n draft.authorizedTagsLoading = true;\n break;\n case types.GET_AUTHORIZED_TAGS_SUCCESS:\n draft.authorizedTagsLoading = false;\n draft.authorizedTags = action.data;\n break;\n case types.GET_AUTHORIZED_TAGS_ERROR:\n draft.authorizedTagsLoading = false;\n draft.authorizedTagsError = action.error;\n break;\n default:\n break;\n }\n });\n\nexport default assetDataReducer;\n","import { put, call, takeLatest, all } from 'redux-saga/effects';\nimport React from 'react';\n\nimport * as types from './constants';\nimport * as actions from './actions';\nimport * as actionsBranding from '@redux/branding/actions';\nimport * as actionsRibbon from 'pages/home/ribbon/asset-full/controllers/actions';\n\nimport * as servicesGrid from 'services/grid';\nimport { formatMDYWithParam } from 'utils/formatDate';\nimport {\n AssociationIconRendered,\n AssociationIconRenderedBound,\n} from '../components/index';\nimport { notification } from 'antd';\n\nimport {\n getAssetData,\n serviceToGetFtpFileList,\n updateDigitalAssetService,\n updateDigitalReplaceAssetService,\n editIFrame,\n updateAssetType,\n} from 'services/digitalAsset';\n\nimport * as tagRestrictionsServices from 'services/tag-restrictions';\n\nexport function* getAssetDataSaga(payload) {\n try {\n const response = yield call(getAssetData, payload.assetId);\n if (response.isSuccess) {\n yield put(actions.getAssetDataSuccess(response.data));\n } else {\n yield put(actions.getAssetDataError(response.message));\n }\n } catch (error) {\n yield put(actions.getAssetDataError(error));\n }\n}\n\n//* GET FTP FILE LIST SAGA\nexport function* getFtpFileListSaga(action) {\n try {\n const options = {\n params: {\n ServiceType: action.payload,\n },\n };\n const response = yield call(serviceToGetFtpFileList, options);\n if (response.isSuccess) {\n yield put(actions.getFtpFileListSuccess(response.data.assetsModels));\n } else {\n yield put(actions.getFtpFileListError(response.message));\n }\n } catch (error) {\n yield put(actions.getFtpFileListError(error));\n }\n}\n\nexport function* updateDigitalAsset(payload) {\n try {\n let response;\n if (payload.params?.isIFrame)\n response = yield call(editIFrame, payload.params);\n else response = yield call(updateDigitalAssetService, payload.params);\n if (response?.isSuccess) {\n yield put(actions.updateRequiredField(response?.data?.requiredFields));\n yield put(actions.updateDigitalAssetSuccess(response.data));\n yield put(actionsBranding.getBrandingNoLoading());\n\n if (response.data?.requiredFields?.length) {\n yield put(actionsRibbon.editAsset());\n } else {\n yield put(actions.getAssetData(payload.params.id));\n yield put(actionsRibbon.cancelEditAsset());\n yield put(actions.updateIsActive(true));\n }\n } else {\n yield put(actions.updateDigitalAssetError(response?.message));\n yield put(actionsRibbon.cancelSavingAsset());\n }\n } catch (error) {\n yield put(actions.updateDigitalAssetError(error));\n yield put(actionsRibbon.cancelSavingAsset());\n }\n}\nexport function* updateDigitalReplaceAsset(payload) {\n try {\n const response = yield call(\n updateDigitalReplaceAssetService,\n payload.params\n );\n if (response?.isSuccess) {\n yield put(actions.updateRequiredField(response?.data?.requiredFields));\n yield put(actionsBranding.getBrandingNoLoading());\n if (response.data?.requiredFields?.length) {\n yield put(actionsRibbon.editAsset());\n } else {\n yield put(actions.updateIsActive(true));\n }\n yield put(actions.updateDigitalAssetSuccess(response.data));\n }\n } catch (error) {\n yield put(actions.updateDigitalAssetError(error));\n }\n}\n\nexport function* updateAssetData(payload) {\n try {\n const response = yield call(updateAssetType, payload.params);\n if (response.isSuccess) {\n notification.success({\n message: 'Update Asset Type Success',\n });\n yield put(actions.getAssetData(payload.params.id));\n }\n } catch (error) {\n yield put(actions.updateAssetTypeError(error));\n }\n}\nconst renderIconType = (params) => {\n return ;\n};\n\nconst renderIconBound = (params) => {\n return ;\n};\n\nconst renderFileType = (params) => {\n return params.value?.toUpperCase() ?? null;\n};\n\nexport function* gridDigitalAssetColumnInfo(payload) {\n try {\n const response = yield call(servicesGrid.gridColumnInfo, payload.gridName);\n\n let columns = [\n {\n field: '',\n width: 30,\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n },\n ];\n\n if (response?.columns?.length > 0) {\n response.columns.forEach((val) => {\n if (!['id', 'otherAssetId'].includes(val.fieldNameCamelCase)) {\n if (val.fieldNameCamelCase === 'created') {\n val = {\n ...val,\n width: 100,\n suppressMenu: true,\n cellRenderer: formatMDYWithParam,\n };\n } else if (val.fieldNameCamelCase === 'isInBound') {\n val = {\n ...val,\n headerName: '',\n dataType: 'string',\n width: 100,\n suppressMenu: true,\n cellRenderer: renderIconBound,\n };\n } else if (val.fieldNameCamelCase === 'type') {\n val = {\n ...val,\n headerName: '',\n width: 100,\n suppressMenu: true,\n cellRenderer: renderIconType,\n };\n } else if (val.fieldNameCamelCase === 'assetName') {\n val = { ...val, flex: 1, minWidth: 130, suppressMenu: true };\n } else if (val.fieldNameCamelCase === 'fileType') {\n val = {\n ...val,\n width: 100,\n suppressMenu: true,\n // cellRenderer: renderFileType,\n };\n }\n columns.push(val);\n }\n });\n }\n\n yield put(actions.gridColumnAssetAssociationSuccess(columns));\n } catch (error) {\n yield put(actions.gridColumnAssetAssociationError(error));\n }\n}\n\nexport function* getAuthorizedTagsSaga(payload) {\n try {\n const response = yield call(\n tagRestrictionsServices.getAuthorizedTags,\n payload.memberId\n );\n if (response.isSuccess) {\n yield put(actions.getAuthorizedTagsSuccess(response.data));\n } else {\n yield put(actions.getAuthorizedTagsError(response.message));\n }\n } catch (error) {\n yield put(actions.getAuthorizedTagsError(error));\n }\n}\n\nfunction* watchAll() {\n yield all([\n takeLatest(types.GET_ASSET_DATA, getAssetDataSaga),\n takeLatest(types.GET_FTP_FILE_LIST, getFtpFileListSaga),\n takeLatest(types.UPDATE_DIGITAL_ASSET, updateDigitalAsset),\n takeLatest(types.UPDATE_DIGITAL_REPLACE_ASSET, updateDigitalReplaceAsset),\n takeLatest(\n types.GET_ASSET_ASSOCIATION_GRID_COLUMN,\n gridDigitalAssetColumnInfo\n ),\n takeLatest(types.UPDATE_ASSET_TYPE, updateAssetData),\n takeLatest(types.GET_AUTHORIZED_TAGS, getAuthorizedTagsSaga),\n ]);\n}\n\nexport default watchAll;\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\n/**\n * take digital asset full state from redux\n * @param {object} state\n */\nconst selectAssetData = (state) => state?.digitalAsset || initialState;\n\nconst selectDigitalAsset = () =>\n createSelector(selectAssetData, (state) => state.digitalAsset);\n\nconst selectDigitalAssetMetaData = () =>\n createSelector(selectAssetData, (state) => state.metaData);\n\nconst selectDigitalAssetLoading = () =>\n createSelector(selectAssetData, (state) => state.loading);\n\nconst selectDigitalAssetError = () =>\n createSelector(selectAssetData, (state) => state.error);\n\nconst selectIsActive = () =>\n createSelector(selectAssetData, (state) => state.isActive);\n\nconst assetDataLoading = () =>\n createSelector(selectAssetData, (state) => state.assetData);\n\nconst selectRequiredFields = () =>\n createSelector(selectAssetData, (state) => state.requiredFields);\n\nconst assetDataColumnInfo = () =>\n createSelector(selectAssetData, (state) => state.columns);\n\nconst selectEditSuccess = () =>\n createSelector(selectAssetData, (state) => state.editSuccess);\n\nconst selectDigitalAssetEditError = () =>\n createSelector(selectAssetData, (state) => state.editError);\n\nconst selectEditTypeLoading = () =>\n createSelector(selectAssetData, (state) => state.editTypeLoading);\n\n//* ftp list selector\nconst makeSelectFtpFileList = () =>\n createSelector(selectAssetData, (subState) => subState.ftpFileList);\n\nconst makeSelectAssetData = () =>\n createSelector(selectAssetData, (subState) => subState.assetData);\n\nconst selectAuthorizedTagsLoading = () =>\n createSelector(selectAssetData, (subState) => subState.authorizedTagsLoading);\n\nconst selectAuthorizedTags = () =>\n createSelector(selectAssetData, (subState) => subState.authorizedTags);\n\nconst selectAuthorizedTagsError = () =>\n createSelector(selectAssetData, (subState) => subState.authorizedTagsError);\n\nexport {\n selectIsActive,\n selectDigitalAsset,\n selectDigitalAssetLoading,\n selectDigitalAssetMetaData,\n selectRequiredFields,\n selectAssetData,\n assetDataLoading,\n makeSelectFtpFileList,\n selectDigitalAssetError,\n assetDataColumnInfo,\n selectEditSuccess,\n selectDigitalAssetEditError,\n makeSelectAssetData,\n selectEditTypeLoading,\n selectAuthorizedTagsLoading,\n selectAuthorizedTags,\n selectAuthorizedTagsError,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { List } from 'antd';\nimport * as _ from 'lodash';\nimport { AssetTileCard } from 'pages/branded-assets/components';\n\nfunction AssetTileView(props) {\n const { tileData, handleToggleAssetContext } = props;\n return (\n \n {!!tileData && (\n (\n \n \n \n )}\n />\n )}\n \n );\n}\n\nAssetTileView.propTypes = {\n // ? tileData -> data of tile table\n tileData: PropTypes.array,\n};\n\nexport default React.memo(AssetTileView);\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { List } from 'antd';\nimport * as _ from 'lodash';\nimport { AssetThumbnailCard } from 'pages/branded-assets/components';\n\nfunction AssetThumbView(props) {\n const { thumbData, handleToggleAssetContext } = props;\n return (\n \n {!!thumbData && (\n (\n \n \n \n )}\n />\n )}\n \n );\n}\n\nAssetThumbView.propTypes = {\n // ? thumbData -> data of thumb table\n thumbData: PropTypes.array,\n};\n\nexport default React.memo(AssetThumbView);\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { List } from 'antd';\nimport * as _ from 'lodash';\nimport { AssetItemCard } from 'pages/branded-assets/components';\n\nfunction AssetDetailView(props) {\n const { detailData, handleToggleAssetContext } = props;\n return (\n \n {!!detailData && (\n (\n \n \n \n )}\n />\n )}\n \n );\n}\n\nAssetDetailView.propTypes = {\n // ? tileData -> data of tile table\n detailData: PropTypes.array,\n // ? handleToggleAssetContext\n handleToggleAssetContext: PropTypes.func,\n};\n\nexport default React.memo(AssetDetailView);\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { Card, Checkbox } from 'antd';\nimport classnames from 'classnames';\nimport './AssetThumbnailCard.less';\n\nconst AssetThumbnailCard = ({ alt, src, id, handleToggleAssetContext }) => {\n const [isChecked, setCheckedStatus] = useState(false);\n\n const onCheckHandler = (e) => {\n setCheckedStatus(e.target.checked);\n };\n\n return (\n \n \n handleToggleAssetContext(id)}\n />\n \n );\n};\n\nAssetThumbnailCard.propTypes = {\n // ? src\n src: PropTypes.string,\n // ? atl\n alt: PropTypes.string,\n // ? id\n id: PropTypes.string,\n //? handleToggleAssetContext\n handleToggleAssetContext: PropTypes.func,\n};\n\nexport default AssetThumbnailCard;\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { Checkbox, Card, Typography } from 'antd';\nimport './AssetTileCard.less';\n\nconst { Text } = Typography;\n\nconst AssetListItemCard = (props) => {\n const { alt, src, widget, upc12, id, handleToggleAssetContext } = props;\n const [isChecked, setCheckedStatus] = useState(false);\n\n const onCheckHandler = (e) => {\n setCheckedStatus(e.target.checked);\n };\n console.log(src);\n return (\n \n \n
handleToggleAssetContext(id)}>\n {alt}\n {`${upc12} - ${widget}`}\n
\n \n );\n};\n\nAssetListItemCard.propTypes = {\n // ? src - img source\n src: PropTypes.string,\n // ? alt - alternative for image source\n alt: PropTypes.string,\n // ? widget - unknown\n widget: PropTypes.string,\n // ? upc12 - unknown\n upc12: PropTypes.string,\n // ? id\n id: PropTypes.string,\n // ? handleToggleAssetContext\n handleToggleAssetContext: PropTypes.func,\n};\n\nexport default AssetListItemCard;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Card } from 'antd';\nimport * as _ from 'lodash';\nimport {\n AssetItemCardTop,\n AssetItemCardBottom,\n} from 'pages/branded-assets/components';\n\nimport './AssetItemCard.less';\n\nconst AssetItemCard = (props) => {\n const { detailItemData, handleToggleAssetContext } = props;\n\n return (\n \n handleToggleAssetContext(_.get(detailItemData, 'id'))\n }\n >\n \n \n \n );\n};\n\n// define propTypes with type\nAssetItemCard.propTypes = {\n // ? detailItemData\n detailItemData: PropTypes.object,\n // ? handleToggleAssetContext\n handleToggleAssetContext: PropTypes.func,\n};\n\nexport default AssetItemCard;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Typography, List } from 'antd';\nimport {\n CodeSandboxOutlined,\n PictureOutlined,\n RedoOutlined,\n} from '@ant-design/icons';\nimport './AssetItemCardTop.less';\n\nconst { Text } = Typography;\n\nconst AssetItemCardTop = (props) => {\n const {\n upc12,\n brand,\n name,\n packageLevels,\n snl,\n assetImgUrl,\n publishImgUrl,\n } = props;\n\n return (\n \n \n \n \n product\n \n \n \n \n {upc12}\n \n \n {brand}\n \n \n {name}\n \n \n \n (\n \n {packageItem}\n {idx !== packageLevels.length - 1 && /}\n \n )}\n />\n \n \n \n \n \n \n \n publish\n \n \n {snl}\n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nAssetItemCardTop.propTypes = {\n // ? upc12\n upc12: PropTypes.string,\n // ? brand\n brand: PropTypes.string,\n // ? name\n name: PropTypes.string,\n // ? packageLevels\n packageLevels: PropTypes.arrayOf(PropTypes.string),\n // ? snl\n snl: PropTypes.string,\n // ? assetImgUrl\n assetImgUrl: PropTypes.string,\n //? publish\n publishImgUrl: PropTypes.string,\n};\n\nexport default React.memo(AssetItemCardTop);\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Typography } from 'antd';\nimport moment from 'moment';\n\nconst { Text } = Typography;\n\nconst AssetItemCardBottom = (props) => {\n const { imageUpdateDate, lastUpdateDate } = props;\n\n return (\n \n \n \n Last Updated: \n\n \n {\n //TODO: DATETIME\n moment(lastUpdateDate).format('MM/DD/YYYY')\n }\n \n \n \n \n image Updated: \n \n {\n //TODO: DATETIME\n moment(imageUpdateDate).format('MM/DD/YYYY')\n }\n \n \n \n );\n};\n\nAssetItemCardBottom.propTypes = {\n //? imageUpdateDate - iso date\n imageUpdateDate: PropTypes.string,\n //? lastUpdateDate - iso date\n lastUpdateDate: PropTypes.string,\n};\n\nexport default React.memo(AssetItemCardBottom);\n","import React, { useState } from 'react';\nimport { Typography, Space, Row, Col, Button, Tooltip, Modal } from 'antd';\nimport { get } from 'lodash';\nimport IconList from 'common/components/icon-list/IconList';\nimport EntityStatusTag from 'common/components/tag/entity-status-tag/EntityStatusTag';\nimport PropTypes from 'prop-types';\nimport { formatSizeUnits } from 'utils/formatSizeUnits';\nimport * as getLink from 'utils/common/linkBuilder';\n\nconst { Paragraph, Title, Link } = Typography;\n\nconst AssetTileBody = (props) => {\n const { dataDetail } = props;\n\n const [visible, setVisible] = useState(false);\n\n const status = get(dataDetail, 'status', '');\n const assetName = get(dataDetail, 'assetName', '');\n const id = get(dataDetail, 'id', '');\n const assetType = get(dataDetail, 'assetType', '');\n const fileType = get(dataDetail, 'fileType', '');\n const fileName = get(dataDetail, 'fileName', '');\n const fileSize = get(dataDetail, 'fileSize', 0);\n const additionalSearchTags = get(dataDetail, 'additionalSearchTags', '');\n const dataAssetSegments = get(dataDetail, 'dataAssetSegments', '');\n const description = get(dataDetail, 'description', '');\n const tagList = additionalSearchTags ? additionalSearchTags.split(',') : [];\n const aLink = getLink.assetLink(id, assetName);\n\n const renderDescriptionTooltip = (description) => {\n return (\n <>\n \n {description}\n \n setVisible(true)}>\n More\n \n \n );\n };\n\n const renderDescriptionInfo = (description) => {\n return (\n setVisible(false)}\n footer={[\n ,\n ]}\n >\n \n {description}\n \n \n );\n };\n\n return (\n
\n \n \n {aLink}\n \n {assetType}\n \n \n {fileName}\n \n \n {fileType || 'file-type'} / {formatSizeUnits(fileSize)}\n \n {description && (\n \n \n \n {description}\n \n \n \n )}\n {description && renderDescriptionInfo(description)}\n \n \n \n \n \n \n \n \n
\n );\n};\n\nAssetTileBody.propTypes = {\n dataDetail: PropTypes.object,\n};\n\nexport default AssetTileBody;\n","/* eslint-disable jsx-a11y/alt-text */\n// eslint-disable-next-line jsx-a11y/alt-text\n\nimport React from 'react';\n\nimport classnames from 'classnames';\n\nimport { Row, Avatar } from 'antd';\nimport PropTypes from 'prop-types';\nimport iframe from 'assets/iframe.png';\n\nimport { useImageLoaded } from 'hooks';\n\nimport { Images } from 'config/assets';\n\nconst AssetTileHeader = (props) => {\n const { dataDetail } = props;\n\n // Viet - get image with version suffix to prevent cache image\n const imageThumbnail = dataDetail?.thumbSize300;\n const image = dataDetail?.isIFrame ? iframe : dataDetail && imageThumbnail;\n\n const [ref, loaded, onLoad] = useImageLoaded();\n\n return (\n \n
\n\n
\n \n \n \n
\n
\n );\n};\n\nAssetTileHeader.propTypes = {\n dataDetail: PropTypes.object,\n};\n\nexport default AssetTileHeader;\n","import React from 'react';\nimport { Row, Col } from 'antd';\n\nimport { formatMDY } from 'utils/formatDate';\nimport { get } from 'lodash';\nimport { injectIntl } from 'react-intl';\nimport PropTypes from 'prop-types';\n\nconst AssetTileFooter = (props) => {\n const { intl, dataDetail } = props;\n\n const loadedDate = get(dataDetail, 'loadedDate', '');\n const lastUpdated = get(dataDetail, 'lastUpdated', '');\n\n return (\n \n \n \n \n {intl.formatMessage({\n id: 'Taco.common.components.assetList.lastUpdated',\n })}{' '}\n \n {lastUpdated && formatMDY(lastUpdated)} \n \n \n \n {intl.formatMessage({\n id: 'Taco.common.components.assetList.imageDate',\n })}{' '}\n \n {loadedDate && formatMDY(loadedDate)}\n \n \n \n );\n};\n\nAssetTileFooter.propTypes = {\n loadedDate: PropTypes.string,\n lastUpdate: PropTypes.string,\n};\n\nexport default injectIntl(AssetTileFooter);\n","import React from 'react';\nimport { AssetTileBody, AssetTileFooter, AssetTileHeader } from '../index';\nimport './AssetTile.less';\nimport { get } from 'lodash';\nimport useDoubleClick from 'hooks/useDoubleClick';\n\nconst AssetTile = (props) => {\n const { dataDetail } = props;\n const { onClickItemGrid, onDoubleClick } = props.clickEvents;\n const assetName = get(dataDetail, 'assetName', '');\n\n const divRef = React.useRef();\n useDoubleClick({\n onSingleClick: (e) => {\n if (onClickItemGrid) onClickItemGrid(dataDetail, e);\n },\n onDoubleClick: (e) => {\n if (onDoubleClick) onDoubleClick(dataDetail);\n },\n ref: divRef,\n latency: 250,\n });\n\n return (\n
\n {/*Placeholder for click events*/}\n \n \n \n \n
\n );\n};\n\nexport default AssetTile;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { forwardTo } from 'utils/common/route';\nimport { ThumbnailItem } from 'common/components';\nimport iframe from 'assets/iframe.png';\nimport * as getLink from 'utils/common/linkBuilder';\n/**\n * Asset thumbnail is inherit from thumbnail item\n * @param {object} props\n */\nconst AssetThumbnailCard = (props) => {\n const {\n dataDetail,\n selected,\n onClickItemGrid,\n onClickCheckboxItem,\n pathname,\n linkTarget,\n style,\n isShareBtn = true,\n hideCheckbox = false,\n } = props;\n\n const onDoubleClick = (item) => {\n if (props.onDoubleClick) {\n return props.onDoubleClick(item);\n }\n\n if (!pathname) return;\n const { id } = item;\n forwardTo(`${pathname}/${id}`);\n };\n\n // Viet - get image with version suffix to prevent cache image\n const imageThumbnail = dataDetail?.thumbSize300;\n const image = dataDetail?.isIFrame ? iframe : dataDetail && imageThumbnail;\n // Bp - add link to asset thumbnail\n const alink = getLink.assetLink(\n dataDetail?.id,\n dataDetail?.assetName,\n linkTarget\n );\n\n return (\n \n );\n};\n\nAssetThumbnailCard.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default React.memo(AssetThumbnailCard);\n","import React from 'react';\nimport { Spin, Divider } from 'antd';\nimport { useSelector } from 'react-redux';\nimport assetsRibbonSelector from 'pages/home/ribbon/asset-full/controllers/selectors';\nimport { AssetPanelAssociation, AssetPanelThumbnailInfo } from '../index';\nimport LinkAssets from './link-assets/LinkAssets';\nimport AssetOverview from 'pages/asset-full-view/components/metadata-panel/AssetOverview';\nimport './AssetPanel.less';\nimport AssetDownload from 'pages/asset-full-view/components/metadata-panel/AssetDownload';\n\nconst AssetPanel = (props) => {\n const { assetData, loadingDetail, style } = props;\n const modeLinkAssets = useSelector(\n assetsRibbonSelector.selectModeLinkAssets()\n );\n\n const typeData = {\n assetType: assetData?.assetType,\n assetSubType: assetData?.assetSubType,\n packageLevel: assetData?.metadata?.packageLevel,\n packagingDisposition: assetData?.metadata?.packagingDisposition,\n angle: assetData?.metadata?.angle,\n facing: assetData?.metadata?.facing,\n language: assetData?.metadata?.language,\n panelType: assetData?.metadata?.panelType,\n logoType: assetData?.metadata?.logoType,\n certificateType: assetData?.metadata?.certificateType,\n documentType: assetData?.metadata?.documentType,\n };\n\n return (\n
\n {loadingDetail ? (\n
\n \n
\n ) : (\n assetData && (\n
\n \n \n
\n \n
\n {modeLinkAssets ? null : (\n \n )}\n {modeLinkAssets ? : null}\n {!assetData?.isIFrame && (\n
\n \n
\n )}\n
\n )\n )}\n
\n );\n};\nexport default AssetPanel;\n","import React, { useEffect } from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\nimport { useParams } from 'react-router-dom';\nimport AssetAssociations from '../../../asset-full-view/components/metadata-panel/AssetAssociations';\nimport * as selectors from '../../../asset-full-view/controllers/selectors';\nimport * as assetActions from '../../../asset-full-view/controllers/actions';\n\nconst AssetPanelAssociation = (props) => {\n const { assetData } = props;\n const { id } = useParams();\n const dispatch = useDispatch();\n const associationColumn = useSelector(selectors.assetDataColumnInfo());\n useEffect(() => {\n dispatch(assetActions.gridColumnAssetAssociation('asset-association-grid'));\n }, [dispatch]);\n\n return (\n
\n
Associations:
\n
\n 0 ? associationColumn : [{}]\n }\n assetData={assetData}\n />\n
\n
\n );\n};\n\nexport default AssetPanelAssociation;\n","import React from 'react';\nimport { message, Dropdown, Menu, Typography } from 'antd';\nimport { DownloadOutlined } from '@ant-design/icons';\nimport { dialogFunction } from 'common/components';\nimport { injectIntl } from 'react-intl';\n\nimport { getLinkDownloadAsset } from 'services/digitalAsset';\nimport * as api from 'config/axios';\nimport DigitalRight from 'assets/DRM.png';\n\nconst { Text } = Typography;\n\nconst defaultAsset = 'Original';\n\nconst AssetPanelDownload = ({ assetData, intl }) => {\n const { id, fileUrl, fileType, downloadFormats } = assetData;\n\n const downloadOriginalFormat = async () => {\n const params = `${fileUrl}?dl=1`;\n try {\n await api.sendDownload({\n url: params,\n });\n } catch (error) {\n console.log(error);\n }\n };\n const downloadAnotherFormat = async (key) => {\n try {\n const response = await getLinkDownloadAsset(id, key);\n if (response.isSuccess) {\n api.sendDownload({\n url: response.data.url,\n });\n } else {\n message.error(response.message);\n }\n } catch (error) {\n message.error(error);\n }\n };\n\n const addMissingFileType = () => {\n if (!fileType) return;\n const upCaseFileType = fileType.toUpperCase();\n return Array.from(new Set([...downloadFormats, upCaseFileType]?.sort()));\n };\n\n const listTypeDownload = addMissingFileType() ?? [];\n\n const triggerDownload = (key) => {\n if (key === 'Original' && fileUrl) {\n downloadOriginalFormat();\n } else {\n downloadAnotherFormat(key.toLowerCase());\n }\n };\n\n const menu = (\n {\n assetData?.drm ? handlePreDownload(key) : triggerDownload(key);\n }}\n >\n {listTypeDownload.map((format) => (\n \n {format}\n \n ))}\n \n );\n\n function handlePreDownload(data) {\n dialogFunction({\n type: 'warn',\n content: (\n
\n \n {intl.formatMessage({\n id: 'Taco.home.ribbon.dialogDeleteDRMsingle',\n })}\n
\n ),\n\n okText: 'Cancel',\n onCancel: () => triggerDownload(data),\n cancelText: 'Download',\n });\n }\n\n return (\n trigger.parentElement}\n >\n {\n assetData?.drm\n ? handlePreDownload(defaultAsset)\n : triggerDownload(defaultAsset);\n }}\n />\n \n );\n};\n\nconst disableDownloadButton = (assetData) => {\n if (assetData?.isIFrame) return true;\n return false;\n};\n\nexport default injectIntl(AssetPanelDownload);\n","import React, { useRef } from 'react';\nimport Image from 'common/components/image/Image';\nimport { FavoriteStarIconRender } from 'common/components';\nimport { get } from 'lodash';\nimport { Row, Col, Typography, Tooltip } from 'antd';\nimport { EyeOutlined } from '@ant-design/icons';\nimport { AssetPanelDownload } from '../index';\nimport { forwardTo } from 'utils/common/route';\nimport iframe from 'assets/iframe.png';\nimport { Images } from 'config/assets';\nimport useDoubleClick from 'hooks/useDoubleClick';\n\nconst { Title } = Typography;\n\nconst AssetPanelThumbnailInfo = (props) => {\n const { assetData } = props;\n const thumbUrl = get(assetData, 'thumbnail', '');\n const fileName = get(assetData, 'assetName', '');\n const isFavorited = get(assetData, 'isFavorited', false);\n const divRef = useRef();\n\n useDoubleClick({\n onDoubleClick: (e) => {\n forwardTo(`/asset/${assetData?.id}`);\n },\n ref: divRef,\n latency: 250,\n });\n\n return (\n
\n \n \n trigger.parentElement}\n >\n {\n forwardTo(`/asset/${assetData?.id}`);\n }}\n />\n \n \n \n {!assetData?.isIFrame && }\n \n \n \n
\n \n
\n \n <FavoriteStarIconRender\n isFavorited={isFavorited}\n style={{ marginRight: 8 }}\n />\n {fileName}\n \n \n
\n );\n};\n\nexport default AssetPanelThumbnailInfo;\n","/*\n * Login Messages\n *\n * This contains all the text for the login component.\n */\nimport { defineMessages } from 'react-intl';\n\nexport const scope = 'Taco.branded-assets-products';\n\nexport default defineMessages({\n gridTitle: {\n id: `${scope}.constants.assetGridView.gridTitle`,\n defaultMessage: 'PRODUCT ASSET',\n },\n ucp12: {\n id: `${scope}.constants.assetGridView.upc12`,\n defaultMessage: 'UPC12',\n },\n manufacturer: {\n id: `${scope}.constants.assetGridView.manufacturer`,\n defaultMessage: 'MANUFACTURER',\n },\n brand: {\n id: `${scope}.constants.assetGridView.brand`,\n defaultMessage: 'BRAND',\n },\n description: {\n id: `${scope}.constants.assetGridView.description`,\n defaultMessage: 'DESCRIPTION',\n },\n size: {\n id: `${scope}.constants.assetGridView.size`,\n defaultMessage: 'SIZE',\n },\n status: {\n id: `${scope}.constants.assetGridView.status`,\n defaultMessage: 'STATUS',\n },\n lastModified: {\n id: `${scope}.constants.assetGridView.lastModified`,\n defaultMessage: 'LAST MODIFIED',\n },\n editedBy: {\n id: `${scope}.constants.assetGridView.editedBy`,\n defaultMessage: 'EDITED BY',\n },\n ixoneId: {\n id: `${scope}.constants.assetGridView.ixoneId`,\n defaultMessage: 'IXONE ID',\n },\n ixoneCertifiateDate: {\n id: `${scope}.constants.assetGridView.ixoneCertifiateDate`,\n defaultMessage: 'IXONE CERTIFICATION DATE',\n },\n syncReady: {\n id: `${scope}.constants.assetGridView.syncReady`,\n defaultMessage: 'SYNC READY',\n },\n viewDetail: {\n id: `${scope}.constants.assetGridView.viewDetail`,\n defaultMessage: 'VIEW DETAIL',\n },\n hintGridAsset: {\n id: `${scope}.constants.assetGridView.hintGridAsset`,\n defaultMessage:\n 'You can drag-drop items in the grid after you search successfully.',\n },\n});\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducers';\n\n/**\n * take digital asset full state from redux\n * @param {object} state\n */\n\nconst selectLinkAssetsData = (state) => state?.linkAssets || initialState;\n\nconst makeSelectLinkAssets = () =>\n createSelector(\n selectLinkAssetsData,\n ({ linkAssetsState }) => linkAssetsState\n );\n\nconst makeSelectGridAssets = () =>\n createSelector(selectLinkAssetsData, ({ assetsGrid }) => assetsGrid);\n\nexport { makeSelectLinkAssets, makeSelectGridAssets };\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { AgGridReact, AgGridColumn } from 'ag-grid-react';\nimport { LicenseManager } from 'ag-grid-enterprise';\nimport 'ag-grid-enterprise';\nimport 'ag-grid-community/dist/styles/ag-grid.css';\nimport 'ag-grid-community/dist/styles/ag-theme-alpine.css';\n\nLicenseManager.setLicenseKey(\n 'Using_this_AG_Grid_Enterprise_key_( AG-040843 )_in_excess_of_the_licence_granted_is_not_permitted___Please_report_misuse_to_( legal@ag-grid.com )___For_help_with_changing_this_key_please_contact_( info@ag-grid.com )___( Global Vertical Innovations, LLC )_is_granted_a_( Multiple Applications )_Developer_License_for_( 1 ))_Front-End_JavaScript_developer___All_Front-End_JavaScript_developers_need_to_be_licensed_in_addition_to_the_ones_working_with_AG_Grid_Enterprise___This_key_has_not_been_granted_a_Deployment_License_Add-on___This_key_works_with_AG_Grid_Enterprise_versions_released_before_( 11 May 2024 )____[v2]_MTcxNTM4MjAwMDAwMA==d035e6c32ae72202e23beccd712ab105'\n);\n\nconst getAgGridProps = (rowData = []) => {\n return {\n defaultColDef: {\n enableRowGroup: false,\n enablePivot: false,\n enableValue: false,\n width: 100,\n sortable: false,\n resizable: false,\n filter: false,\n },\n headerHeight: 32,\n rowHeight: 32,\n // rowSelection: 'multiple',\n // suppressRowClickSelection: true,\n rowData,\n pivotPanelShow: 'never',\n\n // onRowSelected: (row) => console.log(row),\n\n // style color row\n rowClassRules: {\n 'new-row': ({ data }) => data?.state === 'Added',\n 'old-row': ({ data }) => !data?.state !== 'Added',\n },\n };\n};\n\nconst GridLinkAssets = ({ columns, rowData, dragOver = false }) => {\n return (\n
\n \n \n
\n \n );\n};\n\nGridLinkAssets.prototype = {\n columns: PropTypes.array,\n rowData: PropTypes.array,\n dragOver: PropTypes.bool,\n};\n\nexport default GridLinkAssets;\n","import React from 'react';\nimport { Card, Avatar, Row, Typography, Col, Tooltip } from 'antd';\nimport { ShareAltOutlined } from '@ant-design/icons';\n\nimport { Draggable } from 'react-beautiful-dnd';\n\nconst ItemLinkAsset = ({ item }) => {\n return (\n \n {(provided, snapshot) => (\n \n \n \n \n \n \n \n \n \n \n \n \n {item?.assetName?.substring(0, 11)}\n \n \n \n \n )}\n \n );\n};\n\nexport default ItemLinkAsset;\n","import React from 'react';\n\nimport { message, Spin, Typography } from 'antd';\nimport { CloseCircleOutlined, InfoCircleOutlined } from '@ant-design/icons';\n\nexport const messageAddSameAsset = (setStatusDragDrop, content) => {\n message.info({\n content: content,\n duration: 1.5,\n style: {\n fontSize: 16,\n },\n });\n setStatusDragDrop({ isExistAsset: false });\n};\n\nexport const messageSelfAsset = (setStatusDragDrop, content) => {\n message.info({\n content: content,\n duration: 1.5,\n style: {\n fontSize: 16,\n },\n });\n setStatusDragDrop({ isSelfAsset: false });\n};\n\nexport const messageSuccessUpdate = (content) => {\n message.success(content);\n};\n\nexport const DeleteAssetGrid = ({ data, handleDeleteAssetGrid, nameGrid }) => {\n return (\n handleDeleteAssetGrid(data, nameGrid)}\n />\n );\n};\n\nexport const Loading = ({ className, size = 'default' }) => {\n return (\n
\n \n
\n );\n};\n\nexport const NotFound = () => {\n return (\n
\n
\n \n
\n \n Not Found\n \n
\n );\n};\n","import moment from 'moment';\nimport * as typesAsset from './controller/constants';\n\nimport * as actionsLinkAssets from './controller/actions';\n\nfunction dateFormatter(params) {\n return moment(params.value).format('MM/DD/YYYY');\n}\n\nconst columnFields = [\n {\n key: '0',\n field: 'assetName',\n width: 160,\n // checkboxSelection: true,\n // headerCheckboxSelection: true,\n menuTabs: [],\n },\n { key: '1', field: 'fileType', width: 110, menuTabs: [] },\n {\n key: '2',\n field: 'dateAssigned',\n cellRendererFramework: dateFormatter,\n width: 140,\n menuTabs: [],\n },\n];\n\n// Order item after dragdrop\nconst reorder = (assets, source, destination) => {\n const startIndex = assets.findIndex((item) => item.id === source.index);\n const endIndex = assets.findIndex((item) => item.id === destination.index);\n\n const result = Array.from(assets);\n const [removedAsset] = result.splice(startIndex, 1);\n result.splice(endIndex, 0, removedAsset);\n\n return result;\n};\n\nconst handleDragEnd = ({\n dispatch,\n setStatusDragDrop,\n assetsSearch,\n idAsset,\n assetsGridState,\n ...props\n}) => {\n const { destination, source } = props;\n\n // parentGridAssets: This is a grid assets contain the selected asset\n // childGridAssets: This is a grid assets inside the selected asset\n const { parentGridAssets, childGridAssets } = assetsGridState;\n\n if (!destination) return;\n\n if (destination.index === source.index) return;\n\n // Dragdrop same line\n if (destination.droppableId === source.droppableId) {\n const assetsAfterDrop = reorder(assetsSearch, source, destination);\n\n dispatch({\n type: typesAsset.DRAG_DROP_ASSETS,\n payload: {\n assets: assetsAfterDrop,\n },\n });\n }\n\n // Dragdrop asset to two grids\n else {\n // Table grid parent\n if (destination.droppableId === 'droppable-grid-parent') {\n const existingAssetIndex = parentGridAssets.findIndex(\n (asset) => asset.assetId === source.index\n );\n\n if (idAsset === source.index) {\n setStatusDragDrop({ isSelfAsset: true });\n return;\n }\n\n if (existingAssetIndex !== -1) {\n setStatusDragDrop({ isExistAsset: true });\n return;\n }\n\n const { assetName, id, assetType } = assetsSearch.find(\n (asset) => asset.id === source.index\n );\n\n // Append fileType to commit with field in AgGrid for rendering.\n const movedAsset = {\n id: 0, // 0: addition\n assetId: id,\n assetName: assetName,\n fileType: assetType,\n associationType: 1, // 1: Parent grid\n state: 'Added',\n };\n\n const params = {\n id: idAsset,\n assetAssociation: [movedAsset],\n };\n\n dispatch(actionsLinkAssets.updateLinkAsset(params));\n\n dispatch({\n type: typesAsset.MOVE_TO_PARENT_GRID,\n payload: { movedAsset },\n });\n }\n\n // Table grid child\n if (destination.droppableId === 'droppable-grid-child') {\n const existingAssetIndex = childGridAssets.findIndex(\n (asset) => asset.assetId === source.index\n );\n\n if (idAsset === source.index) {\n setStatusDragDrop({ isSelfAsset: true });\n return;\n }\n\n if (existingAssetIndex !== -1) {\n setStatusDragDrop({ isExistAsset: true });\n return;\n }\n\n const { assetName, id, assetType } = assetsSearch.find(\n (asset) => asset.id === source.index\n );\n\n // Append fileType to commit with field in AgGrid for rendering.\n const movedAsset = {\n id: 0, // 0: addition\n assetId: id,\n assetName: assetName,\n fileType: assetType,\n associationType: 2, // 2: Child grid\n state: 'Added',\n };\n\n const params = {\n id: idAsset,\n assetAssociation: [movedAsset],\n };\n\n dispatch(actionsLinkAssets.updateLinkAsset(params));\n\n dispatch({\n type: typesAsset.MOVE_TO_CHILD_GRID,\n payload: { movedAsset },\n });\n }\n }\n};\n\nexport { dateFormatter, reorder, handleDragEnd, columnFields };\n","import React, { useState, useEffect, useReducer, useMemo } from 'react';\nimport { Row, Input, Typography, Pagination, Button, Col, Tooltip } from 'antd';\nimport { DragDropContext, Droppable } from 'react-beautiful-dnd';\nimport { QuestionCircleTwoTone, ArrowLeftOutlined } from '@ant-design/icons';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { injectIntl, FormattedMessage } from 'react-intl';\nimport Messages from 'i18n/messages/branded-assets-products';\n\nimport { RIBBON_VIEW } from 'static/Constants';\nimport * as ribbonSelector from '@redux/ribbon/selectors';\nimport * as actionsLinkAssets from './controller/actions';\nimport * as selectorsLinkAssets from './controller/selectors';\nimport gridSelector from 'common/components/grid-view/controllers/selectors';\nimport * as assetFullViewSelector from 'pages/asset-full-view/controllers/selectors';\nimport * as actionsAsset from 'pages/home/ribbon/asset-full/controllers/actions';\n\nimport { dialogFunction } from 'common/components/index';\nimport GridLinkAssets from './GridLinkAssets';\nimport ItemLinkAsset from './ItemLinkAsset';\nimport {\n messageAddSameAsset,\n messageSuccessUpdate,\n messageSelfAsset,\n DeleteAssetGrid,\n Loading,\n NotFound,\n} from './Helper';\nimport { handleDragEnd, columnFields } from './utils';\n\nimport './LinkAssets.less';\n\nconst { Search } = Input;\nconst { Text, Title } = Typography;\n\nconst LinkAssets = ({ intl }) => {\n const dispatch = useDispatch();\n\n const { status, assetsSearch, pageNumber, pageSize, totalItems, error } =\n useSelector(selectorsLinkAssets.makeSelectLinkAssets());\n\n const i18nMessage = useMemo(\n () => [\n {\n message: intl.formatMessage({\n id: 'Taco.asset.linkAsset.messageSameAsset',\n }),\n },\n {\n message: intl.formatMessage({\n id: 'Taco.asset.linkAsset.messageSelfAsset',\n }),\n },\n {\n message: intl.formatMessage({\n id: 'Taco.asset.linkAsset.messageDeleteAssetGrid',\n }),\n },\n {\n message: intl.formatMessage({\n id: 'Taco.asset.linkAsset.updateMessage',\n }),\n },\n ],\n [intl]\n );\n\n const assetsGridState = useSelector(\n selectorsLinkAssets.makeSelectGridAssets()\n );\n const {\n status: statusGrid,\n error: errorGrid,\n statusUpdate,\n parentGridAssets,\n childGridAssets,\n additionParentAssets,\n additionChildAssets,\n deletedParentAssets,\n deletedChildAssets,\n } = assetsGridState;\n\n const selectedAsset = useSelector(\n gridSelector.makeSelectItemCurrentSelection()\n );\n const view = useSelector(ribbonSelector.selectRibbon());\n const digitalAsset = useSelector(assetFullViewSelector.assetDataLoading());\n\n const idAsset =\n view === RIBBON_VIEW.ASSET_FULL_VIEW.NAME\n ? digitalAsset?.id\n : selectedAsset?.id;\n\n const [valueSearch, setValueSearch] = useState('');\n const [statusDragDrop, setStatusDragDrop] = useReducer(\n (state, action) => ({ ...state, ...action }),\n { isExistAsset: false, isSelfAsset: false }\n );\n const { isExistAsset, isSelfAsset } = statusDragDrop;\n\n useEffect(() => {\n if (isExistAsset) {\n messageAddSameAsset(setStatusDragDrop, i18nMessage[0].message);\n }\n\n if (isSelfAsset) {\n messageSelfAsset(setStatusDragDrop, i18nMessage[1].message);\n }\n\n return;\n }, [i18nMessage, isExistAsset, isSelfAsset]);\n\n useEffect(() => {\n if (statusUpdate === 'success') {\n messageSuccessUpdate(i18nMessage[3].message);\n dispatch(actionsLinkAssets.fetchAssetsGrid(idAsset));\n }\n\n return;\n }, [dispatch, i18nMessage, idAsset, statusUpdate]);\n\n useEffect(() => {\n if (!idAsset) return;\n\n dispatch(actionsLinkAssets.fetchAssetsGrid(idAsset));\n }, [dispatch, idAsset]);\n\n const handleDeleteAssetGrid = (data, nameGrid) => {\n const associationType = nameGrid === 'parent' ? 1 : 2;\n\n const params = {\n id: idAsset,\n assetAssociation: [{ ...data, associationType, state: 'Deleted' }],\n };\n\n dialogFunction({\n type: 'warn',\n content: i18nMessage[2].message,\n onOk: () => {\n dispatch(actionsLinkAssets.updateLinkAsset(params));\n },\n });\n };\n\n // Add col in parent grid for deleting assets\n const colDeleteGridParent = {\n key: 3,\n field: '',\n flex: 1,\n menuTabs: [],\n\n cellRendererFramework: ({ data }) => (\n \n ),\n };\n\n // Add col in child grid for deleting assets\n const colDeleteGridChild = {\n key: 3,\n field: '',\n flex: 1,\n menuTabs: [],\n cellRendererFramework: ({ data }) => (\n \n ),\n };\n\n const handleSearchAssets = (_, event) => {\n if (!valueSearch) {\n event.preventDefault();\n } else {\n dispatch(\n actionsLinkAssets.searchItemsLinkAsset(\n pageSize,\n pageNumber,\n valueSearch\n )\n );\n }\n };\n\n const handleChangePagination = (page, _) => {\n dispatch(\n actionsLinkAssets.searchItemsLinkAsset(pageSize, page, valueSearch)\n );\n };\n\n return (\n {\n handleDragEnd({\n assetsSearch: assetsSearch,\n idAsset,\n assetsGridState: assetsGridState,\n dispatch,\n setStatusDragDrop,\n ...propsDragDrop,\n });\n }}\n >\n \n
\n }\n onClick={() => dispatch(actionsAsset.disableModeLinkAsset())}\n >\n Back to\n \n
\n
\n Search assets\n }\n color='#2db7f5'\n >\n \n \n
\n setValueSearch(event.target.value)}\n onSearch={handleSearchAssets}\n defaultValue={valueSearch}\n />\n
\n {status === 'idle' ? null : status === 'loading' ? (\n \n ) : status === 'success' ? (\n <>\n \n {(dropProvided) => (\n <>\n \n {assetsSearch.length === 0 ? (\n \n ) : (\n assetsSearch?.map((item) => (\n \n ))\n )}\n \n {assetsSearch?.length !== 0 ? (\n \n ) : null}\n \n )}\n \n \n ) : (\n {error} \n )}\n {statusGrid === 'idle' ? null : statusGrid === 'loading' ? (\n \n ) : statusGrid === 'success' ? (\n <>\n \n Contains\n \n \n {(dropProvided, snapshot) => (\n <>\n \n \n \n \n \n Total Rows: {parentGridAssets.length}\n \n \n \n Added Rows: {additionParentAssets.length}\n \n \n \n \n Deleted Rows: {deletedParentAssets.length}\n \n \n \n \n )}\n \n \n Included In\n \n \n {(dropProvided, snapshot) => (\n <>\n \n \n \n \n \n Total Rows: {childGridAssets.length}\n \n \n Added Rows: {additionChildAssets.length}\n \n \n \n Deleted Rows: {deletedChildAssets.length}\n \n \n \n \n )}\n \n \n ) : (\n {errorGrid} \n )}\n\n {statusUpdate === 'loading' ? (\n \n ) : null}\n \n );\n};\n\nexport default injectIntl(LinkAssets);\n","import * as types from './constants';\n\nexport function searchItemsLinkAsset(pageSize, pageNumber, searchText) {\n return {\n type: types.SEARCH_ITEMS_LINK_ASSETS,\n pageSize: pageSize,\n pageIndex: pageNumber,\n search: {\n searchText,\n },\n };\n}\n\nexport function searchItemsLinkAssetSuccess(assets, total) {\n return {\n type: types.SEARCH_ITEMS_LINK_ASSETS_SUCCESS,\n assets,\n total,\n };\n}\n\nexport function searchItemsLinkAssetFail(error) {\n return {\n type: types.SEARCH_ITEMS_LINK_ASSETS_FAIL,\n error,\n };\n}\n\nexport function fetchAssetsChangePagination(pageSize, pageNumber, search) {\n return {\n type: types.FETCH_ASSETS_CHANGE_PAGINATION,\n pageSize: pageSize,\n pageIndex: pageNumber,\n 'Search.SearchText': search,\n };\n}\n\nexport function fetchAssetsChangePaginationSuccess(assets, total) {\n return {\n type: types.FETCH_ASSETS_CHANGE_PAGINATION_SUCCESS,\n assets,\n total,\n };\n}\n\nexport function fetchAssetsChangePaginationFail(error) {\n return {\n type: types.SEARCH_ITEMS_LINK_ASSETS_FAIL,\n error,\n };\n}\n\nexport function fetchAssetsGrid(id) {\n return { type: types.FETCH_ASSETS_GRID, id };\n}\n\nexport function fetchAssetsGridSuccess(payload) {\n return { type: types.FETCH_ASSETS_GRID_SUCCESS, payload };\n}\n\nexport function fetchAssetsGridFail(error) {\n return { type: types.FETCH_ASSETS_GRID_ERROR, error };\n}\n\nexport function updateLinkAsset(params) {\n return { type: types.UPDATE_LINK_ASSET, payload: { params } };\n}\n\nexport function updateLinkAssetSuccess() {\n return { type: types.UPDATE_LINK_ASSET_SUCCESS };\n}\n\nexport function updateLinkAssetFail(error) {\n return { type: types.UPDATE_LINK_ASSET_FAIL, error };\n}\n\nexport function resetLinkAsset() {\n return { type: types.RESET_LINK_ASSET };\n}\n","export const SEARCH_ITEMS_LINK_ASSETS = 'SEARCH_ITEMS_LINK_ASSETS';\nexport const SEARCH_ITEMS_LINK_ASSETS_SUCCESS =\n 'SEARCH_ITEMS_LINK_ASSETS_SUCCESS';\nexport const SEARCH_ITEMS_LINK_ASSETS_FAIL = 'SEARCH_ITEMS_LINK_ASSETS_FAIL';\n\nexport const FETCH_ASSETS_CHANGE_PAGINATION = 'FETCH_ASSETS_CHANGE_PAGINATION';\nexport const FETCH_ASSETS_CHANGE_PAGINATION_SUCCESS =\n 'FETCH_ASSETS_CHANGE_PAGINATION_SUCCESS';\nexport const FETCH_ASSETS_CHANGE_PAGINATION_FAIL =\n 'FETCH_ASSETS_CHANGE_PAGINATION_FAIL';\n\nexport const FETCH_ASSETS_GRID = 'FETCH_ASSETS_GRID';\nexport const FETCH_ASSETS_GRID_SUCCESS = 'FETCH_ASSETS_GRID_SUCCESS';\nexport const FETCH_ASSETS_GRID_ERROR = 'FETCH_ASSETS_GRID_ERROR';\n\nexport const DRAG_DROP_ASSETS = 'DRAG_DROP_ASSETS';\nexport const MOVE_TO_PARENT_GRID = 'MOVE_TO_PARENT_GRID';\nexport const MOVE_TO_CHILD_GRID = 'MOVE_TO_CHILD_GRID';\nexport const DELETE_ASSET_IN_PARENT = 'DELETE_ASSET_IN_PARENT';\nexport const DELETE_ASSET_IN_CHILD = 'DELETE_ASSET_IN_CHILD';\n\nexport const UPDATE_LINK_ASSET = 'UPDATE_LINK_ASSET';\nexport const UPDATE_LINK_ASSET_SUCCESS = 'UPDATE_LINK_ASSET_SUCCESS';\nexport const UPDATE_LINK_ASSET_FAIL = 'UPDATE_LINK_ASSET_FAIL';\n\nexport const RESET_LINK_ASSET = 'RESET_LINK_ASSET';\n","import produce from 'immer';\nimport * as types from './constants';\n\nexport const initialState = {\n linkAssetsState: {\n status: 'idle',\n pageNumber: 1,\n pageSize: 4,\n assetsSearch: [],\n totalItems: 0,\n error: null,\n },\n assetsGrid: {\n status: 'idle',\n error: null,\n parentGridAssets: [],\n childGridAssets: [],\n statusUpdate: 'idle',\n errorUpdate: null,\n /*\n * This is the container hold assets that delete and addition in initial grid asset.\n * To know what asset in initial grid asset is change.\n */\n additionParentAssets: [],\n additionChildAssets: [],\n deletedParentAssets: [],\n deletedChildAssets: [],\n },\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst assetReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.SEARCH_ITEMS_LINK_ASSETS:\n case types.FETCH_ASSETS_CHANGE_PAGINATION:\n draft['linkAssetsState'].status = 'loading';\n draft['linkAssetsState'].pageNumber = action.pageIndex;\n draft['linkAssetsState'].pageSize = action.pageSize;\n draft['linkAssetsState'].assetsSearch = [];\n draft['assetsGrid'].statusUpdate = 'idle';\n break;\n\n case types.SEARCH_ITEMS_LINK_ASSETS_SUCCESS:\n case types.FETCH_ASSETS_CHANGE_PAGINATION_SUCCESS:\n draft['linkAssetsState'].status = 'success';\n draft['linkAssetsState'].assetsSearch = action.assets;\n draft['linkAssetsState'].totalItems = action.total;\n draft['linkAssetsState'].error = null;\n draft['assetsGrid'].statusUpdate = 'idle';\n break;\n\n case types.SEARCH_ITEMS_LINK_ASSETS_FAIL:\n case types.FETCH_ASSETS_CHANGE_PAGINATION_FAIL:\n draft['assetsGrid'].status = 'loading';\n draft['linkAssetsState'].status = 'error';\n draft['linkAssetsState'].error = action.error;\n draft['assetsGrid'].statusUpdate = 'idle';\n\n break;\n\n case types.FETCH_ASSETS_GRID:\n draft['assetsGrid'].statusUpdate = 'idle';\n break;\n\n case types.FETCH_ASSETS_GRID_SUCCESS:\n draft['assetsGrid'].status = 'success';\n draft['assetsGrid'].statusUpdate = 'idle';\n draft['assetsGrid'].parentGridAssets = action.payload.containViewModel;\n draft['assetsGrid'].childGridAssets =\n action.payload.includedInViewModel;\n draft['assetsGrid'].additionParentAssets = [];\n draft['assetsGrid'].additionChildAssets = [];\n draft['assetsGrid'].deletedParentAssets = [];\n draft['assetsGrid'].deletedChildAssets = [];\n\n break;\n\n case types.FETCH_ASSETS_GRID_ERROR:\n draft['assetsGrid'].status = 'error';\n draft['assetsGrid'].error = action.error;\n draft['assetsGrid'].additionParentAssets = [];\n draft['assetsGrid'].additionChildAssets = [];\n draft['assetsGrid'].deletedParentAssets = [];\n draft['assetsGrid'].deletedChildAssets = [];\n break;\n\n case types.DRAG_DROP_ASSETS:\n draft['linkAssetsState'].assetsSearch = action.payload.assets;\n break;\n\n case types.MOVE_TO_PARENT_GRID:\n draft['assetsGrid'].parentGridAssets.push(action.payload.movedAsset);\n draft['assetsGrid'].additionParentAssets.push(\n action.payload.movedAsset\n );\n break;\n\n case types.MOVE_TO_CHILD_GRID:\n draft['assetsGrid'].childGridAssets.push(action.payload.movedAsset);\n draft['assetsGrid'].additionChildAssets.push(action.payload.movedAsset);\n break;\n\n case types.DELETE_ASSET_IN_PARENT: {\n const index = draft['assetsGrid'].parentGridAssets.findIndex(\n (asset) => asset.assetId === action.payload.id\n );\n const indexAddition = draft[\n 'assetsGrid'\n ].additionParentAssets.findIndex(\n (asset) => asset.assetId === action.payload.id\n );\n let asset = draft['assetsGrid'].parentGridAssets.find(\n (asset) => asset.assetId === action.payload.id\n );\n asset = { ...asset, associationType: 1, state: 'Deleted' };\n\n // not find asset in additionAsset\n if (indexAddition === -1) {\n draft['assetsGrid'].deletedParentAssets.push(asset);\n }\n\n if (indexAddition !== -1) {\n draft['assetsGrid'].additionParentAssets.splice(indexAddition, 1);\n }\n\n draft['assetsGrid'].parentGridAssets.splice(index, 1);\n break;\n }\n\n case types.DELETE_ASSET_IN_CHILD: {\n const index = draft['assetsGrid'].childGridAssets.findIndex(\n (asset) => asset.assetId === action.payload.id\n );\n const indexAddition = draft['assetsGrid'].additionChildAssets.findIndex(\n (asset) => asset.assetId === action.payload.id\n );\n let asset = draft['assetsGrid'].childGridAssets.find(\n (asset) => asset.assetId === action.payload.id\n );\n asset = { ...asset, associationType: 2, state: 'Deleted' };\n\n if (indexAddition === -1) {\n draft['assetsGrid'].deletedChildAssets.push(asset);\n }\n\n if (indexAddition !== -1) {\n draft['assetsGrid'].additionChildAssets.splice(indexAddition, 1);\n }\n\n draft['assetsGrid'].childGridAssets.splice(index, 1);\n break;\n }\n\n case types.UPDATE_LINK_ASSET:\n // draft['linkAssetsState'].status = 'success';\n draft['assetsGrid'].statusUpdate = 'loading';\n break;\n\n case types.UPDATE_LINK_ASSET_SUCCESS:\n draft['assetsGrid'].statusUpdate = 'success';\n draft['assetsGrid'].additionParentAssets = [];\n draft['assetsGrid'].additionChildAssets = [];\n draft['assetsGrid'].deletedParentAssets = [];\n draft['assetsGrid'].deletedChildAssets = [];\n break;\n\n case types.UPDATE_LINK_ASSET_FAIL:\n draft['assetsGrid'].statusUpdate = 'error';\n draft['assetsGrid'].errorUpdate = action.error;\n draft['assetsGrid'].additionParentAssets = [];\n draft['assetsGrid'].additionChildAssets = [];\n draft['assetsGrid'].deletedParentAssets = [];\n draft['assetsGrid'].deletedChildAssets = [];\n break;\n\n case types.RESET_LINK_ASSET:\n draft['linkAssetsState'].assetsSearch = [];\n draft['linkAssetsState'].status = 'idle';\n draft['assetsGrid'].statusUpdate = 'idle';\n draft['assetsGrid'].additionParentAssets = [];\n draft['assetsGrid'].additionChildAssets = [];\n draft['assetsGrid'].deletedParentAssets = [];\n draft['assetsGrid'].deletedChildAssets = [];\n break;\n }\n });\n\nexport default assetReducer;\n","import { put, call, takeLatest, all } from 'redux-saga/effects';\n\nimport * as types from './constants';\nimport * as actions from './actions';\n\nimport * as services from 'services/assetProduct';\n\nexport function* searchItemsLinkAssets(payload) {\n try {\n const params = {\n type: payload.type,\n PageSize: payload.pageSize,\n PageIndex: payload.pageIndex,\n search: payload.search,\n };\n\n const response = yield call(services.getAssetList, params);\n yield put(\n actions.searchItemsLinkAssetSuccess(\n response.data.gridData,\n response.data.paging.totalRecord\n )\n );\n } catch (error) {\n yield put(actions.searchItemsLinkAssetFail(error));\n }\n}\n\nexport function* fetchAssetsGrid(payload) {\n try {\n const response = yield call(services.getAssetAssociation, payload.id);\n if (response.isSuccess) {\n yield put(actions.fetchAssetsGridSuccess(response.data));\n } else {\n yield put(actions.fetchAssetsGridFail(response.message));\n }\n } catch (error) {\n yield put(actions.fetchAssetsGridFail(error));\n }\n}\n\nexport function* updateLinkAsset(action) {\n try {\n const response = yield call(\n services.updateLinkAsset,\n action.payload.params\n );\n if (response.isSuccess) {\n yield put(actions.updateLinkAssetSuccess());\n } else {\n yield put(actions.updateLinkAssetFail(response.message));\n }\n } catch (error) {\n yield put(actions.updateLinkAssetFail(error));\n }\n}\n\nfunction* watchAll() {\n yield all([\n takeLatest(types.SEARCH_ITEMS_LINK_ASSETS, searchItemsLinkAssets),\n takeLatest(types.FETCH_ASSETS_GRID, fetchAssetsGrid),\n takeLatest(types.UPDATE_LINK_ASSET, updateLinkAsset),\n ]);\n}\n\nexport default watchAll;\n","import * as types from './constants';\n\nexport const showLoading = () => {\n return {\n type: types.SHOW_LOADING,\n };\n};\n\nexport function getDigitalAssetList(\n pageSize,\n pageNumber,\n search,\n primaryFieldsOnly,\n filters,\n mediaType,\n isFavoriteRoute,\n advancedSearchContainer,\n searchCategory,\n fromDate\n) {\n return {\n type: types.GET_DIGITAL_ASSET_LIST,\n pageSize: pageSize,\n pageIndex: pageNumber,\n search,\n primaryFieldsOnly,\n filters,\n mediaType,\n isFavoriteRoute,\n advancedSearchContainer,\n searchCategory,\n fromDate,\n };\n}\n\nexport function getDigitalAssetForMemberList({\n pageSize,\n pageNumber,\n search,\n primaryFieldsOnly,\n filters,\n mediaType,\n isFavoriteRoute,\n advancedSearchContainer,\n searchCategory,\n fromDate,\n}) {\n return {\n type: types.GET_DIGITAL_ASSET_LIST,\n pageSize: pageSize,\n pageIndex: pageNumber,\n search,\n primaryFieldsOnly,\n filters,\n mediaType,\n isFavoriteRoute,\n advancedSearchContainer,\n searchCategory,\n fromDate,\n };\n}\n\nexport function getDigitalAssetListSuccess(assets, total) {\n return {\n type: types.GET_DIGITAL_ASSET_LIST_SUCCESS,\n assets,\n total,\n };\n}\n\nexport function getDigitalAssetListError(error) {\n return {\n type: types.GET_DIGITAL_ASSET_LIST_ERROR,\n error,\n };\n}\n\nexport function gridDigitalAssetColumnInfo(gridName) {\n return {\n type: types.DIGITAL_ASSET_GRID_COLUMN_INFO,\n gridName,\n };\n}\n\nexport function gridDigitalAssetColumnInfoSuccess(columns) {\n return {\n type: types.DIGITAL_ASSET_GRID_COLUMN_INFO_SUCCESS,\n columns,\n };\n}\n\nexport function gridDigitalAssetColumnInfoError(error) {\n return {\n type: types.DIGITAL_ASSET_GRID_COLUMN_INFO_ERROR,\n };\n}\n\nexport function getDigitalAssetShortDetail(id) {\n return {\n type: types.GET_DIGITAL_ASSET_SHORT_DETAIL,\n id,\n };\n}\n\nexport function getDigitalAssetShortDetailSuccess(data) {\n return {\n type: types.GET_DIGITAL_ASSET_SHORT_DETAIL_SUCCESS,\n data,\n };\n}\n\nexport function getDigitalAssetShortDetailError(error) {\n return {\n type: types.GET_DIGITAL_ASSET_SHORT_DETAIL_ERROR,\n error,\n };\n}\n\nexport const updateCacheImage = (newCache) => {\n return {\n type: types.UPDATE_CACHE_IMAGE,\n payload: newCache,\n };\n};\n\nexport const deleteAssets = (assetIds) => {\n return {\n type: types.DELETE_ASSETS,\n payload: {\n assetIds,\n },\n };\n};\n\nexport const deleteAssetsSuccess = () => {\n return {\n type: types.DELETED_ASSETS_SUCCESS,\n };\n};\n\nexport const deleteAssetsError = (message) => {\n return {\n type: types.DELETED_ASSETS_ERROR,\n payload: {\n error: message,\n },\n };\n};\n\nexport const resetDeleteAssets = () => {\n return { type: types.RESET_DELETE_ASSETS };\n};\n\nexport function updateAssetTypePane(params) {\n return {\n type: types.UPDATE_ASSET_TYPE_PANE,\n params,\n };\n}\n\nexport function updateAssetTypePaneSuccess() {\n return {\n type: types.UPDATE_ASSET_TYPE_PANE_SUCCESS,\n };\n}\n\nexport function updateAssetTypePaneError(error) {\n return {\n type: types.UPDATE_ASSET_TYPE_PANE_ERROR,\n error,\n };\n}\n\n// Assets for member\nexport function getAssetsForMember(params) {\n return {\n type: types.GET_ASSETS_FOR_MEMBER,\n params,\n };\n}\n\nexport function getAssetsForMemberSuccess(data) {\n return {\n type: types.GET_ASSETS_FOR_MEMBER_SUCCESS,\n data,\n };\n}\n\nexport function getAssetsForMemberError(error) {\n return {\n type: types.GET_ASSETS_FOR_MEMBER_ERROR,\n error,\n };\n}\n\nexport function getColumnsAssetsForMember(gridName) {\n return {\n type: types.GET_COLUMNS_ASSETS_FOR_MEMBER,\n gridName,\n };\n}\n\nexport function getColumnsAssetsForMemberSuccess(columns) {\n return {\n type: types.GET_COLUMNS_ASSETS_FOR_MEMBER_SUCCESS,\n columns,\n };\n}\n\nexport function getColumnsAssetsForMemberError(error) {\n return {\n type: types.GET_COLUMNS_ASSETS_FOR_MEMBER_ERROR,\n error,\n };\n}\n\nexport function saveIdMember(id) {\n return {\n type: types.SAVE_ID_MEMBER,\n id,\n };\n}\n\nexport const toggleAssetNew = (status) => ({\n type: types.TOGGLE_ASSET_NEW,\n isDisplayAssetNew: status,\n});\n\nexport const cacheFromDate = (fromDate) => ({\n type: types.CACHE_ASSET_FROM_DATE,\n fromDate,\n});\n\nexport const updateLatestGetNewAsset = () => ({\n type: types.UPDATE_LATEST_GET_NEW_ASSET,\n});\n\nexport const updateLatestGetUnmatchAsset = () => ({\n type: types.UPDATE_LATEST_GET_UNMATCH_ASSET,\n});\n\nexport const toggleAssetUnmatch = (status) => ({\n type: types.TOGGLE_ASSET_UNMATCH,\n isDisplayAssetNew: status,\n});\n","export const SHOW_LOADING = 'SHOW_LOADING';\nexport const GET_DIGITAL_ASSET_LIST = 'GET_DIGITAL_ASSET_LIST';\nexport const GET_DIGITAL_ASSET_FOR_MEMBER_LIST =\n 'GET_DIGITAL_ASSET_FOR_MEMBER_LIST';\nexport const GET_DIGITAL_ASSET_LIST_SUCCESS = 'GET_DIGITAL_ASSET_LIST_SUCCESS';\nexport const GET_DIGITAL_ASSET_LIST_ERROR = 'GET_DIGITAL_ASSET_LIST_ERROR';\n\nexport const DIGITAL_ASSET_GRID_COLUMN_INFO = 'DIGITAL_ASSET_GRID_COLUMN_INFO';\nexport const DIGITAL_ASSET_GRID_COLUMN_INFO_SUCCESS =\n 'DIGITAL_ASSET_GRID_COLUMN_INFO_SUCCESS';\nexport const DIGITAL_ASSET_GRID_COLUMN_INFO_ERROR =\n 'DIGITAL_ASSET_GRID_COLUMN_INFO_ERROR';\nexport const GET_DIGITAL_ASSET_SHORT_DETAIL = 'GET_DIGITAL_ASSET_SHORT_DETAIL';\nexport const GET_DIGITAL_ASSET_SHORT_DETAIL_SUCCESS =\n 'GET_DIGITAL_ASSET_SHORT_DETAIL_SUCCESS';\nexport const GET_DIGITAL_ASSET_SHORT_DETAIL_ERROR =\n 'GET_DIGITAL_ASSET_SHORT_DETAIL_ERROR';\n\nexport const RELOAD_PAGE = 'RELOAD_PAGE';\nexport const UPDATE_CACHE_IMAGE = 'UPDATE_CACHE_IMAGE';\n\nexport const DELETE_ASSETS = 'DELETE_ASSETS';\nexport const DELETED_ASSETS_SUCCESS = 'DELETED_ASSETS_SUCCESS';\nexport const DELETED_ASSETS_ERROR = 'DELETED_ASSETS_ERROR';\nexport const RESET_DELETE_ASSETS = 'RESET_DELETE_ASSETS';\nexport const UPDATE_ASSET_TYPE_PANE = 'UPDATE_ASSET_TYPE_PANE';\nexport const UPDATE_ASSET_TYPE_PANE_SUCCESS = 'UPDATE_ASSET_TYPE_PANE_SUCCESS';\nexport const UPDATE_ASSET_TYPE_PANE_ERROR = 'UPDATE_ASSET_TYPE_PANE_ERROR';\n\n// Assets for members\nexport const GET_ASSETS_FOR_MEMBER = 'GET_ASSETS_FOR_MEMBER';\nexport const GET_ASSETS_FOR_MEMBER_SUCCESS = 'GET_ASSETS_FOR_MEMBER_SUCCESS';\nexport const GET_ASSETS_FOR_MEMBER_ERROR = 'GET_ASSETS_FOR_MEMBER_ERROR';\n\nexport const GET_COLUMNS_ASSETS_FOR_MEMBER = 'GET_COLUMNS_ASSETS_FOR_MEMBER';\nexport const GET_COLUMNS_ASSETS_FOR_MEMBER_SUCCESS =\n 'GET_COLUMNS_ASSETS_FOR_MEMBER_SUCCESS';\nexport const GET_COLUMNS_ASSETS_FOR_MEMBER_ERROR =\n 'GET_COLUMNS_ASSETS_FOR_MEMBER_ERROR';\n\nexport const SAVE_ID_MEMBER = 'SAVE_ID_MEMBER';\nexport const TOGGLE_ASSET_NEW = 'TOGGLE_ASSET_NEW';\nexport const CACHE_ASSET_FROM_DATE = 'CACHE_ASSET_FROM_DATE';\nexport const UPDATE_LATEST_GET_NEW_ASSET = 'UPDATE_LATEST_GET_NEW_ASSET';\nexport const UPDATE_LATEST_GET_UNMATCH_ASSET =\n 'UPDATE_LATEST_GET_UNMATCH_ASSET';\nexport const TOGGLE_ASSET_UNMATCH = 'TOGGLE_ASSET_UNMATCH';\n","import produce from 'immer';\nimport * as types from './constants';\n\n// initial state\nexport const initialState = {\n loading: false,\n error: false,\n assets: [],\n total: 0,\n pageSize: 20,\n pageNumber: 1,\n search: '',\n columns: [],\n gridName: '',\n assetData: null,\n loadingDetail: false,\n statusDelete: 'idle',\n cachedImagesVersion: {},\n\n assetsForMember: {\n loading: false,\n pageIndex: 1,\n pageSize: 20,\n totalItems: 0,\n data: [],\n columns: [],\n memberId: null,\n },\n editTypeLoading: false,\n isDisplayAssetNew: false,\n cachedFromDate: null,\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst assetReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.SHOW_LOADING:\n draft.loading = true;\n break;\n case types.GET_DIGITAL_ASSET_LIST:\n draft.loading = true;\n draft.error = false;\n draft.pageSize = action.pageSize;\n draft.pageNumber = action.pageIndex;\n draft.search = action.search;\n break;\n case types.GET_DIGITAL_ASSET_LIST_SUCCESS:\n draft.loading = false;\n draft.assets = action.assets;\n draft.total = action.total;\n draft.statusDelete = 'idle';\n break;\n case types.GET_DIGITAL_ASSET_LIST_ERROR:\n draft.loading = false;\n draft.total = 0;\n draft.assets = [];\n draft.error = action.error;\n draft.statusDelete = 'idle';\n break;\n case types.DIGITAL_ASSET_GRID_COLUMN_INFO:\n draft.loading = true;\n draft.error = false;\n draft.gridName = action.gridName;\n break;\n case types.DIGITAL_ASSET_GRID_COLUMN_INFO_SUCCESS:\n draft.loading = false;\n draft.columns = action.columns;\n break;\n case types.DIGITAL_ASSET_GRID_COLUMN_INFO_ERROR:\n draft.loading = false;\n break;\n case types.GET_DIGITAL_ASSET_SHORT_DETAIL:\n draft.loadingDetail = true;\n draft.error = false;\n break;\n case types.GET_DIGITAL_ASSET_SHORT_DETAIL_SUCCESS:\n draft.loadingDetail = false;\n draft.assetData = action.data;\n break;\n case types.GET_DIGITAL_ASSET_SHORT_DETAIL_ERROR:\n draft.loadingDetail = false;\n draft.error = action.error;\n break;\n case types.UPDATE_CACHE_IMAGE:\n draft.cachedImagesVersion = action.payload;\n break;\n case types.DELETE_ASSETS:\n draft.statusDelete = 'loading';\n break;\n case types.DELETED_ASSETS_SUCCESS:\n draft.statusDelete = 'success';\n draft.assetData = null;\n break;\n case types.DELETED_ASSETS_ERROR:\n draft.statusDelete = 'error';\n break;\n case types.RESET_DELETE_ASSETS:\n draft.statusDelete = 'idle';\n break;\n\n case types.GET_ASSETS_FOR_MEMBER:\n draft.assetsForMember['loading'] = true;\n break;\n\n case types.GET_ASSETS_FOR_MEMBER_SUCCESS:\n draft.assetsForMember['loading'] = false;\n draft.assetsForMember['data'] = action.data.gridData;\n draft.assetsForMember['pageIndex'] =\n action.data.paging.currentPageIndex;\n draft.assetsForMember['pageSize'] = action.data.paging.currentPageSize;\n draft.assetsForMember['totalItems'] = action.data.paging.totalRecord;\n break;\n\n case types.GET_COLUMNS_ASSETS_FOR_MEMBER_SUCCESS:\n draft.assetsForMember['columns'] = action.columns;\n break;\n\n case types.SAVE_ID_MEMBER:\n draft.assetsForMember['memberId'] = action.id;\n break;\n case types.UPDATE_ASSET_TYPE_PANE:\n draft.editTypeLoading = true;\n break;\n case types.UPDATE_ASSET_TYPE_PANE_SUCCESS:\n draft.editTypeLoading = false;\n break;\n case types.UPDATE_ASSET_TYPE_PANE_ERROR:\n draft.editTypeLoading = false;\n break;\n case types.TOGGLE_ASSET_NEW:\n draft.isDisplayAssetNew = action.isDisplayAssetNew;\n break;\n case types.CACHE_ASSET_FROM_DATE:\n draft.cachedFromDate = action.fromDate;\n break;\n }\n });\n\nexport default assetReducer;\n","import React from 'react';\nimport { put, call, takeLatest, all, delay } from 'redux-saga/effects';\n\nimport * as types from './constants';\nimport * as actions from './actions';\nimport * as services from 'services/assetProduct';\nimport * as servicesGrid from 'services/grid';\nimport * as servicesMember from 'services/members';\n\nimport { AgGridThumbnail, AgGridIcons } from 'common/components';\n\nimport { formatMDYWithParam } from 'utils/formatDate';\nimport { formatSizeUnitByParam } from 'utils/formatSizeUnits';\nimport { notification } from 'antd';\nimport { FavoriteStarIconRender } from 'common/components';\nimport { DEFAULT_SORT } from 'static/Constants';\nimport * as actionsBranding from '@redux/branding/actions';\nimport { Images } from 'config/assets';\n\nexport function* getDigitalAssetList(payload) {\n try {\n let params = {\n type: payload.type,\n PageSize: payload.pageSize,\n PageIndex: payload.pageIndex,\n search: {\n searchText: payload?.search,\n primaryFieldsOnly: payload?.primaryFieldsOnly,\n },\n Filters: payload.filters,\n isFavoriteRoute: payload.isFavoriteRoute,\n ...(payload?.search ? null : { sort: DEFAULT_SORT }),\n advancedSearchContainer: payload.advancedSearchContainer,\n searchCategory: payload.searchCategory,\n fromDate: payload.fromDate,\n };\n \n if (payload.mediaType) params.DigitalMediaType = payload.mediaType;\n const response = yield call(services.getAssetList, params);\n yield put(\n actions.getDigitalAssetListSuccess(\n response.data.gridData,\n response.data.paging.totalRecord\n )\n );\n } catch (error) {\n yield put(actions.getDigitalAssetListError(error));\n }\n}\n\nexport function* getDigitalAssetForMemmberListSaga(payload) {\n try {\n let params = {\n type: payload.type,\n PageSize: payload.pageSize,\n PageIndex: payload.pageIndex,\n search: { searchText: payload.search },\n Filters: payload.filters,\n isFavoriteRoute: payload.isFavoriteRoute,\n ...(payload?.search ? null : { sort: DEFAULT_SORT }),\n advancedSearchContainer: payload.advancedSearchContainer,\n searchCategory: payload.searchCategory,\n fromDate: payload.fromDate,\n };\n if (payload.mediaType) params.DigitalMediaType = payload.mediaType;\n const response = yield call(services.getAssetList, params);\n yield put(\n actions.getDigitalAssetListSuccess(\n response.data.gridData,\n response.data.paging.totalRecord\n )\n );\n } catch (error) {\n yield put(actions.getDigitalAssetListError(error));\n }\n}\n\nexport function* getDigitalAssetShortDetail(payload) {\n try {\n const response = yield call(services.getDigitalAssetShortDetail, {\n Id: payload.id,\n });\n yield put(actions.getDigitalAssetShortDetailSuccess(response.data));\n } catch (error) {\n yield put(actions.getDigitalAssetShortDetailError(error));\n }\n}\n\nconst onFavoriteStarIconRender = (param) => {\n return ;\n};\n\nconst renderFavSharePackIcons = (params) => {\n const data = params?.data;\n\n return (\n \n );\n};\n\nconst renderThumbnail = (params) => {\n const thumbnail =\n params?.data?.thumbSize100 ||\n params?.data?.thumbSize300 ||\n Images.RIVIR_LOGO_DEFAULT;\n\n return ;\n};\n\nconst formatAssetDetailColumns = (response) => {\n let columns = [\n { field: '', checkboxSelection: true, filter: false, suppressMenu: true },\n {\n field: 'stateIcons',\n headerName: 'States',\n width: 85,\n cellRenderer: renderFavSharePackIcons,\n filter: false,\n resizable: false,\n headerClass: 'header-text-hide',\n },\n // {\n // field: '',\n // width: 70,\n // cellRenderer: renderThumbnail,\n // filter: false,\n // suppressMenu: true,\n // },\n ];\n\n if (response?.columns?.length > 0) {\n let hiddenCol = [\n 'id',\n 'uniqueId',\n 'canEdit',\n 'isOwner',\n 'type',\n 'fileName',\n ];\n response.columns.forEach((val) => {\n if (hiddenCol.indexOf(val.fieldNameCamelCase) === -1) {\n // eslint-disable-next-line no-lone-blocks\n {\n if (val.fieldNameCamelCase === 'sharedByName') {\n val = { ...val, flex: 1, minWidth: 180, resizable: true };\n } else if (val.fieldNameCamelCase === 'originalFileName') {\n val = {\n ...val,\n minWidth: 180,\n resizable: true,\n headerName: 'File Name',\n };\n } else if (val.fieldNameCamelCase === 'additionalSearchTags') {\n val = { ...val, minWidth: 200, resizable: true };\n } else if (val.dataType === 'datetime') {\n val = {\n ...val,\n minWidth: 150,\n cellRenderer: formatMDYWithParam,\n resizable: true,\n };\n } else if (\n val.fieldNameCamelCase === 'assetName' ||\n val.fieldNameCamelCase === 'ownerName'\n ) {\n val = { ...val, minWidth: 140, resizable: true };\n } else if (val.fieldNameCamelCase === 'assetType') {\n val = { ...val, minWidth: 120, resizable: true };\n } else if (val.fieldNameCamelCase === 'fileSize') {\n val = {\n ...val,\n minWidth: 120,\n resizable: true,\n cellRenderer: formatSizeUnitByParam,\n };\n } else {\n val = { ...val, minWidth: 150, resizable: true };\n }\n\n if (val.fieldNameCamelCase === 'assetName')\n val = { ...val, linkTo: '/asset/{id}', minWidth: 300 };\n\n columns.push(val);\n }\n }\n });\n }\n\n return columns;\n};\n\nexport function* gridDigitalAssetColumnInfo(payload) {\n try {\n const { response } = yield call(getColumnsFilter, payload);\n\n const columns = formatAssetDetailColumns(response);\n\n yield put(actions.gridDigitalAssetColumnInfoSuccess(columns));\n } catch (error) {\n yield put(actions.gridDigitalAssetColumnInfoError(error));\n }\n}\n\nexport function* getColumnsFilter(payload) {\n const response = yield call(servicesGrid.gridColumnInfo, payload.gridName);\n return { response };\n}\n\nexport function* deleteAssets(action) {\n try {\n const { assetIds } = action.payload;\n yield delay(1000);\n const response = yield call(services.deleteAssets, {\n listAssets: assetIds,\n });\n if (response.isSuccess) {\n yield put(actions.deleteAssetsSuccess(types.DELETED_ASSETS_SUCCESS));\n } else {\n yield put(actions.deleteAssetsError(types.DELETED_ASSETS_ERROR));\n }\n } catch (error) {\n yield put(actions.deleteAssetsError(error));\n }\n}\n\nexport function* updateAssetData(payload) {\n try {\n const response = yield call(services.updateAssetType, payload.params);\n if (response.isSuccess) {\n yield put(actions.updateAssetTypePaneSuccess());\n notification.success({\n message: 'Update Asset Type Success',\n });\n yield put(actions.getDigitalAssetShortDetail(payload.params.id));\n }\n } catch (error) {\n yield put(actions.updateAssetTypePaneError(error));\n }\n}\n\nexport function* getAssetsForMemberSaga(action) {\n try {\n const { isSuccess, data } = yield call(\n servicesMember.getAssetsForMember,\n action.params\n );\n if (isSuccess) {\n yield put(actions.getAssetsForMemberSuccess(data));\n }\n } catch (error) {\n yield put(actions.getAssetsForMemberError(error));\n }\n}\n\nexport function* getColumnsAssetsForMembersSaga(action) {\n try {\n const { response } = yield call(getColumnsFilter, action);\n\n const columns = formatAssetDetailColumns(response);\n\n yield put(actions.getColumnsAssetsForMemberSuccess(columns));\n } catch (error) {\n yield put(actions.getColumnsAssetsForMemberError(error));\n }\n}\n\nfunction* updateLatestGetNewAsset() {\n const updateLastGetNewDamResponse = yield call(services.updateLastGetNewDam);\n if (updateLastGetNewDamResponse.isSuccess)\n yield put(actionsBranding.getBrandingNoLoading());\n}\n\nfunction* watchAll() {\n yield all([\n takeLatest(\n types.GET_DIGITAL_ASSET_SHORT_DETAIL,\n getDigitalAssetShortDetail\n ),\n takeLatest(types.GET_DIGITAL_ASSET_LIST, getDigitalAssetList),\n takeLatest(\n types.DIGITAL_ASSET_GRID_COLUMN_INFO,\n gridDigitalAssetColumnInfo\n ),\n takeLatest(types.DELETE_ASSETS, deleteAssets),\n takeLatest(types.UPDATE_ASSET_TYPE_PANE, updateAssetData),\n takeLatest(types.GET_ASSETS_FOR_MEMBER, getAssetsForMemberSaga),\n takeLatest(\n types.GET_COLUMNS_ASSETS_FOR_MEMBER,\n getColumnsAssetsForMembersSaga\n ),\n takeLatest(types.UPDATE_LATEST_GET_NEW_ASSET, updateLatestGetNewAsset),\n takeLatest(\n types.GET_DIGITAL_ASSET_FOR_MEMBER_LIST,\n getDigitalAssetForMemmberListSaga\n ),\n ]);\n}\n\nexport default watchAll;\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\nconst selectAssetList = (state) => state.assetList || initialState;\n\nconst makeSelectLoading = () =>\n createSelector(selectAssetList, (assetState) => assetState.loading);\nconst makeSelectAssetList = () =>\n createSelector(selectAssetList, (assetState) => assetState.assets);\nconst makeSelectTotal = () =>\n createSelector(selectAssetList, (assetState) => assetState.total);\nconst makeSelectPageSize = () =>\n createSelector(selectAssetList, (assetState) => assetState.pageSize);\nconst makeSelectPageNumber = () =>\n createSelector(selectAssetList, (assetState) => assetState.pageNumber);\nconst makeSelectSearch = () =>\n createSelector(selectAssetList, (assetState) => assetState.search);\nconst makeSelectColumns = () =>\n createSelector(selectAssetList, (assetState) => assetState.columns);\nconst makeSelectLoadingDetail = () =>\n createSelector(selectAssetList, (assetState) => assetState.loadingDetail);\nconst makeSelectAssetData = () =>\n createSelector(selectAssetList, (assetState) => assetState.assetData);\n\nconst makeSelectStatusDelete = () =>\n createSelector(selectAssetList, (assetState) => assetState.statusDelete);\n\nconst makeSelectCachedImages = () =>\n createSelector(\n selectAssetList,\n (assetState) => assetState.cachedImagesVersion\n );\n\nconst makeSelectAssetsForMember = () =>\n createSelector(selectAssetList, (assetState) => assetState.assetsForMember);\n\nconst selectEditTypeLoading = () =>\n createSelector(selectAssetList, (assetState) => assetState.editTypeLoading);\n\nconst makeSelectIsDisplayAssetNew = () =>\n createSelector(selectAssetList, (assetState) => assetState.isDisplayAssetNew);\n\nconst makeSelectCachedFromDate = () =>\n createSelector(selectAssetList, (assetState) => assetState.cachedFromDate);\n\nexport {\n selectAssetList,\n makeSelectLoading,\n makeSelectAssetList,\n makeSelectTotal,\n makeSelectPageSize,\n makeSelectPageNumber,\n makeSelectSearch,\n makeSelectColumns,\n makeSelectLoadingDetail,\n makeSelectAssetData,\n makeSelectStatusDelete,\n makeSelectCachedImages,\n makeSelectAssetsForMember,\n selectEditTypeLoading,\n makeSelectIsDisplayAssetNew,\n makeSelectCachedFromDate,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { forwardTo } from 'utils/common/route';\nimport { ThumbnailItem } from 'common/components';\nimport { Images } from 'config/assets';\nimport * as getLink from 'utils/common/linkBuilder';\n\n/**\n * Member thumbnail is inherit from thumbnail item\n * @param {object} props\n */\nconst MemberThumbnailCard = (props) => {\n const {\n dataDetail,\n selected,\n onClickItemGrid,\n onClickCheckboxItem,\n hideCheckbox,\n linkTarget,\n isShareBtn = true,\n style,\n } = props;\n\n const onDoubleClick = (item) => {\n const { id } = item;\n forwardTo(`/company/${id}`);\n };\n\n const alink = getLink.memberLink(\n dataDetail?.id,\n dataDetail.memberName,\n linkTarget\n );\n return (\n \n );\n};\n\nMemberThumbnailCard.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default React.memo(MemberThumbnailCard);\n","import React from 'react';\n\nimport {\n Col,\n Button,\n Image,\n Dropdown,\n Menu,\n Space,\n Typography,\n Result,\n Tag,\n Tooltip,\n} from 'antd';\n\nimport { QuestionCircleOutlined } from '@ant-design/icons';\n\nimport brokerSrc from 'assets/member/broker.png';\nimport distributorSrc from 'assets/member/distributor.png';\nimport manufacturerSrc from 'assets/member/manufacturer.png';\nimport retailerSrc from 'assets/member/retailer.png';\n\nimport './MemberType.less';\n\nconst MemberType = ({ memberType = '' }) => {\n const dropdownContentRender = () => {\n return (\n \n \n
\n {memberType ? (\n \n \n Member Type:\n \n\n \n {memberType ? memberType.toUpperCase() : ''}\n \n \n ) : (\n \n )}\n
\n
\n
\n );\n };\n\n const memberTypeImage = getImageMemberType(memberType);\n\n return (\n \n {memberTypeImage.imageSrc ? (\n \n \n \n ) : (\n \n {memberTypeImage.icon}\n \n )}\n \n );\n};\n\nexport const MemberTypeTile = ({ memberType, ...otherProps }) => {\n const memberTypeImage = getImageMemberType(memberType);\n\n return (\n \n {memberTypeImage.imageSrc ? (\n \n \n \n ) : (\n \n {memberTypeImage.icon}\n \n )}\n \n );\n};\n\nconst TooltipMemberType = ({ memberType, children }) => {\n return (\n (\n \n Member Type: {memberType}\n \n )}\n >\n {children}\n \n );\n};\n\nconst getImageMemberType = (memberType = '') => {\n const lcMemberType = memberType?.toLowerCase();\n\n if (lcMemberType === 'broker') {\n return {\n imageSrc: brokerSrc,\n };\n }\n\n if (lcMemberType === 'distributor')\n return {\n imageSrc: distributorSrc,\n };\n\n if (lcMemberType === 'manufacturer') {\n return {\n imageSrc: manufacturerSrc,\n };\n }\n\n if (lcMemberType === 'retailer')\n return {\n imageSrc: retailerSrc,\n };\n\n return {\n icon: ,\n };\n};\n\nexport default MemberType;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Typography, Space, Row } from 'antd';\nimport { SafetyCertificateFilled } from '@ant-design/icons';\nimport { get } from 'lodash';\n\nimport { StarFilled } from '@ant-design/icons';\nimport IconList from 'common/components/icon-list/IconList';\nimport ProductSubscription from 'common/components/thumb/product/ProductSubscription';\nimport EntityStatusTag from 'common/components/tag/entity-status-tag/EntityStatusTag';\nimport { MemberTypeTile } from 'common/components/thumb/member/MemberType';\n\nconst { Paragraph, Title, Button } = Typography;\n\nconst AssetTileBody = (props) => {\n const { dataDetail } = props;\n const renderTitle = (value, key) => {\n return (\n \n {dataDetail?.memberName}\n \n );\n };\n\n const renderText = (value, key) => {\n return (\n <>\n {value && (\n \n {value}\n \n )}\n \n );\n };\n\n const memberName = get(dataDetail, 'memberName', '');\n const mainAddress = get(\n dataDetail,\n 'primaryAddress.primaryAddressMainAddress',\n ''\n );\n\n const country = get(dataDetail, 'primaryAddress.primaryAddressCountry', '');\n const city = get(dataDetail, 'primaryAddress.primaryAddressCity', '');\n const state = get(dataDetail, 'primaryAddress.primaryAddressState', '');\n const countryAddress = `${city} ${city && ','} ${state}${\n country === 'USA' ? '' : `${state && ', '}` + country\n }`;\n\n const zipcode = get(dataDetail, 'primaryAddress.primaryAddressZipcode', '');\n const segments = get(dataDetail, 'segments', []).map((segmentIcon) => ({\n ...segmentIcon,\n wrapperStyle: {\n marginRight: 4,\n },\n }));\n const haveProductsCertificated = get(\n dataDetail,\n 'haveProductsCertificated',\n false\n );\n\n const infoText = [\n {\n field: 'memberName',\n value: memberName,\n render: renderTitle,\n },\n {\n field: 'mainAddress',\n value: mainAddress,\n render: renderText,\n },\n {\n field: 'country',\n value: countryAddress,\n render: renderText,\n },\n {\n field: 'zipcode',\n value: zipcode,\n render: renderText,\n },\n ];\n\n return (\n
\n \n \n {infoText &&\n infoText.map((textItem) => {\n const { value, field, render } = textItem;\n return render ? render(value, field) : value;\n })}\n \n \n \n \n \n \n \n {haveProductsCertificated ? (\n \n ) : null}\n {dataDetail?.isFavorited && (\n \n )}\n\n {dataDetail?.memberType && (\n \n )}\n {dataDetail?.subscription && (\n \n )}\n \n \n
\n );\n};\n\nAssetTileBody.propTypes = {\n dataDetail: PropTypes.object,\n};\n\nexport default AssetTileBody;\n","/**\n * Branded members Messages\n *\n * This contains all the text for the member grid component.\n */\nimport { defineMessages } from 'react-intl';\n\nexport const scope = 'Taco.branded-members';\n\nexport default defineMessages({\n memberSince: {\n id: `${scope}.components.memberSince.`,\n defaultMessage: 'Since',\n },\n lastUpdated: {\n id: `${scope}.components.lastUpdated.`,\n defaultMessage: 'Last Updated',\n },\n});\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Row, Col } from 'antd';\nimport { get } from 'lodash';\n\nimport { injectIntl } from 'react-intl';\nimport Messages from 'i18n/messages/branded-members';\n\nimport { formatMDY } from 'utils/formatDate';\n\nconst AssetTileFooter = (props) => {\n const { intl, dataDetail } = props;\n\n const loadedDate = get(dataDetail, 'memberSince', '');\n const lastUpdatedDate = get(dataDetail, 'lastUpdatedDate', '');\n\n return (\n \n \n \n \n {intl.formatMessage(Messages.lastUpdated)}\n {': '}\n \n {lastUpdatedDate && formatMDY(lastUpdatedDate)} \n \n \n \n {intl.formatMessage(Messages.memberSince)}\n {': '}\n \n {loadedDate && formatMDY(loadedDate)}\n \n \n \n );\n};\n\nAssetTileFooter.propTypes = {\n loadedDate: PropTypes.string,\n lastUpdate: PropTypes.string,\n};\n\nexport default injectIntl(AssetTileFooter);\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Row, Avatar } from 'antd';\nimport { Images } from 'config/assets';\n\nconst AssetTileHeader = (props) => {\n const { dataDetail } = props;\n\n return (\n \n
\n\n
\n \n
\n
\n );\n};\n\nAssetTileHeader.propTypes = {\n dataDetail: PropTypes.object,\n};\n\nexport default AssetTileHeader;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Tooltip } from 'antd';\nimport { get } from 'lodash';\n\nimport MemberTileBody from './items-new/MemberTileBody';\nimport MemberTileFooter from './items-new/MemberTileFooter';\nimport MemberTileHeader from './items-new/MemberTileHeader';\n\nimport './MemberTileCard.less';\n\nimport useDoubleClick from 'hooks/useDoubleClick';\n\n/**\n * A component displays member information under card layout\n * @param {object} props\n */\nconst MemberTileCard = (props) => {\n // variables\n const { dataDetail } = props;\n const { onClickItemGrid, onDoubleClick } = props.clickEvents;\n\n const memberName = get(props.dataDetail, 'memberName', '');\n\n const divRef = React.useRef();\n useDoubleClick({\n onSingleClick: (e) => {\n if (onClickItemGrid) onClickItemGrid(dataDetail, e);\n },\n onDoubleClick: (e) => {\n if (onDoubleClick) onDoubleClick(dataDetail);\n },\n ref: divRef,\n latency: 250,\n });\n return (\n \n \n\n
\n \n \n \n
\n
\n );\n};\n\nMemberTileCard.propTypes = {\n dataDetail: PropTypes.object,\n selected: PropTypes.bool,\n onClickItemGrid: PropTypes.func,\n onClickCheckboxItem: PropTypes.func,\n};\n\nexport default MemberTileCard;\n","import React, { useState } from 'react';\nimport { Row, Col, Button, notification } from 'antd';\nimport AgGrid from 'common/components/ag-grid/AgGrid';\nimport * as endpoints from 'services/members/endpoints';\nimport './BanListModal.less';\nimport { WithLoading } from 'common/components';\nimport classnames from 'classnames';\nimport * as services from 'services/members';\nimport dialogFunction from 'common/components/dialog-function/DialogFunction';\nimport { EditOutlined, DeleteOutlined, StopOutlined } from '@ant-design/icons';\nimport Message from 'i18n/messages/member-profile';\nimport { useIntl } from 'react-intl';\n\nconst BanListModal = (props) => {\n const intl = useIntl();\n const { columns, removeBanList, changeBanList } = props;\n const [gridApi, setGridApi] = useState(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isEdit, setIsEdit] = useState(false);\n const [rowsSelected, setRowSelected] = useState([]);\n\n const onSetSelectedRows = (selectedNodesDetail) => {\n const bannedMemmberIdList = selectedNodesDetail.map(\n (nodeDetail) => nodeDetail?.bannedMemberId\n );\n setRowSelected(bannedMemmberIdList);\n };\n\n async function toggleRemoveBanList() {\n if (rowsSelected.length > 0) {\n setIsLoading(true);\n const res = await services.removeToBanList({ memberIds: rowsSelected });\n setIsLoading(false);\n if (res?.isSuccess) {\n notification.success({\n message: 'Remove items from ban list successfully!',\n top: 50,\n });\n refreshGrid();\n changeBanList();\n setRowSelected([]);\n } else {\n notification.error({\n message: 'Failed to remove items from ban list!',\n top: 50,\n });\n }\n } else {\n notification.error({\n message: 'Should choose item to remove!',\n top: 50,\n });\n }\n }\n\n function refreshGrid() {\n if (gridApi) gridApi.rivirPurgeServerSideCache();\n }\n\n const confirmDelete = () => {\n dialogFunction({\n type: 'warn',\n content: intl.formatMessage(Message.deleteItemsFromBanList),\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: toggleRemoveBanList,\n });\n };\n\n return (\n <>\n \n \n \n {!isEdit && (\n }\n onClick={() => {\n setIsEdit(!isEdit);\n }}\n />\n )}\n {isEdit && (\n {\n confirmDelete();\n }}\n >\n \n Delete\n \n )}\n {isEdit && (\n }\n onClick={() => setIsEdit(false)}\n >\n Cancel\n \n )}\n \n \n \n \n {\n setGridApi(gridApi);\n }}\n onHandleSelectedRowCustom={onSetSelectedRows}\n // requestParams={requestParams}\n />\n \n \n refreshGrid()}\n >\n setIsEdit(false)}\n >\n \n );\n};\n\nexport default BanListModal;\n","import React from 'react';\nimport { Avatar } from 'antd';\nimport { Images } from 'config/assets';\n\nconst MemberLogo = (props) => {\n const logoSrc = props?.thumb300 || props?.thumb || Images.RIVIR_LOGO_DEFAULT;\n return (\n \n );\n};\n\nexport default MemberLogo;\n","import { useEffect, useRef } from 'react';\n\nimport * as constant from 'static/Constants';\nimport * as actionsAsset from 'pages/branded-assets/controllers/actions';\nimport * as actionsGlobal from '@redux/global/actions';\n\nimport { useGetQuery } from 'hooks/useQuery';\n\nconst useColumnsGrid = (dispatch, typeView) => {\n useEffect(() => {\n if (typeView === constant.RIBBON_TYPES.DETAILSVIEW)\n dispatch(actionsAsset.getColumnsAssetsForMember('assets-for-member'));\n }, [dispatch, typeView]);\n};\n\nconst useAssetsForMember = (\n dispatch,\n pageIndex,\n pageSize,\n memberId,\n searchText\n) => {\n useEffect(() => {\n const params = {\n pageIndex,\n pageSize,\n memberId,\n search: { searchText },\n };\n\n dispatch(actionsAsset.getAssetsForMember(params));\n }, [dispatch, memberId, pageIndex, pageSize, searchText]);\n};\n\nconst useSaveIdMember = (dispatch, memberId) => {\n useEffect(() => {\n dispatch(actionsAsset.saveIdMember(memberId));\n }, [dispatch, memberId]);\n};\n\nconst useToggleAssetsForMember = (dispatch) => {\n useEffect(() => {\n dispatch(actionsGlobal.toggleAssetsToMember());\n }, [dispatch]);\n};\n\nconst useGetMemberId = () => {\n const refMemberId = useRef();\n const query = useGetQuery();\n const memberId = query.get('memberId');\n\n useEffect(() => {\n refMemberId.current = memberId;\n }, [memberId]);\n\n return { memberId, refMemberId };\n};\n\nexport {\n useColumnsGrid,\n useAssetsForMember,\n useSaveIdMember,\n useToggleAssetsForMember,\n useGetMemberId,\n};\n","const getAssetTypeFilter = (filters, filterAssets) => {\n let filterAssetType = {\n fieldName: 'assetType',\n filterType: 'In',\n values: [],\n };\n if (filterAssets.includes('asset')) {\n filterAssetType.values.push('asset');\n }\n if (filterAssets.includes('document')) {\n filterAssetType.values.push('document');\n }\n if (filterAssets.includes('multimedia')) {\n filterAssetType.values.push('multimedia');\n }\n if (filterAssetType.values.length > 0) {\n filters.push(filterAssetType);\n }\n};\n\nexport const filterAsset = (refMemberId, filterAssets) => {\n const defaultFilter = [\n {\n fieldName: 'ownerId',\n value: parseInt(refMemberId.current),\n filterType: 'Equal',\n },\n ];\n let filters = defaultFilter;\n\n if (filterAssets.indexOf('owner') > -1) {\n filters.push({\n fieldName: 'isOwner',\n value: true,\n filterType: 'Equal',\n });\n }\n if (\n filterAssets.indexOf('active') > -1 &&\n filterAssets.indexOf('pending') > -1\n ) {\n filters.push({\n fieldName: 'status',\n values: ['Active', 'Pending'],\n filterType: 'In',\n });\n } else {\n if (filterAssets.indexOf('active') > -1) {\n filters.push({\n fieldName: 'status',\n value: 'Active',\n filterType: 'Equal',\n });\n }\n if (filterAssets.indexOf('pending') > -1) {\n filters.push({\n fieldName: 'status',\n value: 'Pending',\n filterType: 'Equal',\n });\n }\n getAssetTypeFilter(filters, filterAssets);\n }\n if (filterAssets.indexOf('unmatched') > -1) {\n filters.push({\n fieldName: 'meetMinRequirement',\n value: false,\n filterType: 'Equal',\n });\n filters.push({\n fieldName: 'status',\n value: 'Active',\n filterType: 'Equal',\n });\n }\n\n return filters;\n};\n","import React, { useEffect, useCallback, useState, useMemo } from 'react';\nimport PropTypes from 'prop-types';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { Skeleton, Row, Col, Spin } from 'antd';\n\nimport {\n AssetTile,\n AssetThumbnail,\n AssetPanel,\n} from 'pages/branded-assets/components';\nimport { GridView } from 'common/components/';\nimport { OpenItemContentPane } from 'common/components/openItem';\n\nimport { selectRibbonType } from '@redux/ribbon/selectors';\nimport * as actions from '@redux/global/actions';\nimport * as actionsGlobal from '@redux/global/actions';\nimport * as selectorsGlobal from '@redux/global/selectors';\nimport * as brandingSelectors from '@redux/branding/selectors';\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\n\nimport reducer from 'pages/branded-assets/controllers/reducer';\nimport saga from 'pages/branded-assets/controllers/saga';\nimport * as actionsAsset from 'pages/branded-assets/controllers/actions';\nimport * as selectorAsset from 'pages/branded-assets/controllers/selectors';\nimport reducerLinkAssets from 'pages/branded-assets/components/panel/link-assets/controller/reducers';\nimport sagaLinkAssets from 'pages/branded-assets/components/panel/link-assets/controller/saga';\n\nimport * as selectorsAssets from 'pages/branded-assets/controllers/selectors';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\n\nimport * as actionsAssetFull from 'pages/home/ribbon/asset-full/controllers/actions';\nimport * as actionsLinkAssets from 'pages/branded-assets/components/panel/link-assets/controller/actions';\n\nimport assetReducer from 'pages/asset-full-view/controllers/reducer';\nimport sagaDigitalAsset from 'pages/asset-full-view/controllers/saga';\n\nimport { useInjectReducer } from 'utils/common/injectedReducers';\nimport { useInjectSaga } from 'utils/common/injectSaga';\nimport { getGridName } from 'utils/getGridName';\nimport { updateSizeCurrent } from 'common/components/grid-view/utils';\nimport { clearQueryCondition } from 'utils/queryCondition';\n\nimport { useWindowSize } from 'hooks/windowSize';\nimport useCheckFavoriteRoute from 'hooks/useCheckFavoriteRoute';\nimport {\n useSaveConfigColumns,\n useFilterDefaultColumns,\n useSaveAllColumns,\n useSaveChosenColumns,\n} from 'hooks/configGridHooks';\nimport {\n useListenReloadPage,\n useUpdateSelectedData,\n} from 'hooks/useReloadPage';\nimport { useClearSearchText } from 'hooks/useClearSearchText';\nimport { useFilterGrid } from 'hooks/useFilterGrid';\n\nimport { useGetMemberId } from './hooks';\n\nimport { SEARCH_CRITERIA, RIBBON_OPTIONS, OPEN_ITEM } from 'static/Constants';\nimport * as constant from 'static/Constants';\n\nimport * as endpointsAsset from 'services/assetProduct/endpoints';\nimport { handleCreateSearchContainer } from 'pages/reporting/utils';\nimport { filterAsset } from './utils';\n\nconst key = 'assetList';\nconst keyLinkAssets = 'linkAssets';\nconst keyDigitalAsset = 'digitalAsset';\n\nconst Assets = (props) => {\n const option = RIBBON_OPTIONS.ASSET_FOR_MEMBER;\n const searchCriteria = SEARCH_CRITERIA.ASSET;\n useInjectReducer({ key, reducer });\n useInjectSaga({ key, saga });\n useInjectReducer({ key: keyLinkAssets, reducer: reducerLinkAssets });\n useInjectSaga({ key: keyLinkAssets, saga: sagaLinkAssets });\n useInjectReducer({ key: keyDigitalAsset, reducer: assetReducer });\n useInjectSaga({ key: keyDigitalAsset, saga: sagaDigitalAsset });\n\n const { mediaType } = props;\n const dispatch = useDispatch();\n const isFavoriteRoute = useCheckFavoriteRoute();\n const { refMemberId } = useGetMemberId();\n const pathname = window.location.pathname;\n\n const fetchAssetForMember = useCallback((params) => {\n if (!refMemberId.current) return;\n dispatch(\n actionsAsset.getDigitalAssetForMemberList({\n ...params,\n })\n );\n }, []);\n\n const columns = useSelector(selectorAsset.makeSelectColumns());\n const searchCategoriesEffected = useSelector(\n selectorsGridView.makeSelectSearchCategoriesList()\n );\n\n const [requestParams, setRequestParams] = useState({\n DigitalMediaType: mediaType,\n searchCategory: searchCategoriesEffected || [],\n });\n const [filterFromAssets, setFilterFromAssets] = useState([]);\n const asset = useSelector(selectorAsset.makeSelectAssetList());\n const totalPagination = useSelector(selectorAsset.makeSelectTotal());\n\n const detailCurrentItemsSelection = useSelector(\n selectorsGridView.makeSelectDetailCurrentITemsSelection()\n );\n\n const selectAsset = detailCurrentItemsSelection?.[0];\n\n const {\n assetForMemberPage: [currentPageNumber, currentPageSize],\n } = useSelector(selectorsGridView.makeSelectPageCurrent());\n\n const visibleContentPane = useSelector(selectorsGridView.makeSelectVisible());\n\n const loading = useSelector(selectorAsset.makeSelectLoading());\n\n const { assetForMemberText, assetForMemberPrimaryFieldsOnly } = useSelector(\n selectorsGlobal.selectSelectSearchText()\n );\n\n const typeView = useSelector(selectRibbonType());\n const assetData = useSelector(selectorAsset.makeSelectAssetData());\n const loadingDetail = useSelector(selectorAsset.makeSelectLoadingDetail());\n const statusDelete = useSelector(selectorsAssets.makeSelectStatusDelete());\n\n const {\n allColumns,\n defaultColumns: defaultColumnsState,\n isRefreshGrid,\n } = useSelector(selectorsGridView.makeSelectGridConfig());\n\n const showAdvanceFilter = useSelector(\n selectorsGlobal.selectShowAdvanceFilter()\n );\n\n const isNewAssetFilter = useSelector(selectorsGlobal.selectDisplayAssetNew());\n const brandingData = useSelector(brandingSelectors.getBranding());\n\n const fromDate = isNewAssetFilter ? brandingData?.lastGetNewDamsTime : null;\n const cachedFromDate = useSelector(selectorAsset.makeSelectCachedFromDate());\n\n const [width] = useWindowSize();\n const gridName = getGridName(pathname);\n\n const stringSearchCategories = JSON.stringify(searchCategoriesEffected);\n\n const queryConditions = useSelector(\n selectorsGridView.makeSelectAssetsForMemberQuery()\n );\n const prevPathnameQuery = useSelector(\n selectorsGridView.makeSelectPrevPathnameQuery()\n );\n clearQueryCondition(dispatch, pathname, prevPathnameQuery);\n const checkQueryCondition = useSelector(\n selectorsGridView.makeSelectCheckQueryCondition()\n );\n const myQueryDoubleClick = useSelector(\n selectorsGridView.makeSelectMyQueryDoubleClick()\n );\n\n useSaveConfigColumns(gridName);\n useSaveAllColumns(columns);\n const defaultColumns = useFilterDefaultColumns(columns);\n useSaveChosenColumns(columns);\n\n const { gridFilters: filterAssets, updateGridFilter } = useFilterGrid({\n entityType: 'asset',\n clearOtherFilter: true,\n });\n\n const searchText = useMemo(() => {\n return {\n searchText: assetForMemberText,\n primaryFieldsOnly: assetForMemberPrimaryFieldsOnly,\n };\n }, [assetForMemberText, assetForMemberPrimaryFieldsOnly]);\n\n const saveFromDateValue = () => {\n if (isNewAssetFilter && fromDate && !cachedFromDate) {\n dispatch(actionsAsset.cacheFromDate(fromDate));\n }\n };\n\n const updateRibbonCallback = useCallback(() => {\n dispatch(actions.changeRibbonActions(option));\n }, [dispatch]);\n const updateSearchCriteriaCallback = useCallback(() => {\n dispatch(actions.updateSearchCriteria(searchCriteria));\n }, [dispatch]);\n\n useEffect(() => {\n updateRibbonCallback();\n }, [updateRibbonCallback]);\n\n useEffect(() => {\n updateSearchCriteriaCallback();\n }, [updateSearchCriteriaCallback]);\n\n useEffect(() => {\n // the first time come branded-asset will remove assetData on content pane\n dispatch(actionsAsset.getDigitalAssetShortDetailSuccess(null));\n // reset member id of asset\n dispatch(actionsAsset.saveIdMember(null));\n }, [dispatch]);\n\n useEffect(() => {\n if (visibleContentPane && selectAsset) {\n dispatch(actionsAsset.getDigitalAssetShortDetail(selectAsset.id));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectAsset, visibleContentPane]);\n\n useEffect(() => {\n setRequestParams({\n ...requestParams,\n searchCategory: searchCategoriesEffected,\n fromDate: cachedFromDate,\n });\n }, [JSON.stringify(searchCategoriesEffected), cachedFromDate]);\n\n useEffect(() => {\n if (stringSearchCategories === 'null') return;\n\n const filters = filterAsset(refMemberId, filterAssets);\n\n setFilterFromAssets(filters);\n saveFromDateValue();\n if (\n //!warning = this condtion might be wrong since the querycondition should be applied for all view type\n // typeView !== constant.RIBBON_TYPES.DETAILSVIEW &&\n !checkQueryCondition &&\n !myQueryDoubleClick\n ) {\n const advancedSearchContainer =\n handleCreateSearchContainer(queryConditions);\n requestParams.advancedSearchContainer = advancedSearchContainer;\n requestParams.searchCategory = searchCategoriesEffected;\n\n setRequestParams(requestParams);\n\n //* prevent call api when filtering new asset but fromDate not loaded yet\n // if ((isNewAssetFilter && !fromDate) || (!isNewAssetFilter && fromDate)) return;\n\n if (typeView !== constant.RIBBON_TYPES.DETAILSVIEW) {\n isNewAssetFilter &&\n fromDate &&\n filters.length === 0 &&\n fetchAssetForMember({\n pageSize: currentPageSize,\n pageNumber: currentPageNumber,\n search: searchText?.searchText,\n primaryFieldsOnly: searchText?.primaryFieldsOnly,\n filters,\n mediaType,\n isFavoriteRoute,\n advancedSearchContainer,\n searchCategory: searchCategoriesEffected,\n fromDate: cachedFromDate || fromDate || null,\n });\n\n !isNewAssetFilter &&\n !fromDate &&\n fetchAssetForMember({\n pageSize: currentPageSize,\n pageNumber: currentPageNumber,\n search: searchText?.searchText,\n primaryFieldsOnly: searchText?.primaryFieldsOnly,\n filters,\n mediaType,\n isFavoriteRoute,\n advancedSearchContainer,\n searchCategory: searchCategoriesEffected,\n });\n }\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n dispatch,\n searchText,\n filterAssets,\n mediaType,\n isFavoriteRoute,\n typeView,\n stringSearchCategories,\n isNewAssetFilter,\n currentPageSize,\n currentPageNumber,\n // JSON.stringify(searchCategoriesEffected),\n ]);\n\n useEffect(() => {\n return () => {\n dispatch(actionsGridView.deleteItemsSelection());\n dispatch(actionsGridView.updatePagesSelection([]));\n dispatch(actionsGridView.updateItemPageSelection([]));\n };\n }, [\n dispatch,\n searchText,\n filterAssets,\n JSON.stringify(searchCategoriesEffected),\n ]);\n\n useEffect(() => {\n if (typeView === constant.RIBBON_TYPES.DETAILSVIEW) {\n dispatch(\n actionsAsset.gridDigitalAssetColumnInfo('digital-asset-detail-grid')\n );\n }\n }, [dispatch, typeView, pathname, isNewAssetFilter]);\n\n useEffect(() => {\n if (isNewAssetFilter) {\n filterAssets?.length > 0 && updateGridFilter([]);\n dispatch(actionsAsset.updateLatestGetNewAsset());\n }\n }, [dispatch, isNewAssetFilter]);\n\n useEffect(() => {\n if (checkQueryCondition && myQueryDoubleClick) {\n updateSizeCurrent(dispatch, 1, currentPageSize, pathname);\n\n const advancedSearchContainer =\n handleCreateSearchContainer(queryConditions);\n requestParams.advancedSearchContainer = advancedSearchContainer;\n requestParams.searchCategory = searchCategoriesEffected;\n\n setRequestParams(requestParams);\n\n dispatch(actionsGridView.deleteItemsSelection());\n\n if (typeView === constant.RIBBON_TYPES.DETAILSVIEW) {\n dispatch(actionsGridView.updateIsRefreshGrid());\n } else {\n fetchAssetForMember({\n pageSize: currentPageSize,\n pageNumber: 1,\n search: searchText?.searchText,\n primaryFieldsOnly: searchText?.primaryFieldsOnly,\n filters: filterFromAssets,\n mediaType,\n isFavoriteRoute,\n advancedSearchContainer,\n searchCategory: searchCategoriesEffected,\n fromDate: cachedFromDate,\n });\n }\n dispatch(actionsGridView.checkQueryCondition(false));\n dispatch(actionsGridView.myQueryDoubleClick(false));\n }\n }, [\n dispatch,\n checkQueryCondition,\n //* add currentPageSize help keep page size when clear adv filter\n currentPageSize,\n ]);\n\n useEffect(() => {\n dispatch(actionsAssetFull.disableModeLinkAsset());\n dispatch(actionsLinkAssets.resetLinkAsset());\n dispatch(actionsGridView.resetPageCurrentMember());\n dispatch(actionsGlobal.updateSearchTextProduct(''));\n }, [dispatch]);\n\n useEffect(() => {\n dispatch(actionsAsset.showLoading());\n }, []);\n\n useEffect(() => {\n return () => {\n clearNewAssetFilter();\n };\n }, []);\n\n // re-call api when page need to reload\n const isReloadPage = useListenReloadPage(() => {\n const advancedSearchContainer =\n handleCreateSearchContainer(queryConditions);\n\n fetchAssetForMember({\n pageSize: currentPageSize,\n pageNumber: currentPageNumber,\n search: searchText?.searchText,\n primaryFieldsOnly: searchText?.primaryFieldsOnly,\n filters: filterFromAssets,\n mediaType,\n isFavoriteRoute,\n advancedSearchContainer,\n searchCategory: searchCategoriesEffected,\n fromDate: cachedFromDate,\n });\n });\n\n useUpdateSelectedData(asset);\n useClearSearchText(dispatch, 'assetForMember', pathname);\n\n const AssetGridThumbnail = (configProps) => {\n return ;\n };\n\n const AssetGridTile = (configProps) => {\n return ;\n };\n\n function updateAssetTypePane(value) {\n const submitForm = {\n id: selectAsset?.id,\n ...value,\n };\n dispatch(actionsAsset.updateAssetTypePane(submitForm));\n }\n\n const clearNewAssetFilter = () => {\n dispatch(actionsAsset.toggleAssetNew(false));\n dispatch(actionsAsset.toggleAssetUnmatch(false));\n dispatch(actionsAsset.cacheFromDate(null));\n };\n\n const urlGrid = endpointsAsset.DIGITAL_ASSET_DETAIL_GRID;\n const urlGridDistinct = endpointsAsset.DIGITAL_ASSET_DETAIL_GRID_DISTINCT;\n\n return (\n <>\n \n \n \n {statusDelete === 'loading' ? (\n \n \n \n ) : null}\n\n \n console.log('todo-save-folder')}\n onSubmit={(value) => updateAssetTypePane(value)}\n />\n \n }\n filterFromMainPage={filterFromAssets}\n requestParams={requestParams}\n shouldReloadDetailGrid={isRefreshGrid}\n showAdvanceFilter={showAdvanceFilter}\n queryConditions={queryConditions}\n enableDragToFolder\n isDisplaySearchCategories\n isToggle={isNewAssetFilter}\n onClickToSeeAll={clearNewAssetFilter}\n applyDefaultSort={searchText ? false : true}\n />\n \n \n \n \n );\n};\n\nAssets.propTypes = { mediaType: PropTypes.string };\n\nexport default Assets;\n","import { useEffect, useRef } from 'react';\n\nimport * as constant from 'static/Constants';\nimport * as actionsMember from '../../controllers/actions';\nimport * as actionsGlobal from '@redux/global/actions';\nimport { useGetQuery } from 'hooks/useQuery';\n\n// TODOS: Khang - 09/12/2020 - This file will be changed after the Product View implement\n\nconst useColumnsGrid = (dispatch, typeView) => {\n useEffect(() => {\n if (typeView === constant.RIBBON_TYPES.DETAILSVIEW)\n dispatch(\n actionsMember.getColumnsProductsForMember('products-for-member')\n );\n }, [dispatch, typeView]);\n};\n\nconst useProductsForMember = (\n dispatch,\n pageIndex,\n pageSize,\n memberId,\n searchText\n) => {\n useEffect(() => {\n const params = {\n pageIndex,\n pageSize,\n memberId,\n search: { searchText },\n sort: [{ isAscending: false, fieldName: 'id' }],\n };\n\n dispatch(actionsMember.getProductsForMember(params));\n }, [dispatch, memberId, searchText]);\n\n useEffect(() => {\n return () => {\n dispatch(actionsMember.resetProductsForMemberState());\n };\n }, []);\n};\n\nconst useSaveIdMember = (dispatch, memberId) => {\n useEffect(() => {\n dispatch(actionsMember.saveIdMember(memberId));\n }, [dispatch, memberId]);\n};\n\nconst useToggleProdForMember = (dispatch) => {\n useEffect(() => {\n dispatch(actionsGlobal.toggleProdToMember());\n }, [dispatch]);\n};\n\nconst useGetMemberId = () => {\n const refMemberId = useRef();\n const query = useGetQuery();\n const memberId = query.get('memberId');\n\n useEffect(() => {\n refMemberId.current = memberId;\n }, [memberId]);\n\n return { memberId, refMemberId };\n};\n\nexport {\n useColumnsGrid,\n useProductsForMember,\n useSaveIdMember,\n useToggleProdForMember,\n useGetMemberId,\n};\n","import React, { useCallback, useEffect, useState, useMemo } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { useLocation } from 'react-router-dom';\n\n// redux\nimport { useInjectReducer } from 'utils/common/injectedReducers';\nimport { useInjectSaga } from 'utils/common/injectSaga';\nimport reducer from 'pages/branded-products/controllers/reducer';\nimport saga from 'pages/branded-products/controllers/saga';\n\nimport { useWindowSize } from 'hooks/windowSize';\nimport { Skeleton } from 'antd';\nimport _ from 'lodash';\n\nimport * as actionsProduct from 'pages/branded-products/controllers/actions';\nimport * as selectorProduct from 'pages/branded-products/controllers/selectors';\n\nimport * as actionsGlobal from '@redux/global/actions';\nimport * as selectorsGlobal from '@redux/global/selectors';\nimport * as ribbonSelector from '@redux/ribbon/selectors';\n\nimport { GridView } from 'common/components/';\nimport { OpenItemContentPane } from 'common/components/openItem';\n\nimport {\n ProductTile,\n ProductContentPanel,\n} from 'pages/branded-products/components/index';\n\nimport * as constant from 'static/Constants';\nimport useCheckFavoriteRoute from 'hooks/useCheckFavoriteRoute';\nimport ProductThumbnail from 'pages/branded-products/components/card/thumbnail/ProductThumbnail';\nimport { clearQueryCondition } from 'utils/queryCondition';\n\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\nimport * as brandingSelectors from '@redux/branding/selectors';\nimport * as endpointsProduct from 'services/product/endpoints';\nimport * as brandingActions from '@redux/branding/actions';\n\nimport { getGridName } from 'utils/getGridName';\nimport { updateSizeCurrent } from 'common/components/grid-view/utils';\nimport {\n useSaveConfigColumns,\n useSaveAllColumns,\n useSaveChosenColumns,\n} from 'hooks/configGridHooks';\nimport {\n useListenReloadPage,\n useUpdateSelectedData,\n} from 'hooks/useReloadPage';\n\nimport { useClearSearchText } from 'hooks/useClearSearchText';\nimport { useFilterGrid } from 'hooks/useFilterGrid';\n\nimport { useGetMemberId } from './hooks';\n\nimport useGetDefaultConfig from 'pages/branded-products/hooks/useGetDefaultConfig';\n\nimport { handleCreateSearchContainer } from 'pages/reporting/utils';\nimport { getParamsFromUrl } from 'utils/common/route';\n\nconst key = 'product';\n\nconst ProductForMemberGrid = (props) => {\n const option = constant.RIBBON_OPTIONS.PRODUCT_FOR_MEMBER;\n const searchCriteria = constant.SEARCH_CRITERIA.PRODUCT;\n\n const location = useLocation();\n const { brandId } = getParamsFromUrl(location) ?? {};\n\n useInjectReducer({ key, reducer });\n useInjectSaga({ key, saga });\n\n const dispatch = useDispatch();\n const isFavoriteRoute = useCheckFavoriteRoute();\n\n const [width] = useWindowSize();\n\n const { refMemberId } = useGetMemberId();\n\n const fetchProductForMember = useCallback((params) => {\n if (!refMemberId.current) return;\n\n dispatch(\n actionsProduct.getMemberProductList({\n ...params,\n })\n );\n }, []);\n\n // const searchAllItems = useSelector(selectorsGlobal.selectSearchAllItems());\n\n const searchCategoriesEffected = useSelector(\n selectorsGridView.makeSelectSearchCategoriesList()\n );\n const [requestParams, setRequestParams] = useState({\n searchCategory: searchCategoriesEffected || [],\n });\n const [filterFromAssets, setFilterFromAssets] = useState([]);\n const [packageLevels, setPackageLevels] = useState([]);\n const [packageArray, setPackageArray] = useState([]);\n const [currentDate, setCurrentDate] = useState(null);\n const [aplId, setAplId] = useState();\n\n const { allColumns, isRefreshGrid } = useSelector(\n selectorsGridView.makeSelectGridConfig()\n );\n\n const reloadGrid = useSelector(selectorProduct.makeSelectReloadGrid());\n const typeView = useSelector(ribbonSelector.selectRibbonType());\n\n const {\n allConfigFieldsName,\n selectedColumns,\n defaultColumnsGrid: customGridColumns,\n isConfigEmpty,\n } = useSelector(selectorProduct.makeSelectGridConfig());\n\n const applyGridConfig = useSelector(\n selectorProduct.makeSelectApplyGridConfig()\n );\n\n const isDetailView = typeView === constant.RIBBON_TYPES.DETAILSVIEW;\n\n useGetDefaultConfig({\n isEnabled: Boolean(isDetailView),\n applyGridConfig,\n });\n\n const { gridFilters } = useFilterGrid({\n entityType: 'memberProduct',\n clearOtherFilter: true,\n });\n\n // add 2 default cols to configColumns\n\n // ribbon button change\n const updateRibbonCallback = useCallback(() => {\n dispatch(actionsGlobal.changeRibbonActions(option));\n }, [dispatch]);\n\n // change search criteriaProduct\n const updateSearchCriteriaCallback = useCallback(() => {\n dispatch(actionsGlobal.updateSearchCriteria(searchCriteria));\n }, [dispatch]);\n\n const products = useSelector(selectorProduct.makeSelectProducts());\n const totalPagination = useSelector(selectorProduct.makeSelectTotal());\n\n const loading = useSelector(selectorProduct.makeSelectLoading());\n\n const {\n productForMemberPage: [productPageNumber, productPageSize],\n } = useSelector(selectorsGridView.makeSelectPageCurrent());\n\n const detailCurrentItemsSelection = useSelector(\n selectorsGridView.makeSelectDetailCurrentITemsSelection()\n );\n\n const { productForMemberText, productForMemberPrimaryFieldsOnly } =\n useSelector(selectorsGlobal.selectSelectSearchText());\n\n const searchText = useMemo(() => {\n return {\n searchText: productForMemberText,\n primaryFieldsOnly: productForMemberPrimaryFieldsOnly,\n };\n }, [productForMemberText, productForMemberPrimaryFieldsOnly]);\n\n const columns = useSelector(selectorProduct.makeSelectColumns());\n\n const isDisplayProductNew = useSelector(\n selectorsGlobal.selectDisplayProductNew()\n );\n const brandingData = useSelector(brandingSelectors.getBranding());\n const stringSearchCategories = JSON.stringify(searchCategoriesEffected);\n const queryConditions = useSelector(\n selectorsGridView.makeSelectProductsForMemberQuery()\n );\n const prevPathnameQuery = useSelector(\n selectorsGridView.makeSelectPrevPathnameQuery()\n );\n clearQueryCondition(dispatch, window.location.pathname, prevPathnameQuery);\n const checkQueryCondition = useSelector(\n selectorsGridView.makeSelectCheckQueryCondition()\n );\n const myQueryDoubleClick = useSelector(\n selectorsGridView.makeSelectMyQueryDoubleClick()\n );\n const gridName = getGridName(window.location.pathname);\n\n useSaveConfigColumns(gridName);\n useSaveAllColumns(columns);\n useSaveChosenColumns(columns);\n\n const pageSize = productPageSize;\n const pageNumber = productPageNumber;\n\n useClearSearchText(dispatch, 'productForMember', window.location.pathname);\n\n const getRequestColumns = (columns) => {\n //* merge 2 default columns with columns to make sure no fields missed\n const mergedColumns = columns.concat(constant.PRODUCT_DEFAULT_GRID_COLUMN);\n\n //* remove duplicated column\n const requestColumns = _.unionBy(mergedColumns, 'fieldName');\n\n return requestColumns;\n };\n\n useEffect(() => {\n updateRibbonCallback();\n updateSearchCriteriaCallback();\n }, [updateRibbonCallback, updateSearchCriteriaCallback]);\n\n useEffect(() => {\n return () => {\n hideNewProductView();\n };\n }, []);\n\n useEffect(() => {\n if (Boolean(selectedColumns) && isDetailView) {\n requestParams.searchCategory = searchCategoriesEffected;\n requestParams.fromDate = currentDate;\n requestParams.columns = getRequestColumns(allConfigFieldsName);\n setRequestParams(requestParams);\n } else {\n setRequestParams({\n ...requestParams,\n searchCategory: searchCategoriesEffected,\n fromDate: currentDate,\n columns: getRequestColumns([]),\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n // eslint-disable-next-line react-hooks/exhaustive-deps\n JSON.stringify(searchCategoriesEffected),\n currentDate,\n selectedColumns,\n isDetailView,\n ]);\n\n //* Dispatch get Product Columns\n useEffect(() => {\n if (typeView === constant.RIBBON_TYPES.DETAILSVIEW) {\n // columns?.length === 0 &&\n dispatch(actionsProduct.gridColumnInfo('product-detail-grid'));\n }\n }, [dispatch, typeView, window.location.pathname, isDisplayProductNew]);\n\n useEffect(() => {\n if (checkQueryCondition && myQueryDoubleClick) {\n updateSizeCurrent(dispatch, 1, pageSize, window.location.pathname);\n\n const advancedSearchContainer =\n handleCreateSearchContainer(queryConditions);\n requestParams.advancedSearchContainer = advancedSearchContainer;\n setRequestParams(requestParams);\n dispatch(actionsGridView.deleteItemsSelection());\n if (typeView === constant.RIBBON_TYPES.DETAILSVIEW) {\n dispatch(actionsGridView.updateIsRefreshGrid());\n } else {\n fetchProductForMember({\n pageSize, // pageSizePagination,\n pageIndex: 1,\n search: searchText,\n filters: filterFromAssets,\n advancedSearchContainer,\n searchCategory: searchCategoriesEffected,\n packageLevels,\n isFavoriteRoute,\n fromDate: currentDate,\n });\n }\n dispatch(actionsGridView.checkQueryCondition(false));\n dispatch(actionsGridView.myQueryDoubleClick(false));\n }\n }, [\n dispatch,\n checkQueryCondition,\n pageSize,\n // filterFromAssets,\n // queryConditions,\n // searchCategoriesEffected\n ]);\n\n useEffect(() => {\n if (stringSearchCategories === 'null') return;\n\n const categoryParams = window?.productCategory;\n const brickCodeParams = window?.brickCodeHierarchy;\n const defaultFilter = [\n {\n fieldName: 'ownerId',\n value: parseInt(refMemberId.current),\n filterType: 'Equal',\n },\n ];\n\n let filters = defaultFilter;\n let arrValue = [];\n if (gridFilters.indexOf('subscription') > -1) {\n filters.push({\n fieldName: 'subscription',\n value: true,\n filterType: 'Equal',\n });\n }\n if (gridFilters.indexOf('syndication') > -1) {\n filters.push({\n fieldName: 'syndication',\n value: true,\n filterType: 'Equal',\n });\n }\n if (gridFilters.indexOf('owner') > -1) {\n filters.push({\n fieldName: 'isOwner',\n value: true,\n filterType: 'Equal',\n });\n }\n\n if (gridFilters.indexOf('pending') > -1) {\n filters.push({\n fieldName: 'status',\n value: 'Pending',\n filterType: 'Equal',\n });\n }\n\n if (gridFilters.indexOf('active') > -1) {\n filters.push({\n fieldName: 'status',\n value: 'Active',\n filterType: 'Equal',\n });\n }\n if (gridFilters.indexOf('productCategory') > -1) {\n filters.push(...categoryParams);\n }\n if (gridFilters.indexOf('brickCodeHierarchy') > -1) {\n filters.push(...brickCodeParams);\n }\n if (gridFilters.indexOf('unmatched') > -1) {\n filters.push({\n fieldName: 'meetMinRequirement',\n value: false,\n filterType: 'Equal',\n });\n filters.push({\n fieldName: 'status',\n value: 'Active',\n filterType: 'Equal',\n });\n }\n\n if (brandId) {\n filters.push({\n fieldName: 'brandId',\n value: brandId,\n filterType: 'Equal',\n });\n }\n\n if (gridFilters.indexOf('privateLabel') > -1) {\n filters.push({\n fieldName: 'isPrivateLabel',\n value: true,\n filterType: 'Equal',\n });\n }\n\n if (\n gridFilters.indexOf('Pallet') > -1 ||\n gridFilters.indexOf('Master Case') > -1 ||\n gridFilters.indexOf('Case') > -1 ||\n gridFilters.indexOf('Inner Pack') > -1 ||\n gridFilters.indexOf('Unit') > -1 ||\n gridFilters.indexOf('Display Shipper') > -1\n ) {\n if (gridFilters.indexOf('Pallet') > -1) {\n arrValue.push('Pallet');\n }\n if (gridFilters.indexOf('Master Case') > -1) {\n arrValue.push('Master Case');\n }\n if (gridFilters.indexOf('Case') > -1) {\n arrValue.push('Case');\n }\n if (gridFilters.indexOf('Inner Pack') > -1) {\n arrValue.push('Inner Pack');\n }\n if (gridFilters.indexOf('Unit') > -1) {\n arrValue.push('Unit');\n }\n if (gridFilters.indexOf('Display Shipper') > -1) {\n arrValue.push('Display Shipper');\n }\n }\n const aplFilter =\n _.isArray(gridFilters) &&\n gridFilters.find((val) => val?.filter === 'apl')?.value?.id;\n\n requestParams.packageLevels = arrValue;\n requestParams.searchCategory = searchCategoriesEffected;\n requestParams.columns = getRequestColumns(\n Boolean(selectedColumns) ? allConfigFieldsName : []\n );\n requestParams.aplId = aplFilter;\n\n setPackageLevels(arrValue);\n setRequestParams(requestParams);\n setFilterFromAssets(filters);\n setAplId(aplFilter);\n if (\n //!warning = this condtion might be wrong since the querycondition should be applied for all view type\n // typeView !== constant.RIBBON_TYPES.DETAILSVIEW &&\n !checkQueryCondition &&\n !myQueryDoubleClick\n ) {\n const advancedSearchContainer =\n handleCreateSearchContainer(queryConditions);\n requestParams.advancedSearchContainer = advancedSearchContainer;\n requestParams.searchCategory = searchCategoriesEffected;\n requestParams.fromDate = currentDate;\n\n setRequestParams(requestParams);\n setPackageArray(arrValue);\n\n //* this line makes bug occur in grid view selection when change type view (sprint 34 - ticket 1305)\n\n if (typeView !== constant.RIBBON_TYPES.DETAILSVIEW) {\n //* when view type !== detail view\n\n currentDate &&\n isDisplayProductNew &&\n fetchProductForMember({\n pageSize,\n pageIndex: pageNumber,\n search: searchText,\n filters,\n advancedSearchContainer,\n searchCategory: searchCategoriesEffected,\n packageLevels: arrValue,\n isFavoriteRoute,\n fromDate: currentDate,\n aplId: aplFilter,\n });\n\n !currentDate &&\n !isDisplayProductNew &&\n fetchProductForMember({\n pageSize,\n pageIndex: pageNumber,\n search: searchText,\n filters,\n advancedSearchContainer,\n searchCategory: searchCategoriesEffected,\n packageLevels: arrValue,\n isFavoriteRoute,\n aplId: aplFilter,\n });\n }\n }\n }, [\n dispatch,\n searchText,\n typeView,\n isFavoriteRoute,\n gridFilters,\n stringSearchCategories,\n currentDate,\n pageSize,\n pageNumber,\n brandId,\n ]);\n\n useEffect(() => {\n if (reloadGrid && typeView !== constant.RIBBON_TYPES.DETAILSVIEW) {\n const advancedSearchContainer =\n handleCreateSearchContainer(queryConditions);\n fetchProductForMember({\n pageSize, // pageSizePagination,\n pageIndex: pageNumber, // pageIndexPagination,\n search: searchText,\n filters: filterFromAssets,\n advancedSearchContainer,\n searchCategory: searchCategoriesEffected,\n packageArray,\n isFavoriteRoute,\n fromDate: currentDate,\n });\n }\n }, [dispatch, typeView, reloadGrid, pageSize, pageNumber]);\n\n useEffect(() => {\n return () => {\n dispatch(actionsGridView.deleteItemsSelection());\n dispatch(actionsGridView.updatePagesSelection([]));\n dispatch(actionsGridView.updateItemPageSelection([]));\n };\n }, [\n dispatch,\n searchText,\n gridFilters,\n JSON.stringify(searchCategoriesEffected),\n ]);\n\n useEffect(() => {\n updateCurrentDate();\n }, [isDisplayProductNew, isFavoriteRoute]);\n\n //update here when api release\n useEffect(() => {\n if (isDisplayProductNew && currentDate) {\n updateLatestGetNew();\n }\n }, [isDisplayProductNew, currentDate]);\n\n // re-call api when page need to reload\n useListenReloadPage(() => {\n const advancedSearchContainer =\n handleCreateSearchContainer(queryConditions);\n\n fetchProductForMember({\n pageSize,\n pageIndex: pageNumber,\n search: searchText,\n filters: filterFromAssets,\n advancedSearchContainer,\n searchCategory: searchCategoriesEffected,\n packageLevels,\n isFavoriteRoute,\n fromDate: currentDate,\n aplId: aplId,\n });\n });\n\n useUpdateSelectedData(products);\n\n const ProductTileRender = (configProps) => {\n return ;\n };\n\n const ProductThumbnailRender = (configProps) => {\n return ;\n };\n\n const onClickToSeeAll = () => {\n //todo - fix reset page current later - 1/26/2022\n // dispatch(actionsGridView.resetPageCurrentProduct());\n hideNewProductView();\n };\n\n const hideNewProductView = () => {\n dispatch(actionsProduct.toggleProductNew(false));\n setCurrentDate(null);\n setFilterFromAssets([]);\n };\n\n const updateCurrentDate = () => {\n if (isFavoriteRoute) {\n hideNewProductView();\n return;\n }\n if (isDisplayProductNew) {\n dispatch(actionsGlobal.updateFilterProducts([]));\n setCurrentDate(brandingData?.lastGetNewProductsTime);\n } else {\n setCurrentDate(null);\n }\n };\n\n const updateLatestGetNew = () => {\n dispatch(brandingActions.updateLastGetNewProduct());\n };\n\n const urlGrid = endpointsProduct.GET_PRODUCT_DETAIL_CUSTOMIZED_GRID;\n const urlGridDistinct =\n endpointsProduct.GET_PRODUCT_DETAIL_CUSTOMIZED_GRID_DISTINCT;\n\n const productInfo = detailCurrentItemsSelection?.[0];\n\n return (\n \n \n \n \n }\n isToggle={isDisplayProductNew}\n onClickToSeeAll={onClickToSeeAll}\n applyDefaultSort={searchText ? false : true}\n />\n \n );\n};\n\nexport default ProductForMemberGrid;\n","import * as types from './constants';\n\nexport const showLoading = () => {\n return {\n type: types.SHOW_LOADING,\n };\n};\n\nexport function getMemberList(\n pageSize,\n pageNumber,\n search,\n primaryFieldsOnly,\n atTime,\n advancedSearchContainer,\n searchCategory,\n filters,\n isFavoriteRoute\n) {\n if (atTime)\n return {\n type: types.GET_MEMBER_LIST,\n fromDate: atTime,\n pageSize,\n pageNumber,\n 'Search.SearchText': search,\n searchText: search,\n primaryFieldsOnly,\n advancedSearchContainer,\n searchCategory,\n filters,\n isFavoriteRoute,\n };\n else\n return {\n type: types.GET_MEMBER_LIST,\n pageSize,\n pageNumber,\n 'Search.SearchText': search,\n searchText: search,\n primaryFieldsOnly,\n advancedSearchContainer,\n searchCategory,\n filters,\n isFavoriteRoute,\n };\n}\n\nexport function getMemberListSuccess(members, total) {\n return {\n type: types.GET_MEMBER_LIST_SUCCESS,\n members,\n total,\n };\n}\n\nexport function getMemberListError(error) {\n return {\n type: types.GET_MEMBER_LIST_ERROR,\n error,\n };\n}\n\nexport function gridMemberColumnInfo(gridName) {\n return {\n type: types.MEMBER_GRID_COLUMN_INFO,\n gridName,\n };\n}\n\nexport function gridMemberColumnInfoSuccess(columns) {\n return {\n type: types.MEMBER_GRID_COLUMN_INFO_SUCCESS,\n columns,\n };\n}\n\nexport function gridMemberColumnInfoError(error) {\n return {\n type: types.MEMBER_GRID_COLUMN_INFO_ERROR,\n };\n}\n\nexport function banListColumnInfo(gridName, userId) {\n return {\n type: types.BAN_LIST_GRID_COLUMN_INFO,\n gridName,\n };\n}\n\nexport function banListColumnInfoSuccess(columns) {\n return {\n type: types.BAN_LIST_GRID_COLUMN_INFO_SUCCESS,\n columns,\n };\n}\n\nexport function banListColumnInfoError(error) {\n return {\n type: types.BAN_LIST_GRID_COLUMN_INFO_ERROR,\n };\n}\n\nexport function getMemberShortDetail(id) {\n return {\n type: types.GET_MEMBER_SHORT_DETAIL,\n id,\n };\n}\n\nexport function getMemberShortDetailSuccess(data) {\n return {\n type: types.GET_MEMBER_SHORT_DETAIL_SUCCESS,\n data,\n };\n}\n\nexport function getMemberShortDetailError(error) {\n return {\n type: types.GET_MEMBER_SHORT_DETAIL_ERROR,\n error,\n };\n}\n\n// Products for member\nexport function getProductsForMember(params) {\n return {\n type: types.GET_PRODUCTS_FOR_MEMBER,\n params,\n };\n}\n\nexport function getProductsForMemberSuccess(data) {\n return {\n type: types.GET_PRODUCTS_FOR_MEMBER_SUCCESS,\n data,\n };\n}\n\nexport function getProductsForMemberError(error) {\n return {\n type: types.GET_PRODUCTS_FOR_MEMBER_ERROR,\n error,\n };\n}\n\nexport function resetProductsForMemberState() {\n return {\n type: types.RESET_PRODUCT_FOR_MEMBER_STATE,\n };\n}\n\nexport function getColumnsProductsForMember(gridName) {\n return {\n type: types.GET_COLUMNS_PRODUCTS_FOR_MEMBER,\n gridName,\n };\n}\n\nexport function getColumnsProductsForMemberSuccess(columns) {\n return {\n type: types.GET_COLUMNS_PRODUCTS_FOR_MEMBER_SUCCESS,\n columns,\n };\n}\n\nexport function getColumnsProductsForMemberError(error) {\n return {\n type: types.GET_COLUMNS_PRODUCTS_FOR_MEMBER_ERROR,\n error,\n };\n}\n\nexport function saveIdMember(id) {\n return {\n type: types.SAVE_ID_MEMBER,\n id,\n };\n}\n\nexport function getPublicContact(memberId) {\n return {\n type: types.GET_PUBLIC_CONTACT_MEMBER,\n memberId,\n };\n}\n\nexport function getPublicContactSuccess(data) {\n return {\n type: types.GET_PUBLIC_CONTACT_MEMBER_SUCCESS,\n data,\n };\n}\n\nexport function getPublicContactError(error) {\n return {\n type: types.GET_PUBLIC_CONTACT_MEMBER_ERROR,\n error,\n };\n}\n\nexport function removeBanList(data) {\n return {\n type: types.REMOVE_BAN_LIST,\n data,\n };\n}\n\nexport function removeBanListSuccess(data) {\n return {\n type: types.REMOVE_BAN_LIST_SUCCESS,\n data,\n };\n}\n\nexport function removeBanListError(error) {\n return {\n type: types.REMOVE_BAN_LIST_ERROR,\n error,\n };\n}\n","// Action Types\nexport const SHOW_LOADING = 'SHOW_LOADING';\n\nexport const GET_MEMBER_LIST = 'GET_MEMBER_LIST';\nexport const GET_MEMBER_LIST_SUCCESS = 'GET_MEMBER_LIST_SUCCESS';\nexport const GET_MEMBER_LIST_ERROR = 'GET_MEMBER_LIST_ERROR';\n\nexport const MEMBER_GRID_COLUMN_INFO = 'MEMBER_GRID_COLUMN_INFO';\nexport const MEMBER_GRID_COLUMN_INFO_SUCCESS =\n 'MEMBER_GRID_COLUMN_INFO_SUCCESS';\nexport const MEMBER_GRID_COLUMN_INFO_ERROR = 'MEMBER_GRID_COLUMN_INFO_ERROR';\nexport const GET_MEMBER_SHORT_DETAIL = 'GET_MEMBER_SHORT_DETAIL';\nexport const GET_MEMBER_SHORT_DETAIL_SUCCESS =\n 'GET_MEMBER_SHORT_DETAIL_SUCCESS';\nexport const GET_MEMBER_SHORT_DETAIL_ERROR = 'GET_MEMBER_SHORT_DETAIL_ERROR';\n\n// Products for members\nexport const GET_PRODUCTS_FOR_MEMBER = 'GET_PRODUCTS_FOR_MEMBER';\nexport const GET_PRODUCTS_FOR_MEMBER_SUCCESS =\n 'GET_PRODUCTS_FOR_MEMBER_SUCCESS';\nexport const GET_PRODUCTS_FOR_MEMBER_ERROR = 'GET_PRODUCTS_FOR_MEMBER_ERROR';\nexport const RESET_PRODUCT_FOR_MEMBER_STATE = 'RESET_PRODUCT_FOR_MEMBER_STATE';\n\nexport const GET_COLUMNS_PRODUCTS_FOR_MEMBER =\n 'GET_COLUMNS_PRODUCTS_FOR_MEMBER';\nexport const GET_COLUMNS_PRODUCTS_FOR_MEMBER_SUCCESS =\n 'GET_COLUMNS_PRODUCTS_FOR_MEMBER_SUCCESS';\nexport const GET_COLUMNS_PRODUCTS_FOR_MEMBER_ERROR =\n 'GET_COLUMNS_PRODUCTS_FOR_MEMBER_ERROR';\n\nexport const SAVE_ID_MEMBER = 'SAVE_ID_MEMBER';\n\nexport const GET_PUBLIC_CONTACT_MEMBER = 'GET_PUBLIC_CONTACT_MEMBER';\nexport const GET_PUBLIC_CONTACT_MEMBER_SUCCESS =\n 'GET_PUBLIC_CONTACT_MEMBER_SUCCESS';\nexport const GET_PUBLIC_CONTACT_MEMBER_ERROR = 'GET_PUBLIC_CONTACT_ERROR';\nexport const BAN_LIST_GRID_COLUMN_INFO = 'BAN_LIST_GRID_COLUMN_INFO';\nexport const BAN_LIST_GRID_COLUMN_INFO_SUCCESS =\n 'BAN_LIST_GRID_COLUMN_INFO_SUCCESS';\nexport const BAN_LIST_GRID_COLUMN_INFO_ERROR =\n 'BAN_LIST_GRID_COLUMN_INFO_ERROR';\nexport const REMOVE_BAN_LIST = 'REMOVE_BAN_LIST';\nexport const REMOVE_BAN_LIST_SUCCESS = 'REMOVE_BAN_LIST_SUCCESS';\nexport const REMOVE_BAN_LIST_ERROR = 'REMOVE_BAN_LIST_ERROR';\n\n","import produce from 'immer';\nimport * as types from './constants';\n\n// initial state\nexport const initialState = {\n loading: false,\n error: false,\n members: [],\n total: 0,\n pageSize: 20,\n pageNumber: 1,\n search: '',\n columns: [],\n gridName: '',\n memberData: null,\n loadingDetail: false,\n publicContactList: null,\n banListColumns: [],\n\n productsForMember: {\n loading: false,\n pageIndex: 1,\n pageSize: 20,\n totalItems: 0,\n data: [],\n columns: [],\n memberId: null,\n },\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst productReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.SHOW_LOADING:\n draft.loading = true;\n break;\n case types.GET_MEMBER_LIST:\n draft.loading = true;\n draft.error = false;\n draft.pageSize = action.pageSize;\n draft.pageNumber = action.pageNumber;\n draft.search = action.search;\n break;\n case types.GET_MEMBER_LIST_SUCCESS:\n draft.loading = false;\n draft.members = action.members;\n draft.total = action.total;\n break;\n case types.GET_MEMBER_LIST_ERROR:\n draft.loading = false;\n draft.total = 0;\n draft.members = [];\n draft.error = action.error;\n break;\n case types.MEMBER_GRID_COLUMN_INFO:\n draft.error = false;\n draft.gridName = action.gridName;\n break;\n case types.MEMBER_GRID_COLUMN_INFO_SUCCESS:\n draft.loading = false;\n draft.columns = action.columns;\n break;\n case types.MEMBER_GRID_COLUMN_INFO_ERROR:\n draft.loading = false;\n break;\n case types.BAN_LIST_GRID_COLUMN_INFO:\n // draft.error = false;\n break;\n case types.BAN_LIST_GRID_COLUMN_INFO_SUCCESS:\n draft.banListColumns = action.columns;\n break;\n case types.BAN_LIST_GRID_COLUMN_INFO_ERROR:\n break;\n case types.GET_MEMBER_SHORT_DETAIL:\n draft.loadingDetail = true;\n draft.error = false;\n break;\n case types.GET_MEMBER_SHORT_DETAIL_SUCCESS:\n draft.loadingDetail = false;\n draft.memberData = action.data;\n break;\n case types.GET_MEMBER_SHORT_DETAIL_ERROR:\n draft.loadingDetail = false;\n draft.error = action.error;\n break;\n\n case types.GET_PRODUCTS_FOR_MEMBER:\n draft.productsForMember['loading'] = true;\n break;\n\n case types.GET_PRODUCTS_FOR_MEMBER_SUCCESS:\n draft.productsForMember['loading'] = false;\n draft.productsForMember['data'] = action.data.gridData;\n draft.productsForMember['pageIndex'] =\n action.data.paging.currentPageIndex;\n draft.productsForMember['pageSize'] =\n action.data.paging.currentPageSize;\n draft.productsForMember['totalItems'] = action.data.paging.totalRecord;\n break;\n\n case types.RESET_PRODUCT_FOR_MEMBER_STATE:\n draft.productsForMember['loading'] = false;\n draft.productsForMember['data'] = [];\n draft.productsForMember['pageIndex'] = 1;\n draft.productsForMember['pageSize'] = 20;\n draft.productsForMember['totalItems'] = 0;\n break;\n\n case types.GET_COLUMNS_PRODUCTS_FOR_MEMBER_SUCCESS:\n draft.productsForMember['columns'] = action.columns;\n break;\n\n case types.SAVE_ID_MEMBER:\n draft.productsForMember['memberId'] = action.id;\n break;\n\n case types.GET_PUBLIC_CONTACT_MEMBER:\n draft.loadingDetail = true;\n draft.error = null;\n break;\n case types.GET_PUBLIC_CONTACT_MEMBER_SUCCESS:\n draft.loadingDetail = false;\n draft.publicContactList = action.data;\n draft.error = null;\n break;\n case types.GET_PUBLIC_CONTACT_MEMBER_ERROR:\n draft.loadingDetail = false;\n draft.publicContactList = null;\n draft.error = action.error;\n break;\n\n }\n });\n\nexport default productReducer;\n","import React from 'react';\nimport { put, call, takeLatest, all } from 'redux-saga/effects';\n\nimport * as types from './constants';\nimport * as actions from './actions';\nimport * as services from 'services/members';\nimport * as servicesGrid from 'services/grid';\nimport * as ribbonType from '@redux/ribbon/constants';\nimport { AgGridIcons, GlnTooltip, AgGridThumbnail } from 'common/components';\nimport { DEFAULT_SORT } from 'static/Constants';\nimport { notification } from 'antd';\nimport CheckboxGrid from '../components/checkbox-grid/CheckboxGrid';\nimport { MemberLogo } from '../components';\n\nimport { formatProductDetailColumns } from 'pages/branded-products/controllers/saga';\n\nconst renderIcons = (params) => {\n const data = params?.data;\n\n return (\n \n );\n};\n\nconst onMemberLogoRender = (param) => {\n return ;\n};\n\nconst renderGlns = (params) => {\n return ;\n};\n\nexport function* getMemberList(payload) {\n const { searchText, primaryFieldsOnly } = payload;\n\n const params = {\n ...payload,\n ...(searchText ? null : { sort: DEFAULT_SORT }),\n search: { searchText: searchText, primaryFieldsOnly: primaryFieldsOnly },\n };\n\n try {\n const response = yield call(services.getMemberList, params);\n\n const data = response?.data?.gridData || response?.gridData;\n const paging = response?.data?.paging || response?.paging;\n yield put(actions.getMemberListSuccess(data, paging?.totalRecord));\n } catch (error) {\n yield put(actions.getMemberListError(error));\n }\n}\n\nexport function* getMemberShortDetail(payload) {\n try {\n const response = yield call(services.getMemberShortDetail, {\n Id: payload.id,\n });\n const { isSuccess, data, message } = response;\n if (isSuccess) {\n yield put(actions.getMemberShortDetailSuccess(data));\n } else {\n yield put(actions.getMemberShortDetailError(message));\n }\n } catch (error) {\n yield put(actions.getMemberShortDetailError(error));\n }\n}\n\nexport function* gridMemberColumnInfo(payload) {\n try {\n const { response } = yield call(getColumnsFilter, payload);\n\n let columns = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n },\n {\n field: 'memberLogo',\n headerName: 'Member Logo',\n cellRenderer: onMemberLogoRender,\n filter: false,\n width: 70,\n resizable: false,\n allowSort: false,\n headerClass: 'header-text-hide',\n },\n {\n field: 'stateIcons',\n headerName: 'States',\n minWidth: 150,\n cellRenderer: renderIcons,\n filter: false,\n resizable: true,\n allowSort: false,\n headerClass: 'header-text-hide',\n },\n ];\n\n if (response && response.columns && response.columns.length > 0) {\n response.columns.forEach((val, index) => {\n if (\n val.fieldName !== 'Id' &&\n val.fieldName !== 'Type' &&\n val.fieldName !== 'ParentCompanyId' &&\n val.fieldName !== 'Thumb300' &&\n val.fieldName !== 'Thumb'\n ) {\n // let obj = Object.assign(val, { filterValues: filter[index] });\n const col = { ...val, resizable: true };\n if (val.fieldName === 'MemberName') {\n col.linkTo = `/company/{id}`;\n col.minWidth = 300;\n }\n\n if (val.fieldName === 'Glns') {\n col.filter = false;\n col.allowFilter = false;\n col.suppressMenu = true;\n col.allowSort = false;\n col.cellRenderer = renderGlns;\n }\n\n columns.push(col);\n }\n });\n }\n\n yield put(actions.gridMemberColumnInfoSuccess(columns));\n } catch (error) {\n yield put(actions.gridMemberColumnInfoError(error));\n }\n}\n\nexport function* getColumnsFilter(payload) {\n const response = yield call(servicesGrid.gridColumnInfo, payload.gridName);\n // const filter = yield call(getFilter, response);\n return { response };\n}\n\nexport function* getFilter(response) {\n const filter = yield all(\n response.columns &&\n response.columns.length > 0 &&\n response.columns.map((val) =>\n call(services.getMemberDetailGridDistinct, {\n fieldName: val.fieldName,\n })\n )\n );\n return filter;\n}\n\nexport function* getColumnsProductsForMembersSaga(payload) {\n try {\n const { response } = yield call(getColumnsFilter, payload);\n\n const columns = formatProductDetailColumns(response);\n\n yield put(actions.getColumnsProductsForMemberSuccess(columns));\n } catch (error) {\n yield put(actions.getColumnsProductsForMemberError(error));\n }\n}\n\nconst renderIconOwner = (params) => {\n return ;\n};\n\nexport function* getColumnForBanList(action) {\n try {\n const { response } = yield call(getColumnsFilter, action);\n\n const checkboxColumn = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n resizable: true,\n },\n ];\n\n let result = [];\n\n if (response && response.columns && response.columns.length > 0) {\n response.columns.forEach((val, index) => {\n if (val.fieldNameCamelCase === 'banByMemberName') {\n result.push({ ...val, resizable: true, width: 240 });\n } else if (val.fieldNameCamelCase === 'bannedMemberName') {\n result.push({ ...val, resizable: true, flex: 1 });\n }\n });\n }\n yield put(actions.banListColumnInfoSuccess([...checkboxColumn, ...result]));\n } catch (error) {\n yield put(actions.banListColumnInfoError(error));\n }\n}\n\nexport function* fetchPublicContact(payload) {\n if (payload.memberId) {\n try {\n const response = yield call(services.getPublicContact, {\n memberId: Number(payload.memberId),\n pageIndex: 1,\n pageSize: 100,\n });\n yield put({\n type: types.GET_PUBLIC_CONTACT_MEMBER_SUCCESS,\n data: response?.data?.gridData,\n });\n } catch (error) {\n yield put({\n type: types.GET_PUBLIC_CONTACT_MEMBER_ERROR,\n error,\n });\n }\n }\n}\n\nexport function* addToBanList(payload) {\n if (payload) {\n try {\n const response = yield call(services.addToBanList, {\n memberIds: payload.data,\n });\n if (response.isSuccess) {\n notification.success({ message: 'Add to ban list success' });\n yield put({\n type: types.GET_MEMBER_LIST,\n isFavoriteRoute: payload.isFavoriteRoute,\n pageSize: payload.page[1] !== 0 ? payload.page[1] : 20,\n pageNumber: 1,\n });\n }\n } catch (error) {}\n }\n}\n\nexport function* removeToBanList(payload) {\n if (payload) {\n try {\n const response = yield call(services.removeToBanList, {\n memberIds: payload.data,\n });\n if (response.isSuccess) {\n notification.success({ message: 'Remove from ban list success' });\n }\n } catch (error) {}\n }\n}\n\nfunction* watchAll() {\n yield all([\n takeLatest(types.GET_MEMBER_SHORT_DETAIL, getMemberShortDetail),\n takeLatest(types.GET_MEMBER_LIST, getMemberList),\n takeLatest(types.MEMBER_GRID_COLUMN_INFO, gridMemberColumnInfo),\n takeLatest(\n types.GET_COLUMNS_PRODUCTS_FOR_MEMBER,\n getColumnsProductsForMembersSaga\n ),\n takeLatest(types.GET_PUBLIC_CONTACT_MEMBER, fetchPublicContact),\n takeLatest(ribbonType.ADD_TO_BAN_LIST, addToBanList),\n takeLatest(types.BAN_LIST_GRID_COLUMN_INFO, getColumnForBanList),\n takeLatest(types.REMOVE_BAN_LIST, removeToBanList),\n ]);\n}\n\nexport default watchAll;\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\nconst selectMemberList = (state) => state.memberList || initialState;\n\nconst makeSelectLoading = () =>\n createSelector(selectMemberList, (memberState) => memberState.loading);\nconst makeSelectMemberList = () =>\n createSelector(selectMemberList, (memberState) => memberState.members);\nconst makeSelectTotal = () =>\n createSelector(selectMemberList, (memberState) => memberState.total);\nconst makeSelectPageSize = () =>\n createSelector(selectMemberList, (memberState) => memberState.pageSize);\nconst makeSelectPageNumber = () =>\n createSelector(selectMemberList, (memberState) => memberState.pageNumber);\nconst makeSelectSearch = () =>\n createSelector(selectMemberList, (memberState) => memberState.search);\nconst makeSelectColumns = () =>\n createSelector(selectMemberList, (memberState) => memberState.columns);\nconst makeSelectBanListColumns = () =>\n createSelector(selectMemberList, (memberState) => memberState.banListColumns);\nconst makeSelectLoadingDetail = () =>\n createSelector(selectMemberList, (memberState) => memberState.loadingDetail);\nconst makeSelectMemberData = () =>\n createSelector(selectMemberList, (memberState) => memberState.memberData);\nconst makeSelectPublicContactList = () =>\n createSelector(\n selectMemberList,\n (memberState) => memberState.publicContactList\n );\n\nconst makeSelectProductsForMember = () =>\n createSelector(\n selectMemberList,\n (memberState) => memberState.productsForMember\n );\n\nconst makeSelectIsDisplayMemberNew = () =>\n createSelector(\n selectMemberList,\n (memberState) => memberState.isDisplayMemberNew\n );\n\nexport {\n selectMemberList,\n makeSelectLoading,\n makeSelectMemberList,\n makeSelectTotal,\n makeSelectPageSize,\n makeSelectPageNumber,\n makeSelectSearch,\n makeSelectColumns,\n makeSelectLoadingDetail,\n makeSelectMemberData,\n makeSelectProductsForMember,\n makeSelectPublicContactList,\n makeSelectBanListColumns,\n makeSelectIsDisplayMemberNew,\n};\n","import * as types from './constants';\n\nexport const getAPLGridColumns = (gridName) => ({\n type: types.GET_PRODUCT_APL_GRID_COLUMN,\n payload: gridName,\n});\n\nexport const getAPLGridColumnsSuccess = (columns) => {\n return {\n type: types.GET_PRODUCT_APL_GRID_COLUMN_SUCCESS,\n payload: columns,\n };\n};\n\nexport const getAPLGridColumnsError = (error) => ({\n type: types.GET_PRODUCT_APL_GRID_COLUMN_ERROR,\n payload: error,\n});\n\nexport function setSelectedDate(payload) {\n return {\n type: types.SET_APL_SCHEDULE_SELECTED_DATE,\n payload,\n };\n}\n\nexport function setScheduleEvents(payload) {\n return {\n type: types.SET_APL_SCHEDULE_EVENTS,\n payload,\n };\n}\n\nexport function setScheduleIsDragStart(status) {\n return {\n type: types.SET_APL_SCHEDULE_IS_DRAG_START,\n status,\n };\n}\n\nexport function toggleScheduleModal(payload) {\n return {\n type: types.TOGGLE_APL_SCHEDULE_MODAL,\n payload,\n };\n}\n\nexport function toggleReloadGridApl() {\n return {\n type: types.TOGGLE_RELOAD_GRID_APL,\n };\n}\n\nexport function resetReloadGridApl() {\n return {\n type: types.RESET_RELOAD_GRID_APL,\n };\n}\n","export const GET_PRODUCT_APL_GRID_COLUMN = 'GET_PRODUCT_APL_GRID_COLUMN';\nexport const GET_PRODUCT_APL_GRID_COLUMN_SUCCESS =\n 'GET_PRODUCT_APL_GRID_COLUMN_SUCCESS';\nexport const GET_PRODUCT_APL_GRID_COLUMN_ERROR =\n 'GET_PRODUCT_APL_GRID_COLUMN_ERROR';\n\nexport const SET_APL_SCHEDULE_SELECTED_DATE = 'SET_APL_SCHEDULE_SELECTED_DATE';\nexport const SET_APL_SCHEDULE_EVENTS = 'SET_APL_SCHEDULE_EVENTS';\nexport const SET_APL_SCHEDULE_IS_DRAG_START = 'SET_APL_SCHEDULE_IS_DRAG_START';\nexport const TOGGLE_APL_SCHEDULE_MODAL = 'TOGGLE_APL_SCHEDULE_MODAL';\n\nexport const TOGGLE_RELOAD_GRID_APL = 'TOGGLE_RELOAD_GRID_APL';\nexport const RESET_RELOAD_GRID_APL = 'RESET_RELOAD_GRID_APL';\n","import produce from 'immer';\nimport * as types from './constants';\n\n// initial state\n\nexport const initialState = {\n loading: false,\n productAplColumns: [],\n error: null,\n reloadGrid: false,\n};\n\nconst productAPLReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_PRODUCT_APL_GRID_COLUMN:\n draft.loading = true;\n draft.productAplColumns = [];\n break;\n case types.GET_PRODUCT_APL_GRID_COLUMN_SUCCESS:\n draft.loading = false;\n draft.productAplColumns = action.payload;\n break;\n case types.GET_PRODUCT_APL_GRID_COLUMN_ERROR:\n draft.loading = false;\n draft.productAplColumns = [];\n draft.error = action.payload;\n break;\n\n case types.TOGGLE_RELOAD_GRID_APL:\n draft.reloadGrid = true;\n break;\n case types.RESET_RELOAD_GRID_APL:\n draft.reloadGrid = false;\n break;\n\n default:\n break;\n }\n });\n\nexport default productAPLReducer;\n","import { put, call, takeLatest, all } from 'redux-saga/effects';\nimport * as servicesGrid from 'services/grid';\nimport * as types from './constants';\nimport * as actions from './actions';\n\nimport { formatMDYWithParam } from 'utils/formatDate';\nimport { calculateToPercentByParam } from 'utils/formatSizeUnits';\n\nexport function* getProductAplColumns(action) {\n const { linkTarget } = action.payload || {};\n try {\n const response = yield call(servicesGrid.gridColumnInfo, 'apl-grid');\n let columns = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n sortable: false,\n },\n ];\n if (response?.columns?.length > 0) {\n let hiddenCol = [\n 'id',\n 'ownerCompanyId',\n 'createdBy', // createById\n 'shareable',\n 'type',\n ];\n const dateList = ['created', 'lastModified'];\n response.columns.forEach((val, index) => {\n if (hiddenCol.indexOf(val.fieldNameCamelCase) === -1) {\n // eslint-disable-next-line no-lone-blocks\n {\n if (val.fieldNameCamelCase === 'aplDescription') {\n val = { ...val, flex: 1, minWidth: 200, resizable: true };\n } else if (dateList.includes(val.fieldNameCamelCase)) {\n val = {\n ...val,\n width: 140,\n cellRenderer: formatMDYWithParam,\n resizable: true,\n };\n } else if (val.fieldNameCamelCase === 'matchedRate') {\n val = {\n ...val,\n width: 120,\n cellRenderer: calculateToPercentByParam,\n resizable: true,\n };\n } else {\n val = { ...val, width: 160, resizable: true };\n }\n\n if (val.fieldNameCamelCase === 'aplName')\n val = {\n ...val,\n linkTo: '/products/apl/{id}',\n minWidth: 300,\n linkTarget,\n };\n\n columns.push(val);\n }\n }\n });\n }\n\n yield put(actions.getAPLGridColumnsSuccess(columns));\n } catch (error) {\n yield put(actions.getAPLGridColumnsError(error));\n }\n}\n\nfunction* watchAll() {\n yield all([\n takeLatest(types.GET_PRODUCT_APL_GRID_COLUMN, getProductAplColumns),\n ]);\n}\n\nexport default watchAll;\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\nconst selectProductAPL = (state) => state.productAPL || initialState;\n\nconst selectProductAPLColumns = () =>\n createSelector(selectProductAPL, (aplState) => aplState.productAplColumns);\n\nconst makeSelectReloadGridApl = () =>\n createSelector(selectProductAPL, (aplState) => aplState.reloadGrid);\n\nexport { selectProductAPLColumns, makeSelectReloadGridApl };\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { ThumbnailItem } from 'common/components';\nimport { useCheckAllowEditProducts } from 'hooks';\n\nconst ProductThumbnail = (props) => {\n const {\n dataDetail,\n selected,\n onClickItemGrid,\n onClickCheckboxItem,\n onDoubleClick,\n labelThumbnail,\n imageThumbnail,\n ...rest\n } = props;\n\n const { checkAllowEditProductFull } = useCheckAllowEditProducts();\n\n const isAllowEditProduct = checkAllowEditProductFull(dataDetail);\n\n return (\n \n );\n};\nProductThumbnail.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductThumbnail;\n","import React from 'react';\n\nimport { Row, Col, Typography, Spin } from 'antd';\nimport { LoadingOutlined } from '@ant-design/icons';\nimport { TooltipParagraph } from 'common/components';\nimport { findDimensionEnumDisplay } from '../../../product-full-view/mappers/mapToEnums';\n\nconst Loading = () => {\n const loadingIcon = ;\n\n return (\n
\n \n
\n );\n};\n\nconst InformationLabel = ({ children, ...otherProps }) => {\n return (\n \n \n {children}:\n \n \n );\n};\n\nconst InformationData = ({ data, children, ...otherProps }) => {\n return (\n \n {children}\n {data && {data}}\n \n );\n};\n\nconst ListDimensionInfo = ({\n listNameDimension,\n listImperialValue,\n imperialUnit,\n listMetricValue,\n metricUnit,\n productEnums,\n}) => {\n return (\n <>\n {listImperialValue.map((imperialValue, index) => (\n \n ))}\n \n );\n};\n\nconst DimensionInfo = ({\n name,\n\n imperialValue,\n imperialUnit,\n metricValue,\n metricUnit,\n productEnums,\n}) => {\n return (\n \n \n {name}: \n \n {isNaN(parseFloat(imperialValue)) ? (\n 'N/A'\n ) : (\n <>\n {Math.round(parseFloat(imperialValue) * 100) / 100}{' '}\n {findDimensionEnumDisplay(imperialUnit, productEnums)}\n \n )}\n \n \n \n {name}: \n \n {isNaN(parseFloat(metricValue)) ? (\n 'N/A'\n ) : (\n <>\n {Math.round(parseFloat(metricValue) * 100) / 100}{' '}\n {findDimensionEnumDisplay(metricUnit, productEnums)}\n \n )}\n \n \n \n );\n};\n\nexport {\n InformationLabel,\n InformationData,\n ListDimensionInfo,\n DimensionInfo,\n Loading,\n};\n","import React, { useRef, useEffect, useState } from 'react';\nimport { useSelector } from 'react-redux';\nimport { useIntl } from 'react-intl';\n\nimport { Row, Col, Tooltip, Typography, Divider } from 'antd';\nimport { EyeOutlined } from '@ant-design/icons';\nimport { isEmpty } from 'lodash';\n\nimport Messages from 'i18n/messages/product';\n\nimport { FavoriteStarIconRender, Img } from 'common/components';\nimport {\n InformationLabel,\n InformationData,\n ListDimensionInfo,\n DimensionInfo,\n Loading,\n} from './SharedComponents';\n\nimport { Images } from 'config/assets';\n\nimport useDoubleClick from 'hooks/useDoubleClick';\nimport { forwardTo } from 'utils/common/route';\n\nimport { getProductShortDetail } from 'services/product';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\n\nimport { useGetProductEnums } from 'hooks';\n\nimport './style.less';\n\n/**\n * Use for Content Pane\n * Use for Right section of Product History\n */\nconst ProductContentPanel = (props) => {\n const {\n historyPage = false,\n productShortDetailHistory,\n historyProductId,\n productId,\n forceVisible = false,\n getProductDetail,\n } = props;\n\n const detailCurrentItemsSelection = useSelector(\n selectorsGridView.makeSelectDetailCurrentITemsSelection()\n );\n\n const idProduct = detailCurrentItemsSelection[0]?.id || productId;\n\n const visibleContentPanel = useSelector(\n selectorsGridView.makeSelectVisible()\n );\n\n const [product, setProduct] = useState(null);\n\n useEffect(() => {\n if (!productId) setProduct(null);\n\n if (\n historyPage ||\n (forceVisible === false && visibleContentPanel === false) ||\n !idProduct\n )\n return;\n\n getProductShortDetail({ id: idProduct }).then((resp) => {\n if (resp?.isSuccess) {\n setProduct(resp.data);\n }\n });\n }, [historyPage, idProduct, visibleContentPanel]);\n\n useEffect(() => {\n if (historyPage && !isEmpty(productShortDetailHistory)) {\n setProduct(productShortDetailHistory);\n }\n }, [JSON.stringify(productShortDetailHistory)]);\n\n useEffect(() => {\n if (product && getProductDetail) {\n getProductDetail(product);\n }\n }, [product, getProductDetail]);\n\n return (\n <>\n {product ? (\n \n \n \n \n \n ) : (\n \n )}\n \n );\n};\n\nexport const ProductContent = ({ children }) => {\n return {children};\n};\n\nexport const ProductActions = ({ id }) => {\n return (\n \n \n \n forwardTo(`/product/${id}`)}\n />\n \n \n {/* \n \n console.log('Download API does not has yet')}\n />\n \n */}\n \n );\n};\n\nexport const ProductLogoThumbnail = ({ id, logo }) => {\n const logoRef = useRef();\n\n useDoubleClick({\n onDoubleClick: () => {\n forwardTo(`/product/${id}`);\n },\n ref: logoRef,\n latency: 250,\n });\n\n return (\n \n \n \n );\n};\n\nexport const ProductInformation = ({ product, historyPage = false }) => {\n const {\n productName,\n productDescription,\n rivirId,\n brandName = 'N/A',\n brickCode = 'N/A',\n brickCodeName = 'N/A',\n productType,\n gtin,\n imperialHeight,\n height: metricHeight,\n imperialWidth,\n width: metricWidth,\n imperialDepth,\n depth: metricDepth,\n imperialWeight,\n weight: metricWeight,\n imperialDimensionUOM,\n dimensionUOM: metricDimensionUOM,\n imperialWeightUOM,\n weightUOM: metricWeightUOM,\n isFavorited,\n } = product;\n\n const intl = useIntl();\n\n // H: Height, W: Width, D: Depth\n const listNameDimension = ['H', 'W', 'D'];\n\n const listImperialValue = [imperialHeight, imperialWidth, imperialDepth];\n const listMetricValue = [metricHeight, metricWidth, metricDepth];\n const { productEnums } = useGetProductEnums();\n\n return (\n \n \n \n \n {productName}\n \n \n\n \n\n \n \n {intl.formatMessage(Messages.description)}\n \n \n \n\n \n \n {intl.formatMessage(Messages.rivirID)}\n \n \n\n \n {intl.formatMessage(Messages.brandName)}\n \n \n\n \n {intl.formatMessage(Messages.barcode)}\n \n \n\n \n {intl.formatMessage(Messages.bricCode)}\n \n \n {/* TODOS: Applied after*/}\n \n\n \n {intl.formatMessage(Messages.dimensions)}\n \n \n \n\n \n \n \n \n );\n};\n\nexport default ProductContentPanel;\n","import { AgGridIcons, AgGridThumbnail } from 'common/components';\nimport { Link } from 'react-router-dom';\nimport { Images } from 'config/assets';\n\nimport { PrimarySizeUOM } from '../';\n\nconst renderIcons = (params) => {\n const data = params?.data;\n\n return (\n \n );\n};\n\nconst renderThumbnail = (params) => {\n const thumbnail300 = params?.data?.thumbnail || Images.RIVIR_LOGO_DEFAULT;\n const thumbnail500 = params?.data?.thumb500 || Images.RIVIR_LOGO_DEFAULT;\n const thumbnail1000 = params?.data?.thumb1000 || Images.RIVIR_LOGO_DEFAULT;\n\n return (\n \n \n \n );\n};\n\nconst renderPrimarySizeUOM = (params) => {\n return ;\n};\n\nconst customCellComponents = {\n renderThumbnail,\n renderIcons,\n renderPrimarySizeUOM,\n};\n\nexport default customCellComponents;\n","/* eslint-disable jsx-a11y/alt-text */\nimport React from 'react';\n\nimport classnames from 'classnames';\n\nimport { Row } from 'antd';\nimport { Images } from 'config/assets';\n\nimport { useImageLoaded } from 'hooks';\n\nconst ProductTileHeader = (props) => {\n const { productName, thumbnail } = props;\n\n const [ref, loaded, onLoad] = useImageLoaded();\n\n console.log('loaded', { loaded });\n\n return (\n \n
\n\n
\n \n \n
\n \n
\n );\n};\n\nexport default ProductTileHeader;\n","import React, { useMemo } from 'react';\nimport { Typography, Space, Row, Col, Tooltip } from 'antd';\nimport classnames from 'classnames';\n\nimport { StarFilled, SafetyOutlined } from '@ant-design/icons';\nimport IconList from 'common/components/icon-list/IconList';\nimport { packageLevelIcons } from 'common/components/icon-list/assets';\nimport ProductSubscription from 'common/components/thumb/product/ProductSubscription';\nimport EntityStatusTag from 'common/components/tag/entity-status-tag/EntityStatusTag';\nimport PrivateLabelIcon from 'common/components/thumb/product/PrivateLabelcon';\n\nimport * as getLink from 'utils/common/linkBuilder';\n\nconst ProductTileBody = (props) => {\n const {\n productName,\n productDescription,\n brandName,\n isFavorited,\n subscription,\n packageLevel,\n categories,\n weight,\n weightUOM,\n imperialWeight,\n imperialWeightUOM,\n primarySize,\n primarySizeUOM,\n subscriptionShield,\n gdsnShield,\n id,\n status,\n isPrivateLabel,\n } = props;\n const { Paragraph, Title } = Typography;\n\n const categoryIcon = useMemo(() => {\n const defaultCategory = categories || [];\n let nextCategoryList = [...defaultCategory];\n\n if (packageLevel) {\n const foundPackageIcon = packageLevelIcons.find(\n (packItem) => packItem?.name === packageLevel.toLowerCase()\n );\n\n if (foundPackageIcon) {\n nextCategoryList = [foundPackageIcon, ...nextCategoryList];\n }\n }\n\n if (true) {\n nextCategoryList = [\n // {\n // ...productSubscriptionIcon,\n // style: {\n // fontSize: 19,\n // color: subscriptionShield,\n // top: 3,\n // position: 'relative',\n // },\n // },\n ...nextCategoryList,\n ];\n }\n\n return nextCategoryList;\n }, [subscription, packageLevel, categories]);\n\n const aLink = getLink.productLink(id, productName);\n return (\n
\n \n \n \n {aLink}\n \n \n {productDescription}\n \n\n \n {brandName}\n \n {!!weight && (\n \n {weight} {weightUOM}\n \n )}\n {!!imperialWeight && (\n \n {imperialWeight} {imperialWeightUOM}\n \n )}\n {!!primarySize && (\n \n {primarySize} {primarySizeUOM}\n \n )}\n \n \n
\n \n \n \n \n \n \n \n {isPrivateLabel && }\n {gdsnShield && (\n \n \n \n )}\n {isFavorited && }\n {subscription && }\n \n \n
\n
\n );\n};\n\nconst styles = {\n favoriteIcon: {\n fontSize: '18px',\n color: '#fec810',\n },\n};\n\nexport default ProductTileBody;\n","import React from 'react';\nimport { Typography, Row, Col } from 'antd';\n\nimport classnames from 'classnames';\n\nconst ProductTileFooter = (props) => {\n const { upc12, rivirId, gtin } = props;\n const { Text } = Typography;\n\n return (\n
\n {upc12 || gtin ? (\n <>\n \n \n \n GTIN:\n \n \n {gtin || 'N/A'}\n \n \n \n \n UPC12:\n \n \n {upc12 || 'N/A'}\n \n \n \n \n ) : (\n \n \n \n RIVIR ID:\n \n \n {rivirId || 'N/A'}\n \n \n \n )}\n
\n );\n};\n\nexport default ProductTileFooter;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n// import { forwardTo } from 'utils/common/route';\nimport { useHistory } from 'react-router';\nimport ProductTileHeader from './ProductTileHeader';\nimport ProductTileBody from './ProductTileBody';\nimport ProductTileFooter from './ProductTileFooter';\nimport useDoubleClick from 'hooks/useDoubleClick';\n\nimport './ProductTile.less';\n\n/**\n * A component displays product information under card layout\n * @param {object} props\n */\nconst ProductTile = (props) => {\n const { dataDetail } = props;\n const { onClickItemGrid, onDoubleClick } = props.clickEvents;\n const history = useHistory();\n\n const divRef = React.useRef();\n\n useDoubleClick({\n onSingleClick: (e) => {\n if (onClickItemGrid) onClickItemGrid(dataDetail, e);\n },\n onDoubleClick: (e) => {\n if (onDoubleClick) {\n history.push(`/product/${dataDetail?.id}`);\n // forwardTo(`${pathname}/${dataDetail?.id}`);\n }\n },\n ref: divRef,\n latency: 250,\n });\n\n return (\n
\n {/*Placeholder for click events*/}\n \n \n \n \n
\n );\n};\n\nProductTile.propTypes = {\n /**\n * product data detail\n */\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductTile;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Typography, Space, Checkbox, Card, Avatar, Row } from 'antd';\nimport { Images } from 'config/assets';\nimport './ProductListItem.less';\n\nconst ListItem = (props) => {\n const { dataDetail, selected, onClickItemGrid } = props;\n\n return (\n \n \n {\n if (onClickItemGrid) onClickItemGrid(dataDetail, e);\n }}\n >\n \n \n \n {dataDetail && dataDetail.upc12} - Widget #1\n \n \n \n \n );\n};\n\nListItem.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ListItem;\n","import React, { Fragment } from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Typography } from 'antd';\n\nconst { Text } = Typography;\n\nconst ProductCategory = (props) => {\n const { dataDetail } = props;\n\n return (\n \n \n \n Category: \n \n {dataDetail && dataDetail.categoryName}\n \n Classification: \n \n {dataDetail && dataDetail.classificationName}\n \n \n \n Sub-Category: \n \n {dataDetail && dataDetail.subCategoryName}\n \n Sub-classi: \n \n {dataDetail && dataDetail.subClassificationName}\n \n \n );\n};\n\nProductCategory.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductCategory;\n","import React, { Fragment } from 'react';\nimport PropTypes from 'prop-types';\nimport { Typography } from 'antd';\n\nconst { Paragraph } = Typography;\n\nconst ProductData = (props) => {\n const { dataDetail } = props;\n\n return (\n \n \n {dataDetail && dataDetail.productName}\n \n \n {dataDetail && dataDetail.brandName}\n \n \n {dataDetail &&\n dataDetail.packageLevelInformation &&\n dataDetail.packageLevelInformation.length > 0 &&\n dataDetail.packageLevelInformation[0].gtin}\n \n \n {dataDetail && dataDetail.memberName}\n \n \n {dataDetail && dataDetail.primarySize} \n {dataDetail && dataDetail.primarySizeUom}\n \n \n );\n};\n\nProductData.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductData;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Typography } from 'antd';\n\nconst { Text } = Typography;\n\nconst ProductDescription = (props) => {\n const { dataDetail } = props;\n\n return (\n \n \n Extended Description:\n \n \n {dataDetail && dataDetail.productDescription}\n \n \n );\n};\n\nProductDescription.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductDescription;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Space, Avatar } from 'antd';\nimport { Images } from 'config/assets';\nconst ProductIdentification = (props) => {\n const { dataDetail } = props;\n\n return (\n \n \n \n \n \n \n );\n};\n\nProductIdentification.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductIdentification;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Avatar } from 'antd';\nimport { Images } from 'config/assets';\n\nconst ProductLogo = (props) => {\n const { dataDetail } = props;\n\n return (\n \n );\n};\n\nProductLogo.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductLogo;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Typography } from 'antd';\n\nconst { Paragraph } = Typography;\n\nconst ProductRightData = (props) => {\n const { dataDetail } = props;\n\n return (\n \n \n Last Modified:\n \n {\n //TODO: DATETIME\n dataDetail && dataDetail.lastModifiedDate\n }\n \n \n \n );\n};\n\nProductRightData.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductRightData;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Divider } from 'antd';\nimport * as ProductHeader from './header/index';\nimport './ProductInfo.less';\n\nconst ProductInfo = (props) => {\n const { dataDetail } = props;\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n );\n};\n\nProductInfo.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductInfo;\n","import React from 'react';\nimport { Input, Select, Row, Col, Typography } from 'antd';\nimport { CodeSandboxOutlined } from '@ant-design/icons';\n\nimport { WrapperSelect } from 'common/components';\n\nconst { Paragraph } = Typography;\nconst { Option } = Select;\nconst options = [1, 2, 3, 4, 5];\n\nconst ProductPackageLevelInfo = (props) => {\n const {\n gtin,\n upc12,\n height,\n width,\n depth,\n weight,\n cube,\n pack,\n packageLevel,\n } = props.packageLevelInformation;\n return (\n \n \n \n \n \n \n \n {options &&\n options.map((item, index) => {\n return (\n \n );\n })}\n \n \n {gtin} \n {upc12} \n {height} \n {width} \n {depth} \n {weight} \n {cube} \n {pack} \n \n \n );\n};\n\nexport default ProductPackageLevelInfo;\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Typography } from 'antd';\nimport { LeftOutlined, RightOutlined } from '@ant-design/icons';\nimport { FormattedMessage } from 'react-intl';\nimport Messages from 'i18n/messages/brandedProduct.js';\nimport ProductPackageLevelInfo from './info/ProductPackageLevelInfo';\nimport 'slick-carousel/slick/slick.css';\nimport 'slick-carousel/slick/slick-theme.css';\nimport './ProductPackageLevel.less';\n\nconst { Paragraph } = Typography;\n\nconst compare = (a, b) => {\n if (a.packageLevel < b.packageLevel) {\n return -1;\n }\n if (a.packageLevel > b.packageLevel) {\n return 1;\n }\n return 0;\n};\n\nconst ProductPackageLevel = (props) => {\n const [currentSlide, setCurrentSlide] = useState(0);\n const [transformPixel, setTransformPixel] = useState(0);\n const { dataDetail } = props;\n const slides =\n dataDetail &&\n dataDetail.packageLevelInformation &&\n dataDetail.packageLevelInformation.length > 0\n ? [...dataDetail.packageLevelInformation].sort(compare)\n : [];\n\n const selectSilde = (index) => {\n if (currentSlide === index) return;\n setCurrentSlide(index);\n if (slides.length < 2) return;\n setTransformPixel(\n transformPixel - ((index - currentSlide) * 100) / slides.length\n );\n };\n\n const onClickLeftSlider = () => {\n if (currentSlide === 0) return;\n const current = currentSlide - 1;\n setTransformPixel(transformPixel + 100 / slides.length);\n setCurrentSlide(current);\n };\n\n const onClickRightSlider = () => {\n if (currentSlide >= slides.length - 3) return;\n const current = currentSlide + 1;\n setTransformPixel(transformPixel - 100 / slides.length);\n setCurrentSlide(current);\n };\n\n return (\n \n \n \n  \n \n \n :\n \n \n :\n \n \n :\n \n \n :\n \n \n :\n \n \n :\n \n \n :\n \n \n :\n \n \n :\n \n \n \n \n onClickLeftSlider()}\n style={{\n fontSize: '20px',\n color: 'black',\n position: 'absolute',\n zIndex: 10,\n cursor: 'pointer',\n left: '0',\n }}\n />\n = slides.length - 3 ? 'arrow-disabled' : ''\n }\n disabled={true}\n onClick={() => onClickRightSlider()}\n style={{\n fontSize: '20px',\n color: 'black',\n position: 'absolute',\n right: '0',\n zIndex: 10,\n cursor: 'pointer',\n }}\n />\n \n \n {slides &&\n slides.length &&\n slides.map((item, index) => {\n let cssSlider = 'slick-slide';\n if (index >= currentSlide && index <= currentSlide + 2) {\n cssSlider += ' slick-active';\n }\n if (index === currentSlide) {\n cssSlider += ' slick-current';\n }\n return (\n selectSilde(index)}\n style={{\n outline: 'none',\n width: `${100 / slides.length}%`,\n }}\n className={cssSlider}\n >\n \n \n );\n })}\n \n \n \n \n \n );\n};\n\nProductPackageLevel.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductPackageLevel;\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nimport {\n QuestionCircleOutlined,\n CheckCircleOutlined,\n PieChartOutlined,\n} from \"@ant-design/icons\";\nimport { Space, Row, Col, Avatar, Typography } from \"antd\";\n\nimport { get } from \"lodash\";\n\nimport { FormattedMessage } from \"react-intl\";\nimport Messages from \"i18n/messages/brandedProduct\";\n\nimport \"./ProductIngredient.less\";\n/**\n * TODO: remove this static image\n */\nimport ingredientIcon from \"assets/ingredient.png\";\nconst { Text, Paragraph } = Typography;\n\n/**\n * This function just render static UI\n * TODO: apply detail data later\n */\nconst renderStaticIconList = () => {\n return (\n \n \n \n \n \n );\n};\n\nconst renderIngredientItem = (item, key) => {\n const { label, render, extra } = item;\n return (\n \n \n {label ? (\n \n :\n \n ) : null}\n \n \n {render && render}\n \n {extra && (\n \n {extra}\n \n )}\n \n );\n};\n\nconst ProductIngredient = (props) => {\n const { dataDetail } = props;\n const ingredientContent = get(dataDetail, \"ingredient\", false);\n\n const ingredientIconComp = (\n \n );\n\n const ingredientExtraContent = ingredientContent ? (\n {ingredientContent}\n ) : null;\n\n const renderData = [\n // Ingredient\n {\n label: Messages.ingredientLabel,\n render: ingredientIconComp,\n extra: ingredientExtraContent,\n },\n // allergens\n {\n label: Messages.allergensLabel,\n render: renderStaticIconList(),\n },\n // Certification\n {\n label: Messages.certificationsLabel,\n render: renderStaticIconList(),\n },\n ];\n\n return (\n \n {renderData &&\n renderData.length > 0 &&\n renderData.map((data, index) => renderIngredientItem(data, index))}\n \n );\n};\n\nProductIngredient.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductIngredient;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Slider from 'react-slick';\nimport 'slick-carousel/slick/slick.css';\nimport 'slick-carousel/slick/slick-theme.css';\nimport './SlickSlider.less';\nimport { LeftOutlined, RightOutlined } from '@ant-design/icons';\n\nfunction SampleNextArrow(props) {\n const { className, onClick } = props;\n return (\n
\n \n
\n );\n}\n\nfunction SamplePrevArrow(props) {\n const { className, onClick } = props;\n return (\n
\n \n
\n );\n}\n\nexport default function SlickSlider(props) {\n const { isSmallSlides } = props;\n const settings = {\n className: 'center',\n centerMode: true,\n infinite: true,\n centerPadding: '0',\n slidesToShow: isSmallSlides ? 1 : 3,\n speed: 1000,\n dots: true,\n nextArrow: ,\n prevArrow: ,\n dotsClass: 'slick-dots-new',\n };\n const { children } = props;\n return (\n
\n {children}\n
\n );\n}\nSlickSlider.propTypes = {\n children: PropTypes.array.isRequired,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport SlickSlider from 'common/components/slickslider/SlickSlider';\nimport Image from 'common/components/image/Image';\nexport const ProductAssets = (props) => {\n const { dataDetail } = props;\n return (\n \n {dataDetail &&\n dataDetail.assetImage &&\n dataDetail.assetImage.length > 0 &&\n dataDetail.assetImage.map((item, index) => {\n return (\n
\n {item.alt\n
\n );\n })}\n
\n );\n};\nProductAssets.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\nexport default ProductAssets;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Drawer } from 'antd';\n\nconst ProductDrawer = (props) => {\n const { visible, isDisplayMask, contentDrawer, onClose } = props;\n const widthDrawer = props.widthDrawer ? props.widthDrawer : 500;\n const parentPadding = props.parentPadding ? props : 24;\n\n return (\n \n \n \n \n \n {contentDrawer}\n \n \n \n \n );\n};\nProductDrawer.propTypes = {\n // visible: show or hide drawer\n visible: PropTypes.bool.isRequired,\n // isDisplayMask: display mask of drawer or not\n isDisplayMask: PropTypes.bool.isRequired,\n // contentDrawer: content of drawer need to show\n contentDrawer: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node,\n ]).isRequired,\n};\n\nexport default ProductDrawer;\n","import React, { Fragment } from 'react';\nimport PropTypes from 'prop-types';\nimport * as ProductComponent from '../../components/index';\n\nconst ProductDetail = (props) => {\n const { dataDetail } = props;\n return (\n \n \n \n \n \n \n );\n};\n\nProductDetail.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ProductDetail;\n","import React, { useState, useEffect, useMemo, useCallback } from 'react';\nimport { useSelector } from 'react-redux';\nimport { Row, Col, Select, Tree, Button, Space } from 'antd';\nimport { Form, StyledModal, WrapperSelect } from 'common/components';\n\nimport * as globalSelectors from '@redux/global/selectors';\nimport debounce from 'lodash.debounce';\n\nfunction ProductBrickCode({\n visible,\n handleCancel,\n handleBrickCode,\n initialBrickCode,\n}) {\n const productBrickCodeModules = useSelector(\n globalSelectors.selectBrickCodeModules()\n );\n\n // Segments -> Family -> Class -> Brick\n const [segments, setSegments] = useState(null);\n const [family, setFamily] = useState([]);\n const [classBrick, setClassBrick] = useState([]);\n const [brick, setBrick] = useState([]);\n const [isExpand, setIsExpand] = useState(false);\n const [expandedKeys, setExpandedKeys] = useState([]);\n const [hightLightKey, setHightLightKey] = useState([]);\n\n const handleOk = () => {\n handleBrickCode(brick);\n handleReset();\n };\n\n const handleCancelModal = () => {\n handleCancel();\n handleReset();\n };\n\n const modalProps = {\n title: 'Product Brick Code',\n visible: visible,\n closable: true,\n maskClosable: false,\n onCancel: handleCancelModal,\n wrapClassName: 'brick-modal',\n width: '75%',\n onOk: handleOk,\n bodyStyle: { maxHeight: '55vh', overflow: 'hidden' },\n };\n\n useEffect(() => {\n if (initialBrickCode && visible) {\n handleSelectTree(initialBrickCode);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [visible]);\n\n const handleSelectTree = useCallback((expandedKeys) => {\n const treeModal = { children: editTreeView };\n\n const pathValues = getPath(treeModal, expandedKeys);\n\n if (pathValues) {\n const [, segmentKey, familyKey, classesKey, brickKey] = pathValues;\n\n const segmentModule = productBrickCodeModules?.find(\n (segment) => segment?.SegmentCode === segmentKey?.key\n );\n setSegments(segmentModule);\n const familyModule = segmentModule?.Families?.find(\n (family) => family?.FamilyCode === familyKey?.key\n );\n setFamily(familyModule);\n const classModule = familyModule?.Classes?.find(\n (family) => family?.ClassCode === classesKey?.key\n );\n setClassBrick(classModule);\n const brick = classModule?.Bricks?.find(\n (brick) => brick?.BrickCode === brickKey?.key\n );\n setBrick(brick);\n handleExpand([\n segmentKey?.key,\n familyKey?.key,\n classesKey?.key,\n brickKey?.key,\n ]);\n setHightLightKey([brickKey?.key]);\n }\n }, []);\n\n const editTreeView = useMemo(() => {\n const mappingTreeView = productBrickCodeModules?.map((segment) => {\n return {\n title: `Segment: ${segment?.SegmentCode} - ${segment?.SegmentDescription}`,\n key: segment?.SegmentCode,\n children: segment?.Families?.map((family) => ({\n title: `Family: ${family?.FamilyCode} - ${family?.FamilyDescription}`,\n key: family?.FamilyCode,\n children: family?.Classes?.map((classes) => ({\n title: `Class: ${classes?.ClassCode} - ${classes?.ClassDescription}`,\n key: classes?.ClassCode,\n children: classes?.Bricks?.map((brick) => ({\n title: `Brick: ${brick?.BrickCode} - ${brick?.BrickDescription}`,\n key: brick?.BrickCode,\n })),\n })),\n })),\n };\n });\n return mappingTreeView;\n }, []);\n\n function getPath(model, key) {\n let path,\n item = { key: model.key };\n\n if (!model || typeof model !== 'object') return;\n\n if (model.key === key) return [item];\n (model.children || []).some((child) => (path = getPath(child, key)));\n\n return path && [item, ...path];\n }\n\n const { Option } = Select;\n\n const handleReset = () => {\n setSegments(null);\n setFamily([]);\n setClassBrick([]);\n setBrick([]);\n handleExpand([]);\n setExpandedKeys([]);\n setHightLightKey([]);\n };\n\n const handleSegment = (code) => {\n const segmentModule = productBrickCodeModules?.find(\n (segments) => segments?.SegmentCode === code\n );\n setSegments(segmentModule);\n setFamily([]);\n setClassBrick([]);\n setBrick([]);\n handleExpand([code]);\n };\n\n const handleFamily = (code) => {\n const familyModule = segments?.Families?.find(\n (family) => family?.FamilyCode === code\n );\n setFamily(familyModule);\n handleExpand([...expandedKeys, code]);\n setClassBrick([]);\n setBrick([]);\n setHightLightKey([]);\n };\n\n const handleClass = (code) => {\n const classModule = family?.Classes?.find(\n (family) => family?.ClassCode === code\n );\n setClassBrick(classModule);\n handleExpand([...expandedKeys, code]);\n setBrick([]);\n setHightLightKey([]);\n };\n\n const handleBrick = (code) => {\n const brick = classBrick?.Bricks?.find(\n (brick) => brick?.BrickCode === code\n );\n setBrick(brick);\n setHightLightKey([code]);\n };\n\n const handleExpand = (expandedKeys, info) => {\n setExpandedKeys(expandedKeys);\n setIsExpand(false);\n };\n\n const expandMethod = (arr) => {\n const expandedKeys = [];\n arr.forEach((data) => {\n expandedKeys.push(data.key);\n if (data.children) {\n expandMethod(data.children);\n }\n });\n return expandedKeys;\n };\n\n const handleExpandAll = () => {\n const newKeys = expandMethod(editTreeView);\n setExpandedKeys(newKeys);\n };\n\n const handleCollapseAll = () => {\n setExpandedKeys([]);\n };\n\n const handleSelect = (expandedKeys) => {\n handleSelectTree(expandedKeys?.[0]);\n };\n const handleDebounceSelect = debounce(handleSelect, 300);\n\n const handleFilter = (input, option) => {\n return (\n option?.props?.children\n ?.split('-')[1]\n ?.toLowerCase()\n ?.indexOf(input.toLowerCase()) >= 0 ||\n option?.props?.value.toLowerCase()?.indexOf(input.toLowerCase()) >= 0\n );\n };\n\n return (\n \n \n \n \n \n handleFilter(input, option)}\n >\n {productBrickCodeModules?.map((segments) => (\n \n {`${segments?.SegmentCode} - ${segments?.SegmentDescription}`}\n \n ))}\n {' '}\n \n \n handleFilter(input, option)}\n >\n {segments?.Families?.map((family) => (\n \n ))}\n {' '}\n \n \n handleFilter(input, option)}\n >\n {family?.Classes?.map((classes) => (\n \n ))}\n \n \n \n handleFilter(input, option)}\n >\n {classBrick?.Bricks?.map((brick) => (\n \n ))}\n {' '}\n \n \n \n \n {/* {segments && ( */}\n <>\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {/* )} */}\n \n \n \n );\n}\n\nexport default React.memo(ProductBrickCode);\n","import React from 'react';\n\nimport { useGetProductEnums } from 'hooks';\nimport { findDimensionEnumDisplay } from 'pages/product-full-view/mappers/mapToEnums';\n\nimport * as _ from 'lodash';\n\nconst PrimarySizeUOM = (props) => {\n const { params } = props;\n\n const { productEnums } = useGetProductEnums();\n if (_.isEmpty(productEnums)) {\n return
;\n }\n\n const enumDisplay =\n findDimensionEnumDisplay(params?.data?.primarySizeUOM, productEnums) ||\n params?.data?.primarySizeUOM ||\n '';\n return
{enumDisplay}
;\n};\n\nexport default PrimarySizeUOM;\n","import { useEffect } from 'react';\nimport { useAsync } from 'hooks';\n\nimport { getProductFullView } from 'services/product';\n\nexport const useGetPublishingProduct = ({ productId, isEnabled }) => {\n const { data, run } = useAsync();\n\n useEffect(() => {\n if (isEnabled) {\n run(\n getProductFullView({\n productItemId: productId,\n })\n );\n }\n }, [productId, run, isEnabled]);\n\n return {\n publishingProduct: data ?? {},\n };\n};\n","import React, { useState } from 'react';\n\nimport { Row, Drawer, Col, Typography } from 'antd';\n\nimport {\n ProductHierarchyDetail,\n ProductHierarchyEndpointInfo,\n} from 'pages/product-full-view/components';\n\nimport * as productService from 'services/product';\n\nconst { Text } = Typography;\n\nconst ProductItemSearchDrawer = (props) => {\n const {\n toggleIsDrawerOpen,\n isDrawerVisible,\n productDetail,\n setEditProductId,\n hierarchyItems,\n } = props;\n\n const [hierarchyLoading, setHierarchyLoading] = useState(false);\n const [hierarchyData, setHierarchyData] = useState([]);\n\n const getHierarchyData = () => {\n setHierarchyLoading(true);\n\n const params = {\n productId: productDetail?.productId,\n };\n\n productService\n .getProductHierarchy(params)\n .then((response) => {\n const { isSuccess, data } = response;\n\n if (isSuccess && data?.productHierarchies) {\n setHierarchyData(data.productHierarchies);\n }\n })\n .finally(() => {\n setHierarchyLoading(false);\n });\n };\n\n return (\n \n Select product item from hierarchy view\n \n }\n placement='right'\n onClose={toggleIsDrawerOpen}\n visible={isDrawerVisible}\n width={630}\n className='fix-publication-invalid-modal__hierarchy-drawer'\n zIndex={1200}\n >\n
\n \n \n \n \n \n \n \n \n \n \n
\n \n );\n};\n\nexport default ProductItemSearchDrawer;\n","import React, { useEffect, useMemo } from 'react';\n\nimport { ProductDetailView } from 'pages/product-full-view/components/product-new-detail-view';\n\nimport {\n useProductDetail,\n useProductDetailDispatch,\n productDetailActionTypes,\n} from 'pages/product-full-view/components/product-new-detail-view/ProductDetailContext';\n\nimport {\n filterModuleProductSchema,\n uppercaseFirstLetter,\n} from 'pages/product-full-view/shared/utils';\n\nconst PublicationErrorProductDetail = ({\n productDetail,\n productSchema,\n currentError = {},\n onResolveErrorPublicationSuccess,\n}) => {\n const { fieldName: fieldFullPath } = currentError;\n const moduleNameError = fieldFullPath.split('.')[0];\n\n const dispatch = useProductDetailDispatch();\n\n const { formInstance } = useProductDetail();\n\n const { baseProductSchema, advancedProductSchema } = useMemo(\n () => filterModuleProductSchema(productSchema),\n [productSchema]\n );\n\n const baseProductModuleNames = baseProductSchema.map((schemaProd) =>\n schemaProd.moduleName.toLowerCase()\n );\n\n const isBaseProductSchema = Boolean(\n baseProductModuleNames.includes(moduleNameError.toLowerCase())\n );\n\n const advancedProductModuleNames = advancedProductSchema.map((schemaProd) =>\n schemaProd.moduleName.toLowerCase()\n );\n\n const isAdvancedProductSchema = Boolean(\n advancedProductModuleNames.includes(moduleNameError.toLowerCase())\n );\n\n useEffect(() => {\n if (isBaseProductSchema) {\n dispatch({\n type: productDetailActionTypes.ACTIVE_MODULES,\n payload: {\n value: [uppercaseFirstLetter(moduleNameError)], // header -> Header,... Elastic changed format data\n moduleView: 'base',\n },\n });\n dispatch({\n type: productDetailActionTypes.SET_ERROR_FIELD_FULL_PATH,\n payload: {\n fieldFullPath,\n },\n });\n }\n }, [dispatch, fieldFullPath, isBaseProductSchema, moduleNameError]);\n\n useEffect(() => {\n if (isAdvancedProductSchema) {\n dispatch({\n type: productDetailActionTypes.ACTIVE_MODULES,\n payload: {\n value: [uppercaseFirstLetter(moduleNameError)], // header -> Header,... Elastic changed format data\n moduleView: 'advanced',\n },\n });\n dispatch({\n type: productDetailActionTypes.SET_ERROR_FIELD_FULL_PATH,\n payload: {\n fieldFullPath,\n },\n });\n\n dispatch({\n type: productDetailActionTypes.SEARCH_PROPERTIES,\n payload: {\n searchText: fieldFullPath,\n moduleSchema: advancedProductSchema,\n modeView: 'view',\n formInstance,\n },\n });\n }\n }, [\n advancedProductSchema,\n dispatch,\n fieldFullPath,\n formInstance,\n isAdvancedProductSchema,\n moduleNameError,\n ]);\n\n return (\n
\n \n
\n );\n};\n\nexport default PublicationErrorProductDetail;\n","import React from 'react';\n\nimport { Typography } from 'antd';\nimport { SearchOutlined } from '@ant-design/icons';\nimport { FormAddButton } from 'common/components';\n\nconst { Text } = Typography;\n\nconst WarningMessage = ({ toggleProductSearchDrawer }) => (\n
\n \n Product Id was not given please search for product item and fix its error\n to pass your publication,\n \n }\n onClick={toggleProductSearchDrawer && toggleProductSearchDrawer}\n />\n
\n);\n\nexport const mapToPublishErrorAlert = (error, toggleProductSearchDrawer) => {\n return error && error?.errorProductId\n ? {\n message: 'Please fix error in the product item to pass your publication',\n status: 'error',\n }\n : {\n message: (\n \n ),\n status: 'warning',\n };\n};\n","import React from 'react';\n\nimport { Row, Col, Alert } from 'antd';\nimport { StyledModal } from 'common/components';\n\nimport { ProductDetailProvider } from 'pages/product-full-view/components/product-new-detail-view';\n\nimport PublicationErrorProductDetail from './PublicationErrorProductDetail';\n\nimport { mapToPublishErrorAlert } from 'pages/branded-products/mapper/mapToPublishErrorAlert';\n\nimport { useGetProductSchema } from 'hooks';\n\nimport { sleep } from 'utils/delay';\n\nconst PublicationErrorDetailModal = (props) => {\n const {\n isErrModalVisible,\n publishingProduct,\n toggleCheckErrorModal,\n currentError,\n toggleIsDrawerOpen,\n getPublishCheckList,\n setReloadOneError,\n setErrModalVisible,\n } = props;\n const { productSchema } = useGetProductSchema();\n\n const onCancel = () => {\n toggleCheckErrorModal && toggleCheckErrorModal();\n };\n\n const alertConfig = mapToPublishErrorAlert(currentError, toggleIsDrawerOpen);\n\n const onResolveErrorPublicationSuccess = async () => {\n if (currentError) {\n getPublishCheckList &&\n typeof getPublishCheckList === 'function' &&\n getPublishCheckList();\n\n setErrModalVisible(false);\n if (setReloadOneError) {\n setReloadOneError(true);\n\n await sleep(1000);\n setReloadOneError(false);\n }\n }\n };\n\n return (\n <>\n {isErrModalVisible && (\n \n \n \n {currentError && (\n \n \n \n )}\n \n \n \n \n \n \n )}\n \n );\n};\n\nexport default PublicationErrorDetailModal;\n","import React, { useMemo, useEffect } from 'react';\n\nimport { Form } from 'common/components';\n\nimport {\n findProductModule,\n findDataProperties,\n formatObjectToCheckValueDatetime,\n RenderNewFormItem,\n RenderFormItem,\n isLeftModule,\n NewFormItemContainer,\n // filterModuleProductSchema,\n // filterModuleBrickCode,\n} from 'pages/branded-products/components';\n\nimport { FormContextProvider } from 'pages/product-full-view/components/product-detail-view/FormContext';\n\nimport { pickBy, identity } from 'lodash';\n\nimport './InstantFixForm.less';\n\nconst layoutForm = {\n labelCol: { span: 11 },\n wrapperCol: { span: 11 },\n};\n//todo - add product brick code if needed\nconst InstantFixInput = (props) => {\n const {\n productSchema,\n productEnums,\n errorInfo,\n productId,\n // productBrickCode,\n productItemModules,\n formName,\n } = props;\n\n const editableModuleName = errorInfo?.moduleName;\n\n const [formInstance] = Form.useForm();\n\n // const { leftProductSchema, rightProductSchema } = useMemo(\n // () => filterModuleProductSchema(productSchema),\n // [productSchema]\n // );\n\n // const brickCodeSchema = useMemo(\n // () => filterModuleBrickCode(rightProductSchema, modulesBrickCode),\n // [modulesBrickCode, rightProductSchema]\n // );\n\n // const mixedProductSchema = useMemo(\n // () => [...(leftProductSchema || []), ...(brickCodeSchema || [])],\n // [leftProductSchema, brickCodeSchema]\n // );\n\n const { nonGroupModule } = useMemo(() => {\n return findProductModule(editableModuleName, productSchema);\n }, [editableModuleName, productSchema]);\n\n const isPrivateProperties = isLeftModule(nonGroupModule?.moduleName);\n\n const foundInputFromModule = (\n nonGroupModule?.moduleProperties?.length > 0\n ? nonGroupModule?.moduleProperties\n : []\n ).find((property) => property?.propertyName === errorInfo?.fieldName);\n\n const foundInputFromGroupModule = useMemo(() => {\n if (!isPrivateProperties) return null;\n\n let result;\n\n // eslint-disable-next-line no-unused-expressions\n Object.entries(nonGroupModule?.moduleProperties)?.find(\n ([title, modPropers]) =>\n modPropers.find((property) => {\n if (property?.propertyName === errorInfo?.fieldName) {\n result = { title, property: property || {} };\n return true;\n }\n })\n );\n\n return result;\n }, [isPrivateProperties, errorInfo, nonGroupModule]);\n\n const foundDataProperties = useMemo(() => {\n if (!productItemModules) return [];\n\n return findDataProperties(editableModuleName, productItemModules);\n }, [editableModuleName, productItemModules]);\n\n useEffect(() => {\n if (editableModuleName) {\n const newFormatData =\n formatObjectToCheckValueDatetime(foundDataProperties) || {};\n\n let formData = pickBy(newFormatData, identity);\n\n const customFormData = {\n ...formData,\n productId: productId,\n fieldName: errorInfo?.fieldName,\n moduleName: errorInfo?.moduleName,\n };\n\n formInstance.setFieldsValue(customFormData);\n }\n }, [\n editableModuleName,\n formInstance,\n foundDataProperties,\n productId,\n errorInfo,\n ]);\n\n const isModuleFound = nonGroupModule?.moduleProperties?.length > 0;\n\n return (\n \n \n {isModuleFound && (\n <>\n {isPrivateProperties ? (\n <>\n \n \n \n \n ) : (\n \n )}\n \n )}\n\n \n \n \n \n \n );\n};\n\nexport default InstantFixInput;\n","import React, { useState, useEffect } from 'react';\nimport { Form, Input, Select, InputNumber, Row, Col } from 'antd';\nimport { ProductBrickCode } from 'pages/branded-products/components';\nimport { FormEditButton, WrapperSelect } from 'common/components';\nimport { sortByKeyCallback } from 'utils/sortByKey';\n\nconst { Option } = Select;\n\nconst MAX_NUMBER_INPUT_UPC = 9999999999999999999;\n\nconst handleNumberInput = (event) => {\n if (!/[0-9]/.test(event.key)) {\n event.preventDefault();\n }\n};\n\nexport const PACKAGE_LEVELS = [\n 'Unit',\n 'Inner Pack',\n 'Case',\n 'Master Case',\n 'Pallet',\n];\n\nexport const textAreaEnums = [{ name: 'productDescription' }];\n\nexport const inputNumberEnums = [\n { name: 'primarySize', min: 0, max: 999999 },\n { name: 'width', min: 0, max: MAX_NUMBER_INPUT_UPC },\n { name: 'height', min: 0, max: MAX_NUMBER_INPUT_UPC },\n { name: 'depth', min: 0, max: MAX_NUMBER_INPUT_UPC },\n { name: 'weight', min: 0, max: MAX_NUMBER_INPUT_UPC },\n];\n\nexport const selectEnums = [\n {\n name: 'productType',\n options: (productTypeEnums) => {\n return productTypeEnums?.[0]?.enumProperties\n ?.sort(sortByKeyCallback('enumDisplayName'))\n .map((type, index) => (\n \n ));\n },\n },\n {\n name: 'packageLevel',\n options: PACKAGE_LEVELS,\n },\n {\n name: 'visibility',\n options: ['Only If Shared', 'Public', 'Private'],\n },\n {\n name: 'status',\n options: ['Active', 'Pending'],\n },\n {\n name: 'primarySizeUOM',\n options: ({ productBasicUOM }) => {\n return (\n <>\n {productBasicUOM?.[0]?.enumProperties\n ?.filter((type) => type.enumGroup === 'Mass')\n .sort(sortByKeyCallback('enumDisplayName'))\n .map((item, index) => (\n \n ))}\n \n );\n },\n },\n {\n name: 'weightUOM',\n options: ({ productBasicUOM }) => {\n return (\n <>\n {productBasicUOM?.[0]?.enumProperties\n ?.filter((type) => type.enumGroup === 'Mass')\n .sort(sortByKeyCallback('enumDisplayName'))\n .map((item, index) => (\n \n ))}\n \n );\n },\n },\n {\n name: 'dimensionUOM',\n options: ({ productBasicUOM }) => {\n return (\n <>\n {productBasicUOM?.[0]?.enumProperties\n ?.filter((type) => type.enumGroup === 'Dimensions')\n .sort(sortByKeyCallback('enumDisplayName'))\n .map((item, index) => (\n \n ))}\n \n );\n },\n },\n];\n\nexport const inputTextEnums = [\n { name: 'ixOneId', maxLength: 30 },\n { name: 'productName', maxLength: 70 },\n {\n name: 'gtin',\n maxLength: MAX_NUMBER_INPUT_UPC,\n onKeyPress: handleNumberInput,\n },\n {\n name: 'upc12',\n maxLength: MAX_NUMBER_INPUT_UPC,\n onKeyPress: handleNumberInput,\n },\n {\n name: 'upc8',\n maxLength: MAX_NUMBER_INPUT_UPC,\n onKeyPress: handleNumberInput,\n },\n {\n name: 'upc10',\n maxLength: MAX_NUMBER_INPUT_UPC,\n onKeyPress: handleNumberInput,\n },\n {\n name: 'upc11',\n maxLength: MAX_NUMBER_INPUT_UPC,\n onKeyPress: handleNumberInput,\n },\n {\n name: 'upc13',\n maxLength: MAX_NUMBER_INPUT_UPC,\n onKeyPress: handleNumberInput,\n },\n];\n\nexport const brickCodeEnums = [{ name: 'brickCode' }];\n\nconst BrickCodeInput = (props) => {\n const { onChange, brickCode, brickCodeName } = props;\n\n const [brickModalVisible, setBrickModalVisible] = useState(false);\n const [brick, setBrick] = useState();\n\n const handleBrickCode = (brick) => {\n setBrick({\n brickCode: brick?.BrickCode,\n brickCodeName: brick?.BrickDescription,\n });\n setBrickModalVisible(false);\n };\n\n const toggleBrickModal = () => {\n setBrickModalVisible((prev) => !prev);\n };\n\n useEffect(() => {\n setBrick({\n brickCode: brickCode,\n brickCodeName: brickCodeName,\n });\n }, [brickCode, brickCodeName]);\n\n useEffect(() => {\n onChange && onChange(brick);\n }, [brick, onChange]);\n\n return (\n \n \n \n \n\n \n \n \n <>\n setBrickModalVisible(false)}\n handleBrickCode={handleBrickCode}\n initialBrickCode={brick?.brickCode}\n />\n \n \n );\n};\n\nexport const FormBrickCodeInput = (props) => {\n const { brickCode, brickCodeName, ...restProps } = props;\n\n return (\n \n \n \n );\n};\n\nexport const FormTextAreaInput = (props) => {\n return (\n \n \n \n );\n};\n\nexport const FormTextInput = (props) => {\n return (\n \n \n \n );\n};\n\nexport const FormSelectInput = (props) => {\n const { options, optionParams = {}, ...restProps } = props;\n return (\n \n \n {typeof options === 'function'\n ? options && options(optionParams)\n : options\n ?.sort(sortByKeyCallback(null))\n .map((option, index) => \n \n );\n};\n\nexport const FormNumberInput = (props) => {\n return (\n \n \n \n );\n};\n","import React, { useEffect } from 'react';\n\nimport { Form } from 'common/components';\n\nimport {\n FormTextInput,\n FormTextAreaInput,\n FormSelectInput,\n FormNumberInput,\n FormBrickCodeInput,\n textAreaEnums,\n inputNumberEnums,\n selectEnums,\n inputTextEnums,\n brickCodeEnums,\n} from 'common/components/product-add/ProductEditFormItem';\n\nimport { startCase } from 'lodash';\n\nimport './InstantFixFormRivirField.less';\n\nconst layoutForm = {\n labelCol: { span: 11 },\n wrapperCol: { span: 11 },\n};\n\nconst InstantFixFormRivirField = (props) => {\n const { productEnums, errorInfo, productId, formName, productDetail } = props;\n\n const fieldName = errorInfo?.fieldName;\n\n const [formInstance] = Form.useForm();\n\n const productTypeEnums = productEnums?.filter(\n (type) => type.enumName === 'ProductTypeEnum'\n );\n\n const productBasicUOM = productEnums?.filter(\n (type) => type.enumName === 'BasicUomEnum'\n );\n\n useEffect(() => {\n const initFormValue = () => {\n const fieldName = errorInfo?.fieldName;\n const allProductFields = Object.keys(productDetail);\n\n const foundField = allProductFields.find(\n (field) => field.toLowerCase() === (fieldName || '').toLowerCase()\n );\n\n const customFormData = {\n productId: productId,\n fieldName: errorInfo?.fieldName,\n moduleName: '',\n [fieldName]: productDetail?.[foundField],\n };\n formInstance.setFieldsValue(customFormData);\n };\n\n if (productDetail) {\n initFormValue();\n }\n }, [productDetail, errorInfo, formInstance, productId]);\n\n const renderInput = () => {\n const findCallback = (enumItem) => {\n return enumItem?.name.toLowerCase() === (fieldName || '').toLowerCase();\n };\n\n let foundItem;\n\n foundItem = textAreaEnums.find(findCallback);\n if (foundItem) {\n return (\n \n );\n }\n\n foundItem = inputTextEnums.find(findCallback);\n if (foundItem) {\n return (\n \n );\n }\n\n foundItem = selectEnums.find(findCallback);\n if (foundItem) {\n return (\n \n );\n }\n\n foundItem = inputNumberEnums.find(findCallback);\n if (foundItem) {\n return (\n \n );\n }\n\n foundItem = brickCodeEnums.find(findCallback);\n if (foundItem) {\n return (\n \n );\n }\n };\n\n return (\n <>\n \n {renderInput()}\n\n \n \n \n \n \n );\n};\n\nexport default InstantFixFormRivirField;\n","import React, { useMemo } from 'react';\n\nimport { Row, Col, Typography, Tooltip } from 'antd';\nimport {\n CloseCircleOutlined,\n WarningOutlined,\n CaretRightOutlined,\n LoadingOutlined,\n} from '@ant-design/icons';\n\nimport { Form, FormDeleteButton } from 'common/components';\n\nimport InstantFixForm from './InstantFixForm';\nimport InstantFixFormRivirField from './InstantFixFormRivirField';\n\nimport classnames from 'classnames';\nimport { startCase } from 'lodash';\nimport { ROUTE } from 'static/Constants';\n\nconst { Title } = Typography;\n\n/**\n * ? COMPONENT - error item for validation rule\n * @param {*} props\n * @returns\n */\nexport const PublicationErrorItemValidationRule = (props) => {\n const { productItemId } = props;\n\n const [formInstance] = Form.useForm();\n\n const handleOpenProductNewTab = () => {\n if (productItemId) {\n const url = window.location.origin + ROUTE.PRODUCT + `/${productItemId}`;\n productItemId && window.open(url);\n }\n };\n return (\n
\n \n \n
\n \n
\n \n \n \n Failed GS1 validation\n \n \n\n \n \n }\n onClick={handleOpenProductNewTab}\n style={{ marginRight: 5 }}\n />\n \n \n \n );\n};\n\n/**\n * ? COMPONENT - error item for system required and additional required\n * @param {*} props\n * @returns\n */\n\nconst getNestedFieldName = (fieldNames = []) => {\n let result = '';\n\n fieldNames.forEach((name, index) => {\n console.log(startCase(name), index);\n if (index === 0) {\n result = startCase(name);\n } else {\n result = result + ' / ' + startCase(name);\n }\n });\n\n return result;\n};\n\nexport const PublicationCommonErrorItem = (props) => {\n const {\n errorItem,\n isErrorItem,\n isRivirField,\n status,\n setErrorIndex,\n setProductId,\n toggleCheckErrorModal,\n productEnums,\n productSchema,\n errorInfo,\n groupIdx,\n itemIdx,\n productDetailList,\n productModuleList,\n } = props;\n\n const productDetail = useMemo(() => {\n return (\n productDetailList &&\n productDetailList.find(\n (detail) => detail?.productId === errorItem?.productId\n )\n );\n }, [productDetailList, errorItem?.productId]);\n\n const errorTitle = useMemo(() => {\n const productIdText = productDetail?.gtin\n ? `Product GTIN - ${productDetail?.gtin}`\n : productDetail?.upc12\n ? `Product UPC12 - ${productDetail?.upc12}`\n : `Product ID - ${errorItem?.productId}`;\n\n const productIdPart = (\n \n {productIdText}\n \n );\n\n const rivirFieldText = 'RIVIR Field';\n const fieldNameText = startCase(errorItem?.fieldName || '');\n\n if (isRivirField) {\n return {\n renderTitle: (\n <>\n {productIdPart}  /  {rivirFieldText} / {' '}\n {fieldNameText}\n \n ),\n };\n } else {\n const [moduleName, ...fieldName] = errorItem.fieldName.split('.');\n const nestedFieldNameText = getNestedFieldName(fieldName);\n\n return {\n renderTitle: (\n <>\n {productIdPart}  /  {startCase(moduleName)}  / {' '}\n {nestedFieldNameText}\n \n ),\n };\n }\n }, [productDetail, errorItem, isRivirField]);\n\n return (\n \n \n \n \n
\n {isErrorItem ? : }\n
\n \n \n \n \n {errorTitle?.renderTitle}\n \n \n \n \n {status === 'loading' && (\n \n )}\n \n \n\n \n }\n onClick={() => {\n const activeProductId = errorItem?.productId;\n setErrorIndex(errorInfo?.errorProductId);\n setProductId(activeProductId);\n toggleCheckErrorModal(activeProductId, errorInfo);\n }}\n disabled={isRivirField}\n style={{ marginRight: 5 }}\n />\n \n
\n \n \n {isErrorItem && !isRivirField && (\n modules?.productId === errorItem?.productId\n )\n }\n // formName={`form-${groupIdx}-${itemIdx}`}\n />\n )}\n {isErrorItem && isRivirField && (\n \n )}\n \n \n \n \n );\n};\n","import React from 'react';\n\nimport { PublicationCommonErrorItem } from './PublicationErrorItem';\n\nconst PublicationCommonErrorList = (props) => {\n const {\n errorGroup,\n groupIdx,\n status,\n setErrorIndex,\n setProductId,\n toggleCheckErrorModal,\n productEnums,\n productSchema,\n productDetailList,\n productModuleList,\n } = props;\n return (\n <>\n {errorGroup?.errorFields.map((errorItem, itemIdx) => {\n const isErrorItem = !!errorItem?.productId;\n\n const errorInfo = {\n errorProductId: errorItem?.productId,\n errorType: errorGroup?.errorType,\n errorMessage: errorGroup?.errorMessage,\n moduleName: errorItem?.moduleName,\n fieldName: errorItem?.fieldName,\n };\n\n const itemErrorKey = `${groupIdx}-${itemIdx}`;\n\n const isRivirField = errorItem.fieldName.split('.').length === 1; // fieldName = 'ModuleName.propertyName'\n\n return (\n \n );\n })}\n \n );\n};\n\nexport default PublicationCommonErrorList;\n","import React from 'react';\nimport { Row, Col, Avatar, Typography } from 'antd';\nimport { FormDeleteButton } from 'common/components';\n\nimport { CaretRightOutlined } from '@ant-design/icons';\n\nimport { Images } from 'config/assets';\n\nimport { ROUTE } from 'static/Constants';\n\nimport './PackageItemInfo.less';\n\nconst { Text, Title } = Typography;\n\nconst PackageItemInfo = (props) => {\n const { packageLevelItem } = props;\n\n const handleOpenProductNewTab = () => {\n const productId = packageLevelItem?.productId;\n if (productId) {\n const url = window.location.origin + ROUTE.PRODUCT + `/${productId}`;\n productId && window.open(url);\n }\n };\n\n return (\n \n \n \n \n \n {packageLevelItem?.productName}\n
\n \n {packageLevelItem?.productPackageLevel}\n \n
\n
\n \n {isNaN(packageLevelItem?.productSize)\n ? 'Unknown product size'\n : Math.round(packageLevelItem?.productSize * 100) / 100 ||\n 'Unknown product size'}\n  (\n {packageLevelItem?.productSizeUOM || 'Unknown measurement unit'})\n \n
\n \n \n }\n text='Open product'\n onClick={handleOpenProductNewTab}\n style={{ margin: 5 }}\n />\n \n
\n );\n};\n\nexport default PackageItemInfo;\n","import { deleteObjectField } from 'utils';\n/**\n * @param {*} multipleFormValues\n * @returns //? proccessed value for /api/syndication/save-product-data-for-publishing\n */\nexport const mapToFormValuePublicationInstantFix = (multipleFormValues) => {\n let submitValue = (multipleFormValues || []).map((formValue) => {\n if (!formValue) return {};\n\n let nextFormValue = {\n ...formValue,\n value: formValue[formValue?.fieldName],\n };\n\n deleteObjectField(nextFormValue, [formValue?.fieldName]);\n return nextFormValue;\n });\n\n if (submitValue.find((formValue) => !formValue?.productId)) {\n return false;\n }\n\n if (submitValue?.length <= 0) return [];\n\n //* filter all empty brickcode\n submitValue = submitValue.filter(\n (submitItem) =>\n (submitItem.fieldName || '').toLowerCase() !== 'brickcode' ||\n ((submitItem.fieldName || '').toLowerCase() === 'brickcode' &&\n submitItem?.value?.brickCodeName)\n );\n\n //* create two submit items for each brick code form\n let nextSubmitValue = [...submitValue];\n\n let brickCodeSubmitList = [];\n\n nextSubmitValue.forEach((itemValue, idx) => {\n if ((itemValue.fieldName || '').toLowerCase() === 'brickcode') {\n brickCodeSubmitList.push(idx);\n }\n });\n\n //* add brickcode value form\n brickCodeSubmitList.forEach((brickcodeSubmitIdx) => {\n const brickCodeData = nextSubmitValue[brickcodeSubmitIdx];\n\n const code = brickCodeData?.value?.brickCode;\n const brickCodeName = brickCodeData?.value?.brickCodeName;\n\n const defaultBrickCodeValue = {\n productId: brickCodeData?.productId,\n moduleName: '',\n };\n\n nextSubmitValue = [\n ...nextSubmitValue,\n {\n ...defaultBrickCodeValue,\n fieldName: 'BrickCode',\n value: code,\n },\n {\n ...defaultBrickCodeValue,\n fieldName: 'BrickCodeName',\n value: brickCodeName,\n },\n ];\n });\n\n //* remove all original brickcode form\n nextSubmitValue = nextSubmitValue.filter(\n (submitValueItem, idx) => !brickCodeSubmitList.includes(idx)\n );\n\n return nextSubmitValue;\n};\n","import { useState, useRef, useEffect, useCallback } from 'react';\n\nimport { toUniqueList } from 'utils';\n\nimport { isEqual } from 'lodash';\nimport usePrevious from 'hooks/usePrevious';\n\nimport * as productServices from 'services/product';\n\nconst useFetchDataForErrorList = (errorList, reloadOneError, errorIndex) => {\n const [productDetailList, setProductDetailList] = useState([]);\n const [productModuleList, setProductModuleList] = useState([]);\n\n const refProductDetailIdList = useRef([]);\n const refProductModuleIdList = useRef([]);\n\n const prevReloadOneError = usePrevious(reloadOneError);\n\n const getUniqueListCallback = useCallback(({ errorList }) => {\n let productDetailIdList = [];\n let productModuleIdList = [];\n errorList.forEach((errorGroup) => {\n errorGroup.errorFields.forEach((errorItem) => {\n const isRivirField = !errorItem?.moduleName;\n\n if (!isRivirField) {\n productModuleIdList.push(errorItem?.productId);\n }\n\n //* get all product's detail\n productDetailIdList.push(errorItem?.productId);\n });\n });\n\n return {\n productDetailIdList: toUniqueList(productDetailIdList),\n productModuleIdList: toUniqueList(productModuleIdList),\n };\n }, []);\n\n const fetchProductDataCallback = useCallback(\n async ({ uniqueList }, isRefetch) => {\n const { productDetailIdList, productModuleIdList } = uniqueList;\n\n if (\n !isEqual(productDetailIdList, refProductDetailIdList.current) ||\n isRefetch\n ) {\n refProductDetailIdList.current = productDetailIdList;\n const productDetailServiceList = productDetailIdList.map(\n (productId) => {\n const params = { productItemId: productId };\n return productServices.getProductFullView(params);\n }\n );\n\n await Promise.all(productDetailServiceList).then(async (response) => {\n const isSuccess =\n response.length && response.every((res) => res.isSuccess === true);\n\n if (isSuccess) {\n setProductDetailList(response.map((res) => res?.data));\n }\n });\n }\n\n if (\n !isEqual(productModuleIdList, refProductModuleIdList.current) ||\n isRefetch\n ) {\n refProductModuleIdList.current = productModuleIdList;\n const productModuleServiceList = productModuleIdList.map(\n (productId) => {\n const params = { productId };\n return productServices.getProductItemModules(params);\n }\n );\n\n await Promise.all(productModuleServiceList).then(async (response) => {\n const isSuccess =\n response.length && response.every((res) => res.isSuccess === true);\n\n if (isSuccess) {\n setProductModuleList(response.map((res) => res?.data));\n }\n });\n }\n },\n []\n );\n\n const refetchProductData = async () => {\n try {\n const uniqueList = getUniqueListCallback({ errorList });\n await fetchProductDataCallback({ uniqueList }, true);\n\n return true;\n } catch (err) {\n return false;\n }\n };\n\n useEffect(() => {\n if (errorList) {\n const uniqueList = getUniqueListCallback({ errorList });\n fetchProductDataCallback({ uniqueList });\n }\n }, [errorList, fetchProductDataCallback, getUniqueListCallback]);\n\n useEffect(() => {\n const reFetchOneError = async () => {\n const uniqueList = getUniqueListCallback({ errorList });\n const { productDetailIdList, productModuleIdList } = uniqueList;\n\n const productId = errorIndex;\n\n const foundIndexDetail = productDetailIdList.findIndex(\n (idItem) => idItem === productId\n );\n\n if (foundIndexDetail) {\n const params = { productId };\n const res = await productServices.getProductFullView(params);\n if (res?.isSuccess) {\n setProductDetailList((prev) => {\n let nextValue = [...prev];\n nextValue[foundIndexDetail] = res?.data;\n return nextValue;\n });\n }\n }\n\n const foundIndexModule = productModuleIdList.findIndex(\n (idItem) => idItem === productId\n );\n\n if (foundIndexModule) {\n const params = { productId: productId };\n const res = await productServices.getProductItemModules(params);\n if (res?.isSuccess) {\n setProductModuleList((prev) => {\n let nextValue = [...prev];\n nextValue[foundIndexDetail] = res?.data;\n return nextValue;\n });\n }\n }\n };\n\n if (reloadOneError && prevReloadOneError !== reloadOneError) {\n reFetchOneError();\n }\n }, [\n reloadOneError,\n prevReloadOneError,\n errorIndex,\n errorList,\n getUniqueListCallback,\n ]);\n\n return {\n data: {\n productDetailList,\n productModuleList,\n },\n refetchProductData,\n };\n};\n\nexport default useFetchDataForErrorList;\n","import React, { useState, useEffect } from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { Form, Button, Skeleton, Row, Col } from 'antd';\n\nimport {\n StyledModal,\n CustomNotification,\n WithLoading,\n} from 'common/components';\n\nimport { PublicationErrorItemValidationRule } from './PublicationErrorItem';\n\nimport PublicationCommonErrorList from './PubliccationCommonErrorList';\nimport PackageItemInfo from './PackageItemInfo';\n\nimport { useGetProductEnums } from 'hooks';\n\nimport { saveQuickPublicationFixForm } from 'services/product';\n\nimport { mapToFormValuePublicationInstantFix } from 'pages/branded-products/mapper/mapToFormValuePublicationInstantFix';\nimport { apiHandler } from 'utils/api';\nimport classnames from 'classnames';\nimport { startCase, range } from 'lodash';\nimport { sleep } from 'utils/delay';\n\nimport useFetchDataForErrorList from 'pages/branded-products/hooks/useFetchDataForErrorList';\nimport { useGetProductSchema } from 'hooks';\n\nimport messages from 'i18n/messages/brandedProduct';\n\nimport './PublicationErrorChecker.less';\n\nconst PublicationErrorChecker = (props) => {\n const {\n isErrorListModalOpen,\n errorList,\n setProductId,\n toggleCheckErrorModal,\n toggleErrorListModal,\n selectedErrorIndexHook,\n reloadOneError,\n getPublishCheckList,\n publishCheckLoading,\n packageLevelItem,\n } = props;\n\n const intl = useIntl();\n\n const productItemId = packageLevelItem?.productId;\n\n const [submitLoading, setSubmitLoading] = useState(false);\n const [reloadAfterSubmit, setReloadAfterSubmit] = useState(false);\n const [errorIndex, setErrorIndex] = selectedErrorIndexHook;\n\n const { productEnums } = useGetProductEnums();\n\n const { productSchema, isLoading } = useGetProductSchema();\n\n const {\n data: { productDetailList, productModuleList },\n refetchProductData,\n } = useFetchDataForErrorList(errorList, reloadOneError, errorIndex);\n\n const handleReloadValueAfterSubmit = async () => {\n const isGetCheckListEnd = await getPublishCheckList();\n if (isGetCheckListEnd) {\n setReloadAfterSubmit(true);\n await sleep(1500); // wait for error list to be update\n\n const isLoadProductDataEnd = await refetchProductData();\n\n if (!isLoadProductDataEnd) {\n CustomNotification.error(`Failed to product's data`);\n }\n setReloadAfterSubmit(false);\n }\n };\n\n const handleSubmitForm = async (name, { values, forms }) => {\n if (!forms) return;\n let originalFormValues = [];\n\n await Promise.all(\n Object.keys(forms).map(async (formName) => {\n const values = await forms[formName].getFieldsValue();\n originalFormValues.push(values);\n })\n );\n\n const submitValue = mapToFormValuePublicationInstantFix(originalFormValues);\n\n if (submitValue === false) {\n return CustomNotification.info(\n 'Please try again, we are preparing form data'\n );\n }\n\n const params = { data: submitValue };\n\n setSubmitLoading(true);\n await apiHandler({\n service: saveQuickPublicationFixForm,\n params,\n successMessage: intl.formatMessage(messages.savePublicSuccessMessage),\n errorMessage: intl.formatMessage(messages.savePublicErrorMessage),\n successCallback: () => {\n handleReloadValueAfterSubmit();\n },\n onFinally: async () => {\n setSubmitLoading(false);\n },\n });\n };\n\n useEffect(() => {\n if (errorList?.length === 0 && isErrorListModalOpen) {\n CustomNotification.success('All errors resolved!');\n toggleErrorListModal();\n }\n }, [errorList, isErrorListModalOpen]);\n\n const modalFooter = [\n ,\n \n Submit\n ,\n ];\n\n return (\n \n \n \n \n \n \n {reloadAfterSubmit ? (\n range(3).map(() => )\n ) : (\n \n {errorList.map((errorGroup, groupIdx) => {\n const isEmptyFields = errorGroup?.errorFields?.length <= 0;\n return (\n \n
\n Error type: {startCase(errorGroup?.errorType || '')}\n
\n
Error message: {errorGroup?.errorMessage}
\n\n {isEmptyFields ? (\n \n ) : (\n \n )}\n \n );\n })}\n
\n )}\n \n \n \n \n \n );\n};\n\nexport default PublicationErrorChecker;\n","import React, { useState } from 'react';\n\nimport { WithAbsoluteContainer } from 'common/components/';\n\nimport { useInjectReducer } from 'utils/common/injectedReducers';\nimport { useInjectSaga } from 'utils/common/injectSaga';\n\nimport { useGetPublishingProduct } from './hooks';\n\nimport ProdductItemSearchDrawer from './ProductItemSearchDrawer';\nimport PublicationErrorDetailModal from './PublicationErrorDetailModal';\nimport PublicationErrorChecker from './PublicationErrorChecker';\n\nimport productFullViewSaga from 'pages/product-full-view/controllers/saga';\nimport productFullViewReducer from 'pages/product-full-view/controllers/reducer';\n\nimport './styles.less';\n\nconst key = 'productFullView';\n\nconst PublicationValidationErrorCheck = (props) => {\n const {\n validationResult,\n isErrorListModalOpen,\n toggleErrorListModal,\n getPublishCheckList,\n publishCheckLoading,\n } = props;\n\n const errorList = validationResult?.errors || [];\n const packageLevelItem = validationResult;\n const hierarchyItems = [validationResult];\n\n const productItemId = packageLevelItem?.productId;\n\n useInjectReducer({ key, reducer: productFullViewReducer });\n useInjectSaga({ key, saga: productFullViewSaga });\n\n const [isErrModalVisible, setErrModalVisible] = useState(false);\n\n const [isDrawerVisible, setIsDrawerVisible] = useState(false);\n const [currentError, setCurrentError] = useState(null);\n const [productId, setProductId] = useState(null);\n const selectedErrorIndexHook = useState(null);\n const [reloadOneError, setReloadOneError] = useState(false);\n\n const { publishingProduct } = useGetPublishingProduct({\n productId,\n isEnabled: Boolean(productId),\n });\n\n const toggleCheckErrorModal = (productId, errorInfo) => {\n setErrModalVisible((prev) => {\n if (!prev) {\n setProductId(productId);\n setCurrentError(errorInfo);\n } else {\n setCurrentError(null);\n setProductId(null);\n }\n return !prev;\n });\n };\n\n const toggleIsDrawerOpen = () => setIsDrawerVisible((prev) => !prev);\n\n const setEditProductId = (productId) => {\n setProductId(productId);\n };\n\n return (\n \n \n\n {isErrModalVisible && (\n \n )}\n\n \n \n );\n};\n\nexport default PublicationValidationErrorCheck;\n","import { PUBLISH_TYPES } from 'static/Constants';\n\nconst mapToPublishProductRequestParams = ({\n publishChecklist,\n requestParams,\n}) => {\n let params;\n\n let greenData =\n publishChecklist &&\n publishChecklist.length > 0 &&\n publishChecklist.filter((val) => val.status === 'Green');\n\n let publishInfo = [];\n\n greenData &&\n greenData.length > 0 &&\n greenData.map((val) => {\n publishInfo.push({\n productId: val?.productId,\n recipientGLN: val?.recipientGLN,\n });\n });\n\n let publishType = requestParams?.publishType;\n\n const publishTypeParam =\n publishType === PUBLISH_TYPES.REPUBLISH.value\n ? { IsNewLoad: false, IsInitialLoad: false }\n : publishType === PUBLISH_TYPES.NEW.value\n ? { IsNewLoad: true, IsInitialLoad: false }\n : publishType === PUBLISH_TYPES.INITIAL.value\n ? { IsNewLoad: false, IsInitialLoad: true }\n : {};\n\n params = {\n sourceGLN: requestParams.sourceGLN,\n customImageFormat: requestParams.customImageFormat,\n publishInfo: publishInfo,\n ...publishTypeParam,\n };\n\n return params;\n};\n\nexport default mapToPublishProductRequestParams;\n","import {\n Button,\n Checkbox,\n Col,\n Modal,\n Row,\n Spin,\n Tooltip,\n Typography,\n} from 'antd';\nimport React, { useEffect, useState } from 'react';\n\nimport { ArrowDownOutlined } from '@ant-design/icons';\nimport { CustomNotification } from 'common/components';\nimport PublicationValidationErrorCheck from '../publication-validation-error-check';\n\nimport { Images } from 'config/assets';\n\nimport * as endpointsProduct from 'services/product/endpoints';\nimport { getPublishChecklist } from 'services/product';\n\nimport { AgGridColumn, AgGridReact } from 'ag-grid-react';\nimport classnames from 'classnames';\n\nimport { dialogFunction } from 'common/components/index';\nimport ErrorModal from 'common/components/product-publication-setup/ErrorModal.js';\nimport * as api from 'config/axios';\nimport { formatMDY } from 'utils/formatDate';\n\nimport mapToPublishProductRequestParams from 'pages/branded-products/mapper/mapToPublishProductRequestParams';\n\nimport { useGetProductFullView, useGlobalModal } from 'hooks';\n\nimport 'ag-grid-enterprise/dist/styles/ag-grid.css';\nimport 'ag-grid-enterprise/dist/styles/ag-theme-alpine.css';\nimport './PublicationValidationView.less';\n\nconst color = [\n 'beige',\n 'bisque',\n 'burlywood',\n 'chocolate',\n 'coral',\n 'darkseagreen',\n 'lightblue',\n 'lightcyan',\n 'mistyrose,',\n 'pink',\n 'skyblue',\n 'wheat',\n 'yellowgreen',\n 'teal',\n];\n\nconst PublicationValidationView = ({\n requestParams,\n isFullView,\n productId,\n}) => {\n const [loading, setLoading] = useState(false);\n const [loadingPublish, setLoadingPublish] = useState(false);\n const [publishChecklist, setPublishChecklist] = useState([]);\n const [hieararchySelect, setHieararchySelect] = useState(-1);\n const [publishSelect, setPublishSelect] = useState(-1);\n\n const [visibleHieararchy, setVisibleHieararchy] = useState(false);\n const [rowDataHieararchy, setRowDataHieararchy] = useState([]);\n const [isErrorListModalOpen, setIsErrorListModalOpen] = useState(false);\n const [errorList, setErrorList] = useState([]);\n\n const { handleRefetchProductFullView } = useGetProductFullView({\n productId,\n });\n\n const { checkModalVisible, MODAL_NAMES, closeAllModal } = useGlobalModal();\n\n const visible = checkModalVisible(\n MODAL_NAMES.PUBLICATION_VALIDATE_VIEW_MODAL\n );\n\n const clearState = () => {\n setPublishChecklist([]);\n setPublishSelect(-1);\n setHieararchySelect(-1);\n };\n\n const toggleErrorListModal = () => {\n setIsErrorListModalOpen((prev) => {\n prev && setPublishSelect(-1);\n\n return !prev;\n });\n };\n\n const handleClickErrorStatus = (rowIndex) => {\n setPublishSelect(rowIndex);\n toggleErrorListModal();\n };\n\n useEffect(() => {\n if (!requestParams) return;\n setErrorList([]);\n handleGetPublishCheckList(requestParams);\n }, [requestParams]);\n\n const handleGetPublishCheckList = async (params) => {\n setLoading(true);\n await getPublishChecklist(params)\n .then((response) => {\n const { message, isSuccess, data, status } = response || {};\n if (isSuccess) {\n let data;\n data = response?.data?.publishChecklist;\n setPublishChecklist(data);\n } else {\n const notificationMessage = message\n ? message\n : status === 500 && data?.title\n ? data?.title\n : 'Server Error';\n\n CustomNotification.error(notificationMessage);\n }\n })\n .catch((error) => {})\n .finally(() => setLoading(false));\n };\n\n const renderErrorField = (params, text) => {\n let array = params.data?.errors || [];\n let check = {};\n let result = array.filter((o) => {\n var key = ['errorMessage', 'errorType'].map((k) => o[k]).join('|');\n if (!check[key]) {\n check[key] = true;\n return true;\n }\n });\n return (\n \n \n \n {text}:\n \n \n {result &&\n result.length > 0 > 0 &&\n result.map((val) => {\n return (\n \n \n - {val?.errorType}: {val?.errorMessage}\n \n {val?.errorFields &&\n val?.errorFields.length > 0 &&\n val?.errorFields.map((err) => {\n return (\n \n \n + ({err.packageLevel}) {err.fieldName}\n \n \n );\n })}\n \n );\n })}\n \n );\n };\n const statusRender = (params) => {\n if (params.value === 'Yellow')\n return (\n \n {\n handleClickErrorStatus(params?.rowIndex);\n }}\n style={{\n width: '100%',\n height: '100%',\n color: 'transparent',\n }}\n >\n error list\n \n \n );\n if (params.value === 'Red')\n return (\n \n {\n handleClickErrorStatus(params?.rowIndex);\n }}\n style={{\n width: '100%',\n height: '100%',\n color: 'transparent',\n }}\n >\n error list\n \n \n );\n if (params.value === 'Green')\n return (\n \n }\n onClick={() => {}}\n style={{ color: '#fff', width: '100%', height: '100%' }}\n >\n {' '}\n \n \n );\n return
;\n };\n\n const statusCellClass = (params) => {\n if (params.value === 'Green') {\n return 'rag-green';\n }\n if (params.value === 'Yellow') {\n return 'rag-amber';\n }\n if (params.value === 'Red') {\n return 'rag-red';\n }\n };\n\n const imgRender = (params) => {\n return (\n // \n \n // \n );\n };\n\n const countSizeArrowRender = (params) => {\n return (\n \n \n \n {isNaN(parseFloat(params?.data?.productPackCount)) &&\n isNaN(parseFloat(params?.data?.productSize))\n ? ''\n : isNaN(parseFloat(params?.data?.productPackCount))\n ? Math.round(parseFloat(params?.data?.productSize) * 100) / 100 +\n ' ' +\n (params?.data?.productSizeUOM || 'unknown measurement unit')\n : isNaN(parseFloat(params?.data?.productSize))\n ? params?.data?.productPackCount +\n (params?.data?.productSizeUOM || 'unknown measurement unit')\n : params?.data?.productPackCount +\n '/' +\n Math.round(parseFloat(params?.data?.productSize) * 100) / 100 +\n ' ' +\n (params?.data?.productSizeUOM || 'unknown measurement unit')}\n \n \n \n }\n onClick={() => {\n setPublishSelect(params?.rowIndex);\n let hierarchyItems = params?.data?.hierarchyItems || [];\n hierarchyItems.sort(comparePackageLevel);\n hierarchyItems.sort(\n (firstItem, secondItem) =>\n firstItem?.hierarchyId - secondItem?.hierarchyId\n );\n setRowDataHieararchy(hierarchyItems);\n setVisibleHieararchy(true);\n }}\n >\n \n \n );\n };\n\n const comparePackageLevel = (a, b) => {\n if (a?.productPackageLevel === 'Pallet') {\n if (b?.productPackageLevel === 'Pallet') {\n return 0;\n } else {\n return -1;\n }\n }\n if (a?.productPackageLevel === 'Master Case') {\n if (b?.productPackageLevel === 'Master Case') {\n return 0;\n } else if (b?.productPackageLevel === 'Pallet') {\n return 1;\n } else {\n return -1;\n }\n }\n if (a?.productPackageLevel === 'Case') {\n if (b?.productPackageLevel === 'Case') {\n return 0;\n } else if (\n b?.productPackageLevel === 'Pallet' ||\n b?.productPackageLevel === 'Master Case'\n ) {\n return 1;\n } else {\n return -1;\n }\n }\n if (a?.productPackageLevel === 'Inner Pack') {\n if (b?.productPackageLevel === 'Inner Pack') {\n return 0;\n } else if (\n b?.productPackageLevel === 'Pallet' ||\n b?.productPackageLevel === 'Master Case' ||\n b?.productPackageLevel === 'Case'\n ) {\n return 1;\n } else {\n return -1;\n }\n }\n if (a?.productPackageLevel === 'Unit') {\n if (b?.productPackageLevel === 'Unit') {\n return 0;\n } else {\n return 1;\n }\n }\n return 0;\n };\n\n const renderSize = (params) => {\n return isNaN(parseFloat(params?.value))\n ? ''\n : Math.round(parseFloat(params?.value) * 100) / 100;\n };\n\n const columnDefs = [\n {\n fieldNameCamelCase: 'status',\n displayName: '',\n width: 50,\n cellClass: statusCellClass,\n cellRenderer: statusRender,\n },\n {\n fieldNameCamelCase: 'productImageThumb',\n displayName: '',\n width: 50,\n cellRenderer: imgRender,\n },\n {\n dataType: 'string',\n displayName: 'Recipient',\n fieldName: 'RecipientName',\n fieldNameCamelCase: 'recipientName',\n },\n {\n dataType: 'string',\n displayName: 'Recipient GLN',\n fieldName: 'RecipientGLN',\n fieldNameCamelCase: 'recipientGLN',\n },\n {\n dataType: 'string',\n displayName: 'Product Name',\n fieldName: 'ProductName',\n fieldNameCamelCase: 'productName',\n },\n {\n dataType: 'string',\n displayName: 'Product GTIN',\n fieldName: 'ProductGTIN',\n fieldNameCamelCase: 'productGTIN',\n },\n {\n dataType: 'string',\n displayName: 'Package Level',\n fieldName: 'productPackageLevel',\n fieldNameCamelCase: 'productPackageLevel',\n },\n {\n dataType: 'string',\n displayName: 'Count/Size',\n cellRenderer: countSizeArrowRender,\n },\n {\n dataType: 'string',\n displayName: 'Brand Name',\n fieldName: 'ProductBrandName',\n fieldNameCamelCase: 'productBrandName',\n },\n {\n dataType: 'string',\n displayName: 'RIVIR ID',\n fieldName: 'ProductRivirId',\n fieldNameCamelCase: 'productRivirId',\n },\n {\n dataType: 'string',\n displayName: 'Primary Size',\n fieldName: 'ProductSize',\n fieldNameCamelCase: 'productSize',\n cellRenderer: renderSize,\n },\n {\n dataType: 'string',\n displayName: 'Primary Unit of Measure',\n fieldName: 'ProductSizeUOM',\n fieldNameCamelCase: 'productSizeUOM',\n },\n ];\n\n const handleModalPublish = () => {\n setErrorList([]);\n\n const params = mapToPublishProductRequestParams({\n publishChecklist,\n requestParams,\n });\n\n setLoadingPublish(true);\n api\n .sendPost(endpointsProduct.EXECUTE_PUBLISH_PRODUCTS, params)\n .then((response) => {\n const { isSuccess, data } = response;\n\n if (isSuccess) {\n CustomNotification.success('Publish successfully');\n clearState();\n closeAllModal();\n } else {\n const errorMessages = data?.messages?.map(\n (mess) => mess?.messageContent\n );\n\n setErrorList(errorMessages);\n }\n })\n .catch((error) => {})\n .finally(() => {\n setLoadingPublish(false);\n });\n };\n const handleModalCancel = () => {\n clearState();\n setLoading(false);\n closeAllModal();\n //\n if (isFullView && productId) {\n handleRefetchProductFullView();\n }\n };\n\n const handleModalCancelHieararchy = () => {\n setVisibleHieararchy(false);\n setHieararchySelect(-1);\n };\n const handleModalSelect = () => {\n dialogFunction({\n type: 'warn',\n content:\n 'Validation process will re-execute. Are you sure you want to select new package level for publication?',\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: handleConfirm,\n zIndex: 100000,\n });\n };\n\n const handleConfirm = async () => {\n let dataSelect = rowDataHieararchy[hieararchySelect];\n let dataTemp = [...publishChecklist];\n\n let params = {\n productIds: [dataSelect?.productId],\n recipientGLNs: [dataTemp[publishSelect]?.recipientGLN],\n sourceGLN: requestParams.sourceGLN,\n };\n\n setHieararchySelect(-1);\n setVisibleHieararchy(false);\n setLoading(true);\n\n await getPublishChecklist(params)\n .then((response) => {\n const { isSuccess, message, data, status } = response || {};\n\n if (isSuccess) {\n let data;\n data = response?.data?.publishChecklist;\n dataTemp[publishSelect] = (data && data.length > 0 && data[0]) || [];\n setPublishChecklist(dataTemp);\n } else {\n const notificationMessage = message\n ? message\n : status === 500 && data?.title\n ? data?.title\n : 'Server Error';\n\n CustomNotification.error(notificationMessage);\n }\n })\n .catch((error) => {})\n .finally(() => setLoading(false));\n };\n\n const regetPublishErrorAfterSubmitErrorChecker = async () => {\n let dataSelect = publishChecklist[publishSelect];\n\n let dataTemp = [...publishChecklist];\n\n const recipientListToRecheck = publishChecklist\n .filter(\n (publishCheck) => publishCheck?.productId === dataSelect?.productId\n )\n .map((publishCheck) => publishCheck?.recipientGLN);\n\n let params = {\n productIds: [dataSelect?.productId],\n recipientGLNs: recipientListToRecheck,\n\n sourceGLN: requestParams.sourceGLN,\n };\n\n setLoading(true);\n await getPublishChecklist(params)\n .then((response) => {\n const { isSuccess, status, data, message } = response || {};\n if (isSuccess) {\n let data;\n data = response?.data?.publishChecklist;\n\n data &&\n data?.length >= 0 &&\n data.forEach((resPublishCheck) => {\n const foundCheckListIdx = dataTemp.findIndex(\n (publishCheck) =>\n publishCheck?.productId === resPublishCheck.productId &&\n publishCheck?.recipientGLN === resPublishCheck.recipientGLN\n );\n if (foundCheckListIdx !== -1) {\n dataTemp[foundCheckListIdx] = resPublishCheck;\n }\n });\n\n setPublishChecklist(dataTemp);\n } else {\n const notificationMessage = message\n ? message\n : status === 500 && data?.title\n ? data?.title\n : 'Server Error';\n\n CustomNotification.error(notificationMessage);\n }\n })\n .catch((error) => {})\n .finally(() => setLoading(false));\n\n return true;\n };\n\n const columnGrid = (val, index) => {\n return (\n \n );\n };\n const formatDate = (params) => {\n return formatMDY(params.value);\n };\n const checkboxRender = (params) => {\n return (\n {\n // params.data[params.colDef.field] = e.targetchecked;\n // params.api.refreshCells();\n // }}\n >
\n );\n };\n\n const setColor = (selectPackageLevel, packageLevel) => {\n if (selectPackageLevel === 'Pallet') {\n if (packageLevel === 'Pallet') {\n return 'grey';\n } else {\n return 'grey';\n }\n }\n if (selectPackageLevel === 'Master Case') {\n if (packageLevel === 'Master Case') {\n return 'grey';\n } else if (packageLevel === 'Pallet') {\n return 'green';\n } else {\n return 'grey';\n }\n }\n if (selectPackageLevel === 'Case') {\n if (packageLevel === 'Case') {\n return 'grey';\n } else if (packageLevel === 'Pallet' || packageLevel === 'Master Case') {\n return 'green';\n } else {\n return 'grey';\n }\n }\n if (selectPackageLevel === 'Inner Pack') {\n if (packageLevel === 'Inner Pack') {\n return 'grey';\n } else if (\n packageLevel === 'Pallet' ||\n packageLevel === 'Master Case' ||\n packageLevel === 'Case'\n ) {\n return 'green';\n } else {\n return 'grey';\n }\n }\n if (selectPackageLevel === 'Unit') {\n if (packageLevel === 'Unit') {\n return 'grey';\n } else {\n return 'green';\n }\n }\n return '';\n };\n\n return (\n <>\n \n Cancel\n ,\n {\n handleModalPublish();\n }}\n loading={loading || loadingPublish}\n disabled={\n (publishChecklist &&\n publishChecklist.length > 0 &&\n publishChecklist.filter((val) => val.status === 'Green')\n ?.length === 0) ||\n !publishChecklist\n }\n >\n Publish\n ,\n ]}\n // zIndex={9999}\n >\n {loading || loadingPublish ? (\n
\n ) : (\n \n {columnDefs && columnDefs.length > 0 && (\n <>\n \n \n {columnDefs.map((val, index) => {\n return columnGrid(val, index);\n })}\n \n \n \n \n )}\n \n )}\n \n\n \n Cancel\n ,\n {\n handleModalSelect();\n }}\n loading={loading}\n disabled={hieararchySelect < 0}\n >\n Select\n ,\n ]}\n zIndex={99999}\n >\n \n {rowDataHieararchy &&\n rowDataHieararchy.length > 0 &&\n rowDataHieararchy.map((val, index) => {\n return (\n setHieararchySelect(index)}\n className={\n hieararchySelect === index ||\n (hieararchySelect === -1 &&\n publishChecklist[publishSelect]?.productId ===\n val?.productId &&\n publishChecklist[publishSelect]?.productPackageLevel ===\n val?.productPackageLevel)\n ? 'item-hieararchy item-hieararchy--selected'\n : 'item-hieararchy'\n }\n style={{ background: color[val?.hierarchyId % 10] }}\n >\n \n \n \n \n \n \n {val?.productGTIN} - {val?.productName}\n \n \n \n \n {val?.productBrandName}\n \n \n \n \n {val?.productPackageLevel}\n \n \n \n \n \n Package Count\n \n \n \n \n {val?.productPackCount}\n \n \n \n \n \n \n Size\n \n \n \n \n {isNaN(parseFloat(val?.productSize))\n ? ''\n : Math.round(parseFloat(val?.productSize) * 100) /\n 100}{' '}\n {val?.productSizeUOM}\n \n \n \n \n \n );\n })}\n \n \n <>\n {toggleErrorListModal && (\n \n )}\n \n \n );\n};\n\nexport default PublicationValidationView;\n","import customCellComponents from '../components/custom-cell-components/customCellComponents';\n\nimport { formatMDYWithParam } from 'utils/formatDate';\n\nconst formatFieldsName = (jsonConfig) => {\n let fieldsName = [];\n\n if (jsonConfig) {\n const config = JSON.parse(jsonConfig);\n\n config.columns.forEach((column) => {\n fieldsName.push({\n fieldName: column.fieldFullPath,\n });\n });\n }\n\n return fieldsName;\n};\n\nconst formatColumns = (jsonConfig) => {\n let cols = [\n {\n filter: false,\n suppressMenu: true,\n resizable: true,\n checkboxSelection: true,\n },\n ];\n\n if (jsonConfig) {\n const config = JSON.parse(jsonConfig);\n\n config.columns.forEach((column) => {\n const { fieldFullPath, dataType, displayName, minWidth, width, field } =\n column || {};\n\n if (fieldFullPath === 'productName') {\n cols.push({\n allowFilter: true,\n allowSort: true,\n resizable: true,\n dataType: dataType?.toLowerCase(),\n field: fieldFullPath,\n headerName: displayName,\n linkTo: '/product/{id}',\n minWidth: minWidth,\n width: width,\n });\n } else if (dataType?.toLowerCase() === 'datetime') {\n cols.push({\n field: fieldFullPath,\n headerName: displayName,\n minWidth: minWidth,\n width: width,\n cellRenderer: formatMDYWithParam,\n });\n } else if (field === 'stateIcons') {\n cols.push({\n ...column,\n field: fieldFullPath,\n headerName: 'States',\n minWidth: minWidth,\n width: width,\n cellRenderer: customCellComponents.renderIcons,\n });\n } else if (field === 'productThumbnail') {\n cols.push({\n ...column,\n dataType: dataType?.toLowerCase(),\n field: fieldFullPath,\n headerName: displayName,\n minWidth: minWidth,\n width: width,\n cellRenderer: customCellComponents.renderThumbnail,\n });\n } else {\n cols.push({\n allowFilter: true,\n allowSort: true,\n resizable: true,\n dataType: dataType?.toLowerCase(),\n field: fieldFullPath,\n headerName: displayName,\n minWidth: minWidth,\n width: width,\n });\n }\n });\n }\n\n return cols;\n};\n\nexport { formatColumns, formatFieldsName };\n","import * as types from './constants';\n\nimport { formatColumns, formatFieldsName } from '../utils';\nimport { isUndefined, isBoolean, pickBy } from 'lodash';\n\nexport function getProductList(\n pageSize,\n pageIndex,\n search,\n primaryFieldsOnly,\n filters,\n advancedSearchContainer,\n searchCategory,\n isFavoriteRoute,\n packageLevels,\n fromDate = null,\n aplId\n) {\n return {\n type: types.GET_PRODUCT_LIST,\n pageSize,\n pageIndex,\n search,\n primaryFieldsOnly,\n filters,\n advancedSearchContainer,\n searchCategory,\n isFavoriteRoute,\n packageLevels,\n fromDate,\n aplId,\n };\n}\n\nexport function getMemberProductList({\n pageSize,\n pageIndex,\n search,\n filters,\n advancedSearchContainer,\n searchCategory,\n packageLevels,\n isFavoriteRoute,\n fromDate = null,\n memberId,\n aplId,\n}) {\n return {\n type: types.GET_MEMBER_PRODUCT_LIST,\n pageSize,\n pageIndex,\n search,\n filters,\n advancedSearchContainer,\n searchCategory,\n packageLevels,\n isFavoriteRoute,\n fromDate,\n memberId,\n aplId,\n };\n}\n\nexport function getProductListSuccess(products, total) {\n return {\n type: types.GET_PRODUCT_LIST_SUCCESS,\n products,\n total,\n };\n}\n\nexport function getProductListError(error) {\n return {\n type: types.GET_PRODUCT_LIST_ERROR,\n error,\n };\n}\n\nexport function gridColumnInfo(gridName) {\n return {\n type: types.PRODUCT_GRID_COLUMN_INFO,\n gridName,\n };\n}\n\nexport function gridColumnInfoSuccess(columns) {\n return {\n type: types.PRODUCT_GRID_COLUMN_INFO_SUCCESS,\n columns,\n };\n}\n\nexport function gridColumnInfoError(error) {\n return {\n type: types.PRODUCT_GRID_COLUMN_INFO_ERROR,\n error,\n };\n}\n\nexport function toggleReloadGridProduct(value = true) {\n return {\n type: types.TOGGLE_RELOAD_GRID_PRODUCT,\n payload: value,\n };\n}\n\nexport function saveGridConfig(payload) {\n const { selectedColumns, jsonConfig, isHaveDefaultConfig } = payload;\n\n let nextPayload = {\n selectedColumns: isUndefined(selectedColumns) ? undefined : selectedColumns,\n allConfigFieldsName: isUndefined(jsonConfig)\n ? undefined\n : formatFieldsName(jsonConfig),\n defaultColumnsGrid: isUndefined(jsonConfig)\n ? undefined\n : formatColumns(jsonConfig),\n isConfigEmpty: isUndefined(selectedColumns)\n ? undefined\n : selectedColumns === null\n ? true\n : false,\n isHaveDefaultConfig: isBoolean(isHaveDefaultConfig)\n ? isHaveDefaultConfig\n : undefined,\n };\n\n nextPayload = pickBy(nextPayload, (value) => value !== undefined);\n\n return {\n type: types.SAVE_GRID_CONFIG,\n payload: nextPayload,\n };\n}\nexport function applyGridConfig(data) {\n return {\n type: types.APPLY_GRID_CONFIG,\n payload: data,\n };\n}\n// Add Product\nexport function addProduct(params) {\n return {\n type: types.ADD_PRODUCT,\n params,\n };\n}\n\nexport function addProductSuccess(data) {\n return {\n type: types.ADD_PRODUCT_SUCCESS,\n data,\n };\n}\n\nexport function addProductError(params) {\n return {\n type: types.ADD_PRODUCT_ERROR,\n params,\n };\n}\n\nexport const getProductBrandImageOnAdd = (payload) => {\n return {\n type: types.GET_PRODUCT_BRAND_ON_ADD,\n payload,\n };\n};\nexport const getProductBrandImageOnAddSuccess = (payload) => {\n return {\n type: types.GET_PRODUCT_BRAND_ON_ADD_SUCCESS,\n payload,\n };\n};\nexport const getProductBrandImageOnAddError = (payload) => ({\n type: types.GET_PRODUCT_BRAND_ON_ADD_ERROR,\n payload,\n});\n\nexport const toggleProductNew = (status) => ({\n type: types.TOGGLE_PRODUCT_NEW,\n payload: status,\n});\n\nexport function getGDSNPartyList(gridName) {\n return {\n type: types.GET_GDSN_PARTY_LIST,\n gridName,\n };\n}\n\nexport function getGDSNPartyListSuccess(columns) {\n return {\n type: types.GET_GDSN_PARTY_LIST_SUCCESS,\n columns,\n };\n}\n\nexport function getGDSNPartyListFailure(error) {\n return {\n type: types.GET_GDSN_PARTY_LIST_FAILURE,\n error,\n };\n}\n\nexport const toggleProductUnmatch = (status) => ({\n type: types.TOGGLE_PRODUCT_UNMATCH,\n payload: status,\n});\n","// Action Types\nexport const GET_PRODUCT_LIST = 'GET_PRODUCT_LIST';\nexport const GET_MEMBER_PRODUCT_LIST = 'GET_MEMBER_PRODUCT_LIST';\nexport const GET_PRODUCT_LIST_SUCCESS = 'GET_PRODUCT_LIST_SUCCESS';\nexport const GET_PRODUCT_LIST_ERROR = 'GET_PRODUCT_LIST_ERROR';\nexport const PRODUCT_GRID_COLUMN_INFO = 'PRODUCT_GRID_COLUMN_INFO';\nexport const PRODUCT_GRID_COLUMN_INFO_SUCCESS =\n 'PRODUCT_GRID_COLUMN_INFO_SUCCESS';\nexport const PRODUCT_GRID_COLUMN_INFO_ERROR = 'PRODUCT_GRID_COLUMN_INFO_ERROR';\n\nexport const TOGGLE_RELOAD_GRID_PRODUCT = 'TOGGLE_RELOAD_GRID_PRODUCT';\nexport const SAVE_GRID_CONFIG = 'SAVE_GRID_CONFIG';\nexport const APPLY_GRID_CONFIG = 'APPLY_GRID_CONFIG';\n// Add Product via Form\nexport const ADD_PRODUCT = 'ADD_PRODUCT';\nexport const ADD_PRODUCT_SUCCESS = 'ADD_PRODUCT_SUCCESS';\nexport const ADD_PRODUCT_ERROR = 'ADD_PRODUCT_ERROR';\n\n// Get Brand Image on Add\nexport const GET_PRODUCT_BRAND_ON_ADD = 'GET_PRODUCT_BRAND_ON_ADD';\nexport const GET_PRODUCT_BRAND_ON_ADD_SUCCESS =\n 'GET_PRODUCT_BRAND_ON_ADD_SUCCESS';\nexport const GET_PRODUCT_BRAND_ON_ADD_ERROR = 'GET_PRODUCT_BRAND_ON_ADD_ERROR';\nexport const TOGGLE_PRODUCT_NEW = 'TOGGLE_PRODUCT_NEW';\n\n// GDSN Party List\nexport const GET_GDSN_PARTY_LIST = 'GET_GDSN_PARTY_LIST';\nexport const GET_GDSN_PARTY_LIST_SUCCESS = 'GET_GDSN_PARTY_LIST_SUCCESS';\nexport const GET_GDSN_PARTY_LIST_FAILURE = 'GET_GDSN_PARTY_LIST_FAILURE';\nexport const TOGGLE_PRODUCT_UNMATCH = 'TOGGLE_PRODUCT_UNMATCH';\n","import produce from 'immer';\nimport * as types from './constants';\n\n// initial state\nexport const initialState = {\n loading: false,\n error: false,\n products: [],\n total: 0,\n pageSize: 20,\n pageIndex: 1,\n search: '',\n columns: [],\n gridName: '',\n reloadGrid: false,\n gridConfig: {\n allConfigFieldsName: null,\n selectedColumns: null,\n defaultColumnsGrid: [],\n isConfigEmpty: true,\n isHaveDefaultConfig: false,\n },\n applyGridConfig: {\n configId: null,\n configName: null,\n id: null,\n isDefault: null,\n jsonConfig: null,\n lastModified: null,\n selectedColumns: null,\n isApply: false,\n },\n // ENUM\n enums: null,\n //\n addProductStatus: false,\n addProductError: false,\n\n brandImageOnAdd: {\n loading: false,\n error: false,\n data: [],\n totalItems: 0,\n pageSize: 20,\n pageIndex: 1,\n },\n isDisplayProductNew: false,\n\n GDSNPartyList: {\n loading: false,\n error: false,\n data: [],\n },\n};\n\nconst formatFieldsName = (jsonConfig) => {\n let fieldsName = [];\n\n if (jsonConfig) {\n const config = JSON.parse(jsonConfig);\n\n config.columns.forEach((column) => {\n fieldsName.push({\n fieldName: column.fieldFullPath,\n });\n });\n }\n\n return fieldsName;\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst productReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_PRODUCT_LIST:\n draft.loading = true;\n draft.error = false;\n draft.pageSize = action.pageSize;\n draft.pageIndex = action.pageIndex;\n draft.search = action.search;\n break;\n case types.GET_MEMBER_PRODUCT_LIST:\n draft.loading = true;\n draft.error = false;\n break;\n case types.GET_PRODUCT_LIST_SUCCESS:\n draft.loading = false;\n draft.products = action.products;\n draft.total = action.total;\n draft.reloadGrid = false;\n break;\n case types.GET_PRODUCT_LIST_ERROR:\n draft.loading = false;\n draft.total = 0;\n draft.products = [];\n draft.error = action.error;\n break;\n case types.PRODUCT_GRID_COLUMN_INFO:\n draft.loading = true;\n draft.error = false;\n draft.gridName = action.gridName;\n break;\n case types.PRODUCT_GRID_COLUMN_INFO_SUCCESS:\n draft.loading = false;\n draft.columns = action.columns;\n break;\n case types.PRODUCT_GRID_COLUMN_INFO_ERROR:\n draft.loading = false;\n draft.error = action.error;\n break;\n\n case types.TOGGLE_RELOAD_GRID_PRODUCT:\n draft.reloadGrid = action.payload;\n break;\n\n case types.SAVE_GRID_CONFIG:\n draft.gridConfig = {\n ...draft.gridConfig,\n ...action.payload,\n };\n break;\n\n case types.APPLY_GRID_CONFIG:\n draft.applyGridConfig = action.payload;\n break;\n\n case types.ADD_PRODUCT:\n draft.addProductStatus = true;\n draft.addProductError = false;\n break;\n case types.ADD_PRODUCT_SUCCESS:\n draft.addProductStatus = false;\n break;\n case types.ADD_PRODUCT_ERROR:\n draft.addProductStatus = false;\n draft.addProductError = true;\n break;\n\n case types.GET_PRODUCT_BRAND_ON_ADD:\n draft.brandImageOnAdd['loading'] = true;\n break;\n case types.GET_PRODUCT_BRAND_ON_ADD_SUCCESS:\n draft.brandImageOnAdd['loading'] = false;\n draft.brandImageOnAdd['data'] = action?.payload?.gridData || [];\n draft.brandImageOnAdd['pageIndex'] =\n action?.payload?.paging?.currentPageIndex ||\n initialState.brandImageOnAdd.pageIndex;\n draft.brandImageOnAdd['pageSize'] =\n action?.payload?.paging?.currentPageSize ||\n initialState.brandImageOnAdd.pageSize;\n draft.brandImageOnAdd['totalItems'] =\n action?.payload?.paging?.totalRecord ||\n initialState.brandImageOnAdd.totalItems;\n break;\n case types.GET_PRODUCT_BRAND_ON_ADD_ERROR:\n draft.brandImageOnAdd['loading'] = false;\n break;\n case types.TOGGLE_PRODUCT_NEW:\n draft.isDisplayProductNew = action.payload;\n break;\n\n case types.GET_GDSN_PARTY_LIST:\n draft.GDSNPartyList['loading'] = true;\n break;\n case types.GET_GDSN_PARTY_LIST_SUCCESS:\n draft.GDSNPartyList['loading'] = false;\n draft.GDSNPartyList['data'] = action?.columns || [];\n\n break;\n case types.GET_GDSN_PARTY_LIST_FAILURE:\n draft.GDSNPartyList['loading'] = false;\n break;\n }\n });\n\nexport default productReducer;\n","import { put, call, all } from 'redux-saga/effects';\nimport { takeLatest } from 'redux-saga/effects';\n\nimport * as types from './constants';\nimport * as actions from './actions';\nimport * as services from 'services/product';\nimport * as servicesGrid from 'services/grid';\nimport * as servicesMembers from 'services/members';\n\nimport { formatMDYWithParam } from 'utils/formatDate';\n\nimport { DEFAULT_SORT, DEFAULT_PRODUCT_COLUMNS } from 'static/Constants';\n\nimport customCellComponents from '../components/custom-cell-components/customCellComponents';\n\nexport function* getProductList(payload) {\n const {\n pageIndex,\n pageSize,\n search,\n primaryFieldsOnly,\n filters,\n advancedSearchContainer,\n searchCategory,\n isFavoriteRoute,\n packageLevels,\n fromDate,\n aplId,\n } = payload;\n\n try {\n const params = {\n filters: filters || [],\n pageIndex: pageIndex,\n pageSize: pageSize,\n search: { searchText: search, primaryFieldsOnly: primaryFieldsOnly },\n advancedSearchContainer: advancedSearchContainer ?? {},\n packageLevels: packageLevels,\n searchCategory: searchCategory,\n isFavoriteRoute: isFavoriteRoute,\n ...(search ? null : { sort: DEFAULT_SORT }),\n fromDate: fromDate ? fromDate : null,\n aplId,\n };\n\n const response = yield call(services.getProductListService, params);\n\n if (response?.isSuccess) {\n const products = response?.data?.gridData;\n const count = response?.data?.paging?.totalRecord;\n yield put(actions.getProductListSuccess(products, count));\n }\n } catch (error) {\n yield put(actions.getProductListError(error));\n }\n}\n\nexport function* getMemberProductListSaga(payload) {\n const {\n pageIndex,\n pageSize,\n search,\n filters,\n advancedSearchContainer,\n searchCategory,\n packageLevels,\n isFavoriteRoute,\n fromDate,\n memberId,\n aplId,\n } = payload;\n\n try {\n const params = {\n filters: filters || [],\n pageIndex: pageIndex,\n pageSize: pageSize,\n search: {\n searchText: search?.searchText,\n primaryFieldsOnly: search?.primaryFieldsOnly,\n },\n advancedSearchContainer: advancedSearchContainer,\n packageLevels: packageLevels,\n isFavoriteRoute: isFavoriteRoute,\n searchCategory: searchCategory,\n ...(search ? null : { sort: DEFAULT_SORT }),\n fromDate,\n memberId,\n aplId,\n };\n\n const response = yield call(services.getProductListService, params);\n\n if (response?.isSuccess) {\n const products = response?.data?.gridData;\n const count = response?.data?.paging?.totalRecord;\n yield put(actions.getProductListSuccess(products, count));\n }\n } catch (error) {\n yield put(actions.getProductListError(error));\n }\n}\n\nexport const formatProductDetailColumns = (response) => {\n let columns = [\n { field: '', checkboxSelection: true, filter: false, suppressMenu: true },\n // {\n // field: '',\n // cellRenderer: onFavoriteStarIconRender,\n // filter: false,\n // suppressMenu: true,\n // width: 50,\n // resizable: true,\n // },\n\n {\n field: 'productThumbnail',\n fieldNameCamelCase: 'productThumbnail',\n width: 70,\n cellRenderer: customCellComponents.renderThumbnail,\n filter: false,\n resizable: false,\n allowSort: false,\n headerClass: 'header-text-hide',\n },\n {\n field: 'stateIcons',\n fieldNameCamelCase: 'stateIcons',\n headerName: 'States',\n minWidth: 150,\n cellRenderer: customCellComponents.renderIcons,\n filter: false,\n resizable: true,\n allowSort: false,\n headerClass: 'header-text-hide',\n },\n ];\n\n if (response?.columns?.length > 0) {\n response.columns.forEach((val) => {\n if (!DEFAULT_PRODUCT_COLUMNS.includes(val.fieldNameCamelCase)) {\n return;\n }\n\n const { dataType, fieldNameCamelCase } = val || {};\n\n if (dataType === 'datetime') {\n val = {\n ...val,\n minWidth: 150,\n cellRenderer: formatMDYWithParam,\n resizable: true,\n };\n } else {\n val = {\n ...val,\n minWidth: 150,\n resizable: true,\n };\n }\n\n if (fieldNameCamelCase === 'productName') {\n columns.splice(3, 0, {\n ...val,\n linkTo: '/product/{id}',\n minWidth: 300,\n });\n\n return;\n }\n\n // if (fieldNameCamelCase === 'sharedSupplierNames') {\n // val = {\n // ...val,\n // displayName: 'Supplier Name',\n // };\n // }\n\n if (fieldNameCamelCase === 'rivirId') {\n val = {\n ...val,\n displayName: 'RIVIR ID',\n };\n }\n\n if (fieldNameCamelCase === 'primarySizeUOM') {\n val = {\n ...val,\n minWidth: 150,\n cellRenderer: customCellComponents.renderPrimarySizeUOM,\n resizable: true,\n };\n }\n\n columns.push(val);\n });\n }\n\n return columns;\n};\n\nexport function* gridColumnInfo(payload) {\n try {\n const { response } = yield call(getColumnsFilter, payload);\n\n const columns = formatProductDetailColumns(response);\n\n yield put(actions.gridColumnInfoSuccess(columns));\n } catch (error) {\n yield put(actions.gridColumnInfoError(error));\n }\n}\n\nexport function* getColumnsFilter(payload) {\n const response = yield call(servicesGrid.gridColumnInfo, payload.gridName);\n // const filter = yield call(getFilter, response);\n return { response };\n}\n\nexport function* getFilter(response) {\n const filter = yield all(\n response.columns &&\n response.columns.length > 0 &&\n response.columns.map((val) => {\n return call(servicesMembers.getMemberContactDistinct, {\n memberId: 11,\n fieldName: val.fieldName,\n });\n })\n );\n return filter;\n}\n\nexport function* addProductSage(action) {\n try {\n const response = yield call(services.addProduct, action.params);\n\n if (response?.isSuccess) {\n yield put(actions.addProductSuccess(response?.data));\n } else {\n yield put(actions.addProductError(response?.message));\n }\n } catch (error) {\n yield put(actions.addProductError(error));\n }\n}\n\n// Get brand image on add product\nexport function* getProductBrandImageOnAddSaga(action) {\n try {\n const response = yield call(services.getProductBrandOnAdd, action.payload);\n const { isSuccess, data, message } = response;\n if (isSuccess) {\n yield put(actions.getProductBrandImageOnAddSuccess(data));\n } else {\n yield put(actions.getProductBrandImageOnAddError(message));\n }\n } catch (error) {\n yield put(actions.getProductBrandImageOnAddError('error'));\n }\n}\n\n// Get GDSN Party List\nexport function* getGDSNPartyListSaga(payload) {\n try {\n const { response } = yield call(getColumnsFilter, payload);\n let columns = [\n {\n filter: false,\n suppressMenu: true,\n resizable: true,\n checkboxSelection: true,\n },\n ];\n\n if (response?.columns?.length > 0) {\n let hiddenCol = ['partyCountryCode'];\n response.columns.forEach((val) => {\n if (hiddenCol.indexOf(val.fieldNameCamelCase) === -1) {\n // eslint-disable-next-line no-lone-blocks\n\n if (val.fieldNameCamelCase === 'PartyGln') {\n val = {\n ...val,\n width: 150,\n resizable: true,\n };\n } else {\n val = { ...val, width: 150, resizable: true };\n }\n if (val.fieldNameCamelCase === 'partyName') {\n val = {\n ...val,\n width: 150,\n resizable: true,\n };\n }\n if (val.fieldNameCamelCase === 'partyCountryName') {\n val = {\n ...val,\n minWidth: 150,\n flex: 1,\n resizable: true,\n };\n }\n\n columns.push(val);\n }\n });\n }\n\n yield put(actions.getGDSNPartyListSuccess(columns));\n } catch (error) {\n yield put(actions.getGDSNPartyListFailure(error));\n }\n}\n\n/**\n * Root saga manages watcher lifecycle\n */\nexport default function* watchProduct() {\n yield takeLatest(types.GET_PRODUCT_LIST, getProductList);\n yield takeLatest(types.GET_MEMBER_PRODUCT_LIST, getMemberProductListSaga);\n yield takeLatest(types.PRODUCT_GRID_COLUMN_INFO, gridColumnInfo);\n yield takeLatest(types.ADD_PRODUCT, addProductSage);\n yield takeLatest(\n types.GET_PRODUCT_BRAND_ON_ADD,\n getProductBrandImageOnAddSaga\n );\n yield takeLatest(types.GET_GDSN_PARTY_LIST, getGDSNPartyListSaga);\n}\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\nconst selectProduct = (state) => state.product || initialState;\n\nconst makeSelectLoading = () =>\n createSelector(selectProduct, (productState) => productState.loading);\nconst makeSelectProducts = () =>\n createSelector(selectProduct, (productState) => productState.products);\nconst makeSelectTotal = () =>\n createSelector(selectProduct, (productState) => productState.total);\nconst makeSelectPageSize = () =>\n createSelector(selectProduct, (productState) => productState.pageSize);\nconst makeSelectPageIndex = () =>\n createSelector(selectProduct, (productState) => productState.pageIndex);\nconst makeSelectSearch = () =>\n createSelector(selectProduct, (productState) => productState.search);\nconst makeSelectColumns = () =>\n createSelector(selectProduct, (productState) => productState.columns);\nconst makeSelectReloadGrid = () =>\n createSelector(selectProduct, (productState) => productState.reloadGrid);\n\nconst makeSelectGridConfig = () =>\n createSelector(selectProduct, (productState) => productState.gridConfig);\nconst makeSelectApplyGridConfig = () =>\n createSelector(selectProduct, (productState) => productState.applyGridConfig);\n\nconst makeSelectAddProductStatus = () =>\n createSelector(\n selectProduct,\n (productState) => productState.addProductStatus\n );\nconst makeSelectAddProductError = () =>\n createSelector(selectProduct, (productState) => productState.addProductError);\nconst makeSelectBrandImageOnAdd = () =>\n createSelector(selectProduct, (productState) => productState.brandImageOnAdd);\nconst makeSelectIsDisplayProductNew = () =>\n createSelector(\n selectProduct,\n (productState) => productState.isDisplayProductNew\n );\n\nconst makeSelectGDSNPartyList = () =>\n createSelector(selectProduct, (productState) => productState.GDSNPartyList);\n\nexport {\n selectProduct,\n makeSelectLoading,\n makeSelectProducts,\n makeSelectTotal,\n makeSelectPageSize,\n makeSelectPageIndex,\n makeSelectSearch,\n makeSelectColumns,\n makeSelectReloadGrid,\n makeSelectAddProductStatus,\n makeSelectAddProductError,\n makeSelectBrandImageOnAdd,\n makeSelectIsDisplayProductNew,\n makeSelectGDSNPartyList,\n makeSelectGridConfig,\n makeSelectApplyGridConfig,\n};\n","import { useEffect } from 'react';\n\nimport { useDispatch } from 'react-redux';\n\nimport { getDefaultGridConfig } from 'services/grid';\n\nimport { useAsync } from 'hooks';\n\nimport { saveGridConfig } from 'pages/branded-products/controllers/actions';\n\nimport { useApplyPreviewGridConfig } from 'pages/home/ribbon/components/sections/customize-grid';\n\nconst useGetDefaultGridConfig = ({ isEnabled }) => {\n const { data, run } = useAsync();\n const dispatch = useDispatch();\n\n const { isPreviewGridConfigAcive, applyGridConfig } =\n useApplyPreviewGridConfig();\n\n useEffect(() => {\n if (isEnabled) {\n run(getDefaultGridConfig('product-detail-grid'));\n }\n }, [isEnabled, run]);\n\n useEffect(() => {\n if (!isEnabled) return;\n\n if (!isPreviewGridConfigAcive) {\n if (data) {\n dispatch(\n saveGridConfig({\n jsonConfig: data.jsonConfig,\n selectedColumns: data.selectedColumns,\n isHaveDefaultConfig: true,\n })\n );\n }\n } else {\n dispatch(\n saveGridConfig({\n jsonConfig: applyGridConfig?.jsonConfig,\n selectedColumns: applyGridConfig?.selectedColumns,\n })\n );\n }\n }, [data, dispatch, isEnabled, applyGridConfig, isPreviewGridConfigAcive]);\n};\n\nexport default useGetDefaultGridConfig;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { forwardTo } from 'utils/common/route';\nimport { ThumbnailItem } from 'common/components';\n\nimport * as getLink from 'utils/common/linkBuilder';\n\nimport AssetReport from 'assets/reporting/AssetReport.png';\nimport ProductReport from 'assets/reporting/ProductReport.png';\nimport MemberReport from 'assets/reporting/MemberReport.png';\n\nimport FolderDownloadScheduledIcon from 'pages/folders/components/icons/FolderDownloadScheduledIcon';\n\nconst ReportingThumbnail = (props) => {\n const {\n dataDetail,\n selected,\n onClickItemGrid,\n onClickCheckboxItem,\n pathname,\n } = props;\n\n const onDoubleClick = (item) => {\n const { id } = item;\n forwardTo(`${pathname}/${id}`);\n };\n\n const image =\n (dataDetail?.advType === 'DigitalMedia' && AssetReport) ||\n (dataDetail?.advType === 'Member' && MemberReport) ||\n (dataDetail?.advType === 'ProductItem' && ProductReport);\n\n const aLink = getLink.reportingLink(dataDetail?.id, dataDetail?.name);\n\n const status = dataDetail?.isBasicMode ? 'Basic Report' : null;\n\n const DownloadSchedule = FolderDownloadScheduledIcon;\n return (\n ]}\n />\n );\n};\n\nReportingThumbnail.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default React.memo(ReportingThumbnail);\n","import React from 'react';\nimport { Typography, Space, Row } from 'antd';\nimport { get } from 'lodash';\nimport PropTypes from 'prop-types';\nimport { FormattedMessage } from 'react-intl';\nimport EntityStatusTag from 'common/components/tag/entity-status-tag/EntityStatusTag';\nimport Messages from 'i18n/messages/folder';\nimport { formatSizeUnits } from 'utils/formatSizeUnits';\n// import { aDetailsLink } from 'utils/common/linkBuilder';\n\nconst { Paragraph, Title, Text } = Typography;\n\nconst ReportingTileBody = (props) => {\n const { dataDetail } = props;\n\n const name = get(dataDetail, 'name', '');\n const ownerName = get(dataDetail, 'ownerFullName', '');\n\n const infoText = [\n {\n field: 'name',\n value: name,\n },\n {\n field: 'ownerName',\n value: ownerName,\n },\n ];\n // const detailLink = aDetailsLink(\n // 'reporting',\n // dataDetail?.id,\n // dataDetail?.name\n // );\n const renderReportingBodyInfo = (infoText) => {\n return infoText.map(({ field, value }, index) => {\n if (field === 'name') {\n return (\n \n {dataDetail?.name}\n \n );\n } else if (field === 'folderSize') {\n return (\n \n {formatSizeUnits(value)}\n \n );\n } else if (field === 'productCount' || field === 'assetCount') {\n let text;\n if (field === 'productCount') {\n text =\n value > 0 ? (\n \n ) : (\n \n );\n } else {\n text =\n value > 0 ? (\n \n ) : (\n \n );\n }\n return value > 0 ? (\n \n {value} {text}\n \n ) : null;\n } else {\n return (\n value && (\n \n {value}\n \n )\n );\n }\n });\n };\n\n return (\n
\n \n \n {renderReportingBodyInfo(infoText)}\n \n \n \n \n \n
\n );\n};\n\nReportingTileBody.propTypes = {\n dataDetail: PropTypes.object,\n};\n\nexport default ReportingTileBody;\n","import React from 'react';\nimport { Row, Col } from 'antd';\n\nimport { formatMDY } from 'utils/formatDate';\nimport { get } from 'lodash';\nimport PropTypes from 'prop-types';\nimport { FormattedMessage } from 'react-intl';\nimport Messages from 'i18n/messages/folder';\n\nconst ReportingTileFooter = (props) => {\n const { dataDetail } = props;\n\n const dateCreated = get(dataDetail, 'created', '');\n const lastUpdated = get(dataDetail, 'lastModified', '');\n\n return (\n \n \n \n \n \n \n {dateCreated && formatMDY(dateCreated)}\n \n \n \n \n \n {lastUpdated && formatMDY(lastUpdated)}\n \n \n \n );\n};\n\nReportingTileFooter.propTypes = {\n size: PropTypes.string,\n lastUpdate: PropTypes.string,\n};\n\nexport default ReportingTileFooter;\n","import React from 'react';\nimport { useSelector } from 'react-redux';\nimport { Row, Avatar } from 'antd';\nimport PropTypes from 'prop-types';\nimport userSelectors from '@redux/user/selectors';\n\nimport AssetReport from 'assets/reporting/AssetReport.png';\nimport ProductReport from 'assets/reporting/ProductReport.png';\nimport MemberReport from 'assets/reporting/MemberReport.png';\n\nconst ReportingTileHeader = (props) => {\n const { dataDetail } = props;\n const userId = useSelector(userSelectors.makeSelectUserId());\n const image =\n (dataDetail?.advType === 'DigitalMedia' && AssetReport) ||\n (dataDetail?.advType === 'Member' && MemberReport) ||\n (dataDetail?.advType === 'ProductItem' && ProductReport);\n\n return (\n \n
\n\n
\n \n
\n
\n );\n};\n\nReportingTileHeader.propTypes = {\n dataDetail: PropTypes.object,\n};\n\nexport default ReportingTileHeader;\n","import React from 'react';\nimport { Tooltip } from 'antd';\nimport {\n ReportingTileBody,\n ReportingTileFooter,\n ReportingTileHeader,\n} from '../index';\nimport { get } from 'lodash';\nimport useDoubleClick from 'hooks/useDoubleClick';\nimport './ReportingTile.less';\n\nconst ReportingTile = (props) => {\n const { dataDetail, disableEvent } = props;\n const { onClickItemGrid, onDoubleClick } = props.clickEvents;\n const name = get(dataDetail, 'name', '');\n\n const divRef = React.useRef();\n useDoubleClick({\n onSingleClick: (e) => {\n if (onClickItemGrid) onClickItemGrid(dataDetail, e);\n },\n onDoubleClick: (e) => {\n if (onDoubleClick) onDoubleClick(dataDetail);\n },\n ref: divRef,\n latency: 250,\n });\n\n return (\n \n
\n {/*Placeholder for click events*/}\n \n \n \n \n
\n
\n );\n};\n\nexport default ReportingTile;\n","import React, { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Image, Typography } from 'antd';\n\nimport AssetReport from 'assets/reporting/AssetReport.png';\nimport MemberReport from 'assets/reporting/MemberReport.png';\nimport ProductReport from 'assets/reporting/ProductReport.png';\n\nimport { InfoWithLabel } from 'common/components';\nimport { formatMDY } from 'utils/formatDate';\n\nimport AdvancedSearchTitle from 'common/components/advanced-search/AdvancedSearchTitle';\nimport { DragDropContext } from 'react-beautiful-dnd';\n\nimport PropertyAdvancedFilter from 'common/components/grid-view/components/content-pane/advancedFilter/PropertyAdvancedFilter';\nimport QueryConditions from 'common/components/grid-view/components/content-pane/advancedFilter/QueryConditions';\nimport DataColumns from 'pages/reporting/components/DataColumns';\nimport {\n changeValueDataType,\n mappingPrimaryToFieldsName,\n} from 'pages/reporting/utils';\nimport { useAdvanceFilter } from 'common/components/nested-advance-Search/hook/hook';\nimport { isJson } from 'utils/string';\n\nimport './ReportingPanel.less';\n\nconst infoColProps = {\n infoColProps: {\n flex: 'auto',\n },\n labelColProps: {\n flex: '130px',\n },\n boldInfo: true,\n labelAlign: 'right',\n};\n\nconst ReportingPanel = ({ dataDetail }) => {\n const image =\n (dataDetail?.advType === 'DigitalMedia' && AssetReport) ||\n (dataDetail?.advType === 'Member' && MemberReport) ||\n (dataDetail?.advType === 'ProductItem' && ProductReport);\n\n const [propertiesData, setPropertiesData] = useState();\n const { fetchEntityAttribute } = useAdvanceFilter({});\n\n const decodeJson = isJson(dataDetail?.query)\n ? JSON.parse(dataDetail?.query)\n : {};\n\n const query = mappingPrimaryToFieldsName(decodeJson);\n\n const entityType = changeValueDataType(dataDetail?.advType);\n\n const handleGetEntity = async () => {\n try {\n const data = await fetchEntityAttribute(entityType);\n if (data) {\n setPropertiesData(data);\n }\n } catch (error) {\n console.log(error);\n }\n };\n\n useEffect(() => {\n if (!propertiesData) handleGetEntity();\n }, [entityType, propertiesData]);\n\n return (\n \n \n \n \n \n \n \n {/* */}\n {dataDetail?.name}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nReportingPanel.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default ReportingPanel;\n","import { useQuery, useQueryClient } from '@tanstack/react-query';\nimport { getLinkIframeCard } from 'services/payment';\nimport { CustomNotification } from 'common/components';\n\nconst keys = {\n addCreditCardIframeUrl: ['payment', 'add-card'],\n getBillingProperties: (memberId) => [\n 'payment',\n 'get-member-billing-properties',\n { params: { memberId: parseInt(memberId) } },\n ],\n};\n\n/**\n *? GET\n *? /api/payment/add-card\n */\nconst useQueryAddCreditCardIframeUrl = ({ memberId, ...options }) => {\n return useQuery({\n queryKey: keys.addCreditCardIframeUrl,\n queryFn: async () => {\n const res = await getLinkIframeCard({\n memberId,\n paymentEndpointType: null,\n });\n\n const { isSuccess, message, data } = res || {};\n\n if (!isSuccess) {\n CustomNotification.error(message || 'Server Error');\n }\n\n return data;\n },\n ...options,\n });\n};\n\n/**\n *? GET\n *? /api/payment/get-member-billing-properties\n */\nconst useQueryBillingProperties = ({ memberId, ...options }) => {\n const queryClient = useQueryClient();\n\n const query = useQuery({\n queryKey: keys.getBillingProperties(memberId),\n enabled: Boolean(memberId),\n ...options,\n });\n\n const invalidateBillingProperties = () => {\n queryClient.invalidateQueries({\n queryKey: keys.getBillingProperties(memberId),\n });\n };\n\n return {\n billingProperties: query?.data ?? {},\n invalidateBillingProperties,\n ...query,\n };\n};\n\nexport { useQueryAddCreditCardIframeUrl, useQueryBillingProperties };\n","import * as types from './constants';\n\nexport const getCommunicationTemplates = (pageSize, pageNumber, search) => {\n return {\n type: types.GET_COMMUNICATION_TEMPLATES,\n pageSize: pageSize,\n pageIndex: pageNumber,\n 'Search.SearchText': search,\n };\n};\n\nexport const getCommunicationTemplatesSuccess = (templates, paging) => {\n return {\n type: types.GET_COMMUNICATION_TEMPLATES_SUCCESS,\n templates,\n paging,\n };\n};\n\nexport const getCommunicationTemplatesError = (error) => {\n return {\n type: types.GET_COMMUNICATION_TEMPLATES_ERROR,\n error,\n };\n};\n\nexport const getCommunicationTemplatesGridColumns = (gridName) => ({\n type: types.GET_COMMUNICATION_TEMPLATES_COLUMNS,\n gridName,\n});\n\nexport const getCommunicationTemplatesGridColumnsSuccess = (columns) => ({\n type: types.GET_COMMUNICATION_TEMPLATES_COLUMNS_SUCCESS,\n columns,\n});\n\nexport const getCommunicationTemplatesGridColumnsError = (error) => ({\n type: types.GET_COMMUNICATION_TEMPLATES_COLUMNS_ERROR,\n error,\n});\n\nexport const enableCreateMode = () => {\n return {\n type: types.ENABLE_CREATE_TEMPLATE,\n };\n};\n\nexport const enableEditMode = () => {\n return {\n type: types.ENABLE_EDIT_TEMPLATE,\n };\n};\n\nexport const resetTemplate = () => {\n return {\n type: types.RESET_TEMPLATE,\n };\n};\n\nexport const saveIdTemplate = (id) => {\n return {\n type: types.SAVE_ID_TEMPLATE,\n id,\n };\n};\n\nexport const enableSaveTemplate = () => {\n return {\n type: types.ENABLE_SAVE_TEMPLATE,\n };\n};\n\nexport const unableSaveTemplate = () => {\n return {\n type: types.UNABLE_SAVE_TEMPLATE,\n };\n};\n\nexport const disableUploadMedia = (status) => {\n return {\n type: types.DISABLE_UPLOAD_MEDIA,\n status,\n };\n};\n","export const GET_COMMUNICATION_TEMPLATES = 'GET_COMMUNICATION_TEMPLATES';\nexport const GET_COMMUNICATION_TEMPLATES_SUCCESS =\n 'GET_COMMUNICATION_TEMPLATES_SUCCESS';\nexport const GET_COMMUNICATION_TEMPLATES_ERROR =\n 'GET_COMMUNICATION_TEMPLATES_ERROR';\n\nexport const GET_COMMUNICATION_TEMPLATES_COLUMNS =\n 'GET_COMMUNICATION_TEMPLATES_COLUMNS';\nexport const GET_COMMUNICATION_TEMPLATES_COLUMNS_SUCCESS =\n 'GET_COMMUNICATION_TEMPLATES_COLUMNS_SUCCESS';\nexport const GET_COMMUNICATION_TEMPLATES_COLUMNS_ERROR =\n 'GET_COMMUNICATION_TEMPLATES_COLUMNS_ERROR';\n\nexport const ENABLE_CREATE_TEMPLATE = 'ENABLE_CREATE_TEMPLATE';\nexport const ENABLE_EDIT_TEMPLATE = 'ENABLE_EDIT_TEMPLATE';\nexport const RESET_TEMPLATE = 'RESET_TEMPLATE';\nexport const SAVE_ID_TEMPLATE = 'SAVE_ID_TEMPLATE';\nexport const ENABLE_SAVE_TEMPLATE = 'ENABLE_SAVE_TEMPLATE';\nexport const UNABLE_SAVE_TEMPLATE = 'UNABLE_SAVE_TEMPLATE';\nexport const DISABLE_UPLOAD_MEDIA = 'DISABLE_UPLOAD_MEDIA';\n","import produce from 'immer';\nimport * as types from './constants';\n\nexport const initialState = {\n loading: false,\n paging: {\n pageSize: 20,\n pageNumber: 1,\n total: 0,\n },\n columns: [],\n communications: [],\n mode: {\n isCreate: false,\n isEdit: false,\n },\n idTemplate: null,\n isToggleSave: false,\n disableUploadMedia: false,\n error: null,\n};\n\nconst communicationsReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_COMMUNICATION_TEMPLATES_COLUMNS:\n draft.loading = true;\n break;\n\n case types.GET_COMMUNICATION_TEMPLATES_COLUMNS_SUCCESS:\n draft.loading = false;\n draft.columns = action.columns;\n break;\n\n case types.GET_COMMUNICATION_TEMPLATES_COLUMNS_ERROR:\n draft.loading = false;\n draft.columns = [];\n draft.error = action.error;\n break;\n\n case types.GET_COMMUNICATION_TEMPLATES:\n draft.loading = true;\n draft.error = false;\n break;\n\n case types.GET_COMMUNICATION_TEMPLATES_SUCCESS:\n draft.loading = false;\n draft.communications = action.communications;\n draft['paging'].pageSize = action.paging.currentPageSize;\n draft['paging'].pageNumber = action.paging.currentPageIndex;\n draft['paging'].total = action.paging.totalRecord;\n break;\n\n case types.GET_COMMUNICATION_TEMPLATES_ERROR:\n draft.loading = false;\n draft['paging'].total = 0;\n draft.communications = [];\n draft.error = action.error;\n break;\n\n case types.ENABLE_CREATE_TEMPLATE:\n draft['mode'].isCreate = true;\n draft['mode'].isEdit = false;\n break;\n\n case types.ENABLE_EDIT_TEMPLATE:\n draft['mode'].isEdit = true;\n draft['mode'].isCreate = false;\n break;\n\n case types.RESET_TEMPLATE:\n draft['mode'].isEdit = false;\n draft['mode'].isCreate = false;\n draft.idTemplate = null;\n draft.isToggleSave = false;\n break;\n\n case types.SAVE_ID_TEMPLATE:\n draft.idTemplate = action.id;\n break;\n\n case types.ENABLE_SAVE_TEMPLATE:\n draft.isToggleSave = true;\n break;\n\n case types.UNABLE_SAVE_TEMPLATE:\n draft.isToggleSave = false;\n break;\n\n case types.DISABLE_UPLOAD_MEDIA:\n draft.disableUploadMedia = action.status;\n break;\n\n default:\n break;\n }\n });\n\nexport default communicationsReducer;\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\nconst selectCommunications = (state) => state.communications || initialState;\n\nconst selectLoading = () =>\n createSelector(\n selectCommunications,\n (communicationsState) => communicationsState.loading\n );\n\nconst selectColumns = () =>\n createSelector(\n selectCommunications,\n (communicationsState) => communicationsState.columns\n );\n\nconst selectPaging = () =>\n createSelector(\n selectCommunications,\n (communicationsState) => communicationsState.paging\n );\n\nconst selectCommunicationList = () =>\n createSelector(\n selectCommunications,\n (communicationsState) => communicationsState.communications\n );\n\nconst selectCommunicationMode = () =>\n createSelector(\n selectCommunications,\n (communicationsState) => communicationsState.mode\n );\n\nconst selectToggleSaveTemplate = () =>\n createSelector(\n selectCommunications,\n (communicationsState) => communicationsState.isToggleSave\n );\n\nconst selectIdTemplate = () =>\n createSelector(\n selectCommunications,\n (communicationsState) => communicationsState.idTemplate\n );\n\nconst selectDisableUploadMedia = () =>\n createSelector(\n selectCommunications,\n (communicationsState) => communicationsState.disableUploadMedia\n );\n\nexport {\n selectLoading,\n selectColumns,\n selectPaging,\n selectCommunicationList,\n selectCommunicationMode,\n selectToggleSaveTemplate,\n selectIdTemplate,\n selectDisableUploadMedia,\n};\n","import React, { useEffect, useState, useRef } from 'react';\nimport { useDispatch } from 'react-redux';\nimport PropTypes from 'prop-types';\nimport { Input, Select, Typography } from 'antd';\nimport { LoadingOutlined } from '@ant-design/icons';\n\nimport { FormattedMessage, injectIntl } from 'react-intl';\nimport classnames from 'classnames';\n\n//* COMPONENTS\nimport { locationTypeIcon } from 'common/components/icon-renderer/IconRendererMapping';\nimport {\n Form,\n CustomNotification,\n StyledModal,\n WrapperSelect,\n FlagCountrySelectionFieldInput,\n} from 'common/components';\n\n//* SERVICES\nimport * as memberServices from 'services/members';\nimport * as companyActions from 'pages/company-profile/controllers/actions';\nimport Messages from 'i18n/messages/message-my-company';\n\n//* UTILS\nimport { searchCountryCode } from 'utils/country';\nimport CountryCode from 'static/CountryCode';\n\nimport './CompanyLocationForm.less';\n\nconst { Option } = Select;\nconst { Text } = Typography;\nconst { TextArea } = Input;\n\nconst CompanyLocationForm = (props) => {\n const {\n isOpen,\n isAddNew,\n setIsOpen,\n itemData,\n intl,\n gridApi,\n memberId,\n type,\n onSubmit,\n } = props;\n\n const [formInstance] = Form.useForm();\n const [isLoading, setIsLoading] = useState(false);\n\n const dispatch = useDispatch();\n\n const refCountry = useRef(null);\n\n const handleSubmitForm = async () => {\n try {\n const formValue = await formInstance.validateFields();\n\n if (onSubmit) {\n return onSubmit({ formValue, setIsLoading });\n }\n\n setIsLoading(true);\n\n const response = isAddNew\n ? await memberServices.addMyCompanyLocation({\n memberId,\n ...formValue,\n })\n : await memberServices.updateMyCompanyLocation({\n id: itemData?.id,\n memberId,\n ...formValue,\n });\n\n setIsLoading(false);\n\n if (response?.isSuccess) {\n CustomNotification.success(\n intl.formatMessage(\n isAddNew\n ? Messages.msgLocationCreateSuccess\n : Messages.msgLocationUpdateSuccess\n )\n );\n gridApi?.rivirPurgeServerSideCache();\n dispatch(companyActions.getMemberProfileHeader(memberId));\n setIsOpen(false);\n } else {\n CustomNotification.error(\n response?.message ||\n intl.formatMessage(Messages.msgLocationUpdateFail)\n );\n }\n } catch (error) {\n setIsLoading(false);\n\n if (error?.errorFields) {\n formInstance.scrollToField(error?.errorFields[0].name[0]);\n CustomNotification.error(intl.formatMessage(Messages.msgInvalidFields));\n } else {\n CustomNotification.error(intl.formatMessage(Messages.msgExcepEdit));\n }\n }\n };\n\n useEffect(() => {\n //* set form Data to edit\n const setInitFormDataForEdit = async () => {\n if (isOpen && itemData?.id && !isAddNew) {\n setIsLoading(true);\n const response = await memberServices.getCompanyLocationDetail(\n itemData?.id\n );\n setIsLoading(false);\n\n if (response?.isSuccess) {\n formInstance.setFieldsValue(response?.data);\n refCountry &&\n refCountry.current &&\n refCountry.current.updateSelected(\n searchCountryCode(response.data?.country)\n );\n } else {\n CustomNotification.error('Failed to get contact detail info');\n }\n }\n };\n\n setInitFormDataForEdit();\n }, [isOpen, itemData, isAddNew]);\n\n return (\n \n \n ) : (\n \n )\n }\n visible={isOpen || isAddNew}\n onOk={handleSubmitForm}\n onCancel={() => setIsOpen(false)}\n okText={\n isLoading ? (\n \n \n \n \n \n \n ) : (\n \n )\n }\n cancelText={}\n maskClosable={false}\n destroyOnClose\n >\n \n \n \n );\n};\n\n/**\n * ! SUB COMPONENT - company location form content\n * @param {*} props\n * @returns\n */\nconst CompanyLocationFormBody = injectIntl((props) => {\n const { formInstance, intl, isLoading, refCountry, type } = props;\n\n useEffect(() => {\n return () => {\n formInstance.resetFields();\n formInstance.setFieldsValue({\n addressType: type ? type : null,\n country: CountryCode['US'],\n });\n };\n }, []);\n\n useEffect(() => {\n formInstance.setFieldsValue({\n addressType: type ? type : null,\n });\n }, [type]);\n\n return (\n \n }\n rules={[\n {\n required: true,\n message: 'Type is required',\n },\n ]}\n >\n \n document.getElementById('company-location-edit-form')\n }\n placeholder={intl.formatMessage(Messages.placeHolderLocationType)}\n disabled={!!type}\n >\n {locationTypeIcon.map((locationIconItem) => (\n \n \n {locationIconItem.label}\n \n ))}\n \n \n }\n rules={[\n {\n required: true,\n message: 'Address is required',\n },\n ]}\n >\n \n \n }\n rules={[\n {\n required: true,\n message: 'City is required',\n },\n ]}\n >\n \n \n }\n >\n \n \n }\n >\n {\n formInstance.setFieldsValue({\n ...formInstance.getFieldsValue(),\n country: CountryCode[value],\n });\n }}\n ref={refCountry}\n defaultCountry='US'\n />\n \n ({\n validator(rule, value) {\n const regex = /^\\d{5}[-\\s]?(?:\\d{4})?$/gm;\n if (regex.exec(value) || !value) {\n return Promise.resolve();\n } else {\n return Promise.reject('Invalid Zipcode');\n }\n },\n }),\n ]}\n >\n \n \n }\n rules={[\n {\n required: true,\n message: 'Location Name is required',\n },\n ]}\n >\n \n \n }\n >\n \n \n \n \n \n }\n >\n \n \n \n \n \n }\n >\n \n \n }\n >\n \n \n }\n rules={[{ type: 'email', message: 'Invalid Email' }]}\n >\n \n \n\n {/* BP 12/28/2020 - remove latitude and longitude fields\n {isAddNew && (\n <>\n ({\n validator(rule, value) {\n const regex = /^(\\+|-)?(?:90(?:(?:\\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\\.[0-9]{1,6})?))$/;\n if (regex.exec(value)) {\n return Promise.resolve();\n } else {\n return Promise.reject('Invalid Latitude');\n }\n },\n }),\n ]}\n >\n }\n placeholder={intl.formatMessage(\n Messages.placeHolderLatitude\n )}\n />\n \n }\n rules={[\n () => ({\n validator(rule, value) {\n const regex = /^(\\+|-)?(?:180(?:(?:\\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\\.[0-9]{1,6})?))$/;\n if (regex.exec(value)) {\n return Promise.resolve();\n } else {\n return Promise.reject('Invalid Longitude');\n }\n },\n }),\n ]}\n >\n \n \n \n )} */}\n \n );\n});\n\nCompanyLocationForm.propTypes = {\n isOpen: PropTypes.bool,\n isAddNew: PropTypes.bool,\n setIsOpen: PropTypes.func,\n itemData: PropTypes.object,\n};\n\nexport default injectIntl(CompanyLocationForm);\n","import React from 'react';\nimport { Tag, Tooltip } from 'antd';\nimport * as IconListArray from 'common/components/icon-list/assets';\nimport {\n languageCode,\n currencyData,\n legalEntityType,\n targetMarketCountryCode,\n ownershipType,\n statusType,\n} from 'static/CountryCode';\n\nexport const fiscalYearStartDateFormat = 'MM/DD';\n\nconst IconListName = IconListArray.default;\n\nconst tagRender = (props) => {\n const { value, closable, onClose } = props;\n const src = IconListName.filter((val) => val.segmentId === value);\n return (\n \n \n \n \n \n );\n};\n\nconst getClassificationsOptions = () => {\n return IconListName.map((val) => {\n return {\n label: val.segmentDescription,\n value: val.segmentId,\n icon: val.segmentIcon,\n };\n });\n};\n\nconst getCountryOptions = () => {\n return Object.values(targetMarketCountryCode)\n ?.slice()\n .sort()\n .map((country) => {\n return {\n label: country,\n value: country,\n };\n });\n};\n\nconst getLanguageOptions = () => {\n return languageCode\n ?.slice()\n .sort()\n .map((language) => {\n return {\n label: language,\n value: language,\n };\n });\n};\n\nconst getCurrencyOptions = () => {\n return Object.keys(currencyData).map((currencyCode) => {\n return {\n label: `(${currencyCode}) ${currencyData[currencyCode]}`,\n value: currencyCode,\n };\n });\n};\n\nconst getLegalEntityTypesOptions = () => {\n return legalEntityType.map((type) => ({\n label: type,\n value: type,\n }));\n};\n\nconst getOwnershipTypeOptions = () => {\n return ownershipType.map((type) => ({\n label: type,\n value: type,\n }));\n};\n\nexport const getStatusTypesOptions = () => {\n return statusType.map((type) => ({\n label: type,\n value: type,\n }));\n};\n\nconst editFormSchema = [\n {\n name: 'dba',\n label: 'dbaLabel',\n type: 'text',\n },\n {\n name: 'legalEntityType',\n label: 'legalEntityTypeLabel',\n type: 'select',\n options: getLegalEntityTypesOptions(),\n },\n {\n name: 'status',\n label: 'statusLabel',\n type: 'select',\n options: getStatusTypesOptions(),\n },\n {\n name: 'headquartersCountry',\n label: 'headquartersCountryLabel',\n type: 'selectEnum',\n showSearch: true,\n options: getCountryOptions(),\n enumName: 'CountryCode3166Enum',\n },\n {\n name: 'stateOfIncorporation',\n label: 'incorporationStateLabel',\n type: 'custom',\n },\n {\n name: 'currency',\n label: 'currencyLabel',\n type: 'selectEnum',\n showSearch: true,\n options: getCurrencyOptions(),\n enumName: 'CurrencyCodeISO4217Enum',\n },\n {\n name: 'primaryLanguage',\n label: 'languageLabel',\n type: 'selectEnum',\n showSearch: true,\n options: getLanguageOptions(),\n enumName: 'LanguageCodeISO639_1Enum',\n },\n // {\n // name: 'gln',\n // label: 'glnLabel',\n // type: 'text',\n // },\n {\n name: 'duns',\n label: 'dunsLabel',\n type: 'text',\n },\n {\n name: 'stockSymbol',\n label: 'stockSymbolLabel',\n type: 'text',\n },\n {\n name: 'sicCode',\n label: 'sicCodeLabel',\n type: 'text',\n },\n {\n name: 'naicsCode',\n label: 'naicsLabel',\n type: 'text',\n },\n {\n name: 'annualRevenue',\n label: 'annualRevenueLabel',\n type: 'text',\n },\n {\n name: 'representedSales',\n label: 'representedSalesLabel',\n type: 'text',\n },\n {\n name: 'minorityOwnedType',\n label: 'minorityOwnedTypeLabel',\n type: 'select',\n mode: 'multiple',\n options: [\n {\n label: 'Minority Owned Business Certifications',\n value: 'Minority Owned Business Certifications',\n },\n {\n label: '8(a) Business Development Program',\n value: '8(a) Business Development Program',\n },\n {\n label: 'Asian-Indian',\n value: 'Asian-Indian',\n },\n {\n label: 'Certified B Corp',\n value: 'Certified B Corp',\n },\n {\n label: 'Non Profit',\n value: 'Non Profit',\n },\n {\n label: 'Asian-Pacific American',\n value: 'Asian-Pacific American',\n },\n {\n label: 'Not for Profit',\n value: 'Not for Profit',\n },\n {\n label: 'DOBE (Disability-Owned Business Enterprise)',\n value: 'DOBE (Disability-Owned Business Enterprise)',\n },\n {\n label: 'African American',\n value: 'African American',\n },\n {\n label: 'LGBTBE (LGBT-Owned Business Enterprise)',\n value: 'LGBTBE (LGBT-Owned Business Enterprise)',\n },\n {\n label: 'Small Business (SBA / SBE)',\n value: 'Small Business (SBA / SBE)',\n },\n {\n label: 'DBE (Disadvantaged Business Enterprise)',\n value: 'DBE (Disadvantaged Business Enterprise)',\n },\n {\n label: 'WOSB (Women Owned Small Business)',\n value: 'WOSB (Women Owned Small Business)',\n },\n {\n label: 'NMSDC Certified (Ethnic Minority Owned)',\n value: 'NMSDC Certified (Ethnic Minority Owned)',\n },\n {\n label: 'Hispanic American',\n value: 'Hispanic American',\n },\n {\n label: 'Women Owned',\n value: 'Women Owned',\n },\n {\n label: 'Military Veteran-Owned',\n value: 'Military Veteran-Owned',\n },\n {\n label: 'State Certified Minority Owned',\n value: 'State Certified Minority Owned',\n },\n {\n label: 'VOSB (Veteran Owned Small Business)',\n value: 'VOSB (Veteran Owned Small Business)',\n },\n {\n label: 'Historically Underutilized Business (HUB)',\n value: 'Historically Underutilized Business (HUB)',\n },\n {\n label: 'Latin American',\n value: 'Latin American',\n },\n {\n label: 'MBE (Minority Business Enterprise)',\n value: 'MBE (Minority Business Enterprise)',\n },\n {\n label: 'Native American',\n value: 'Native American',\n },\n {\n label: 'NOD Leading Disability Employer',\n value: 'NOD Leading Disability Employer',\n },\n {\n label: 'Small & Disadvantaged Business',\n value: 'Small & Disadvantaged Business',\n },\n {\n label: 'Other Diversity Based Certification',\n value: 'Other Diversity Based Certification',\n },\n {\n label: 'GEEIS (Gender Equality European & International Standard)',\n value: 'GEEIS (Gender Equality European & International Standard)',\n },\n {\n label: 'SDVOSB (Service-Disabled Veteran-Owned Small Business)',\n value: 'SDVOSB (Service-Disabled Veteran-Owned Small Business)',\n },\n {\n label: 'EDWOSB (Economically Disadvantaged Woman-Owned Small Business)',\n value: 'EDWOSB (Economically Disadvantaged Woman-Owned Small Business)',\n },\n {\n label: 'WBENC (Womans Business Enterprise National Council)',\n value: 'WBENC (Womans Business Enterprise National Council)',\n },\n {\n label: 'NaVOBA (National Veteran-Owned Business Association)',\n value: 'NaVOBA (National Veteran-Owned Business Association)',\n },\n ],\n },\n {\n name: 'ownershipType',\n label: 'ownershipTypeLabel',\n type: 'select',\n options: getOwnershipTypeOptions(),\n },\n {\n name: 'contractPackaging',\n label: 'contractPackagingLabel',\n type: 'checkbox',\n },\n {\n name: 'minorityOwned',\n label: 'minorityOwnedLabel',\n type: 'checkbox',\n },\n {\n name: 'bCorp',\n label: 'bCorpLabel',\n type: 'checkbox',\n },\n {\n name: 'coOp',\n label: 'coOpLabel',\n type: 'checkbox',\n },\n {\n name: 'coOp50',\n label: 'coOp50Label',\n type: 'checkbox',\n },\n {\n name: 'coPacker',\n label: 'coPackerLabel',\n type: 'checkbox',\n },\n {\n name: 'fiscalYearStartDate',\n label: 'fiscalYearStartDateLabel',\n type: 'datePicker',\n dateFormat: fiscalYearStartDateFormat,\n },\n {\n name: 'numberOfEmployees',\n label: 'numberOfEmployeesLabel',\n type: 'number',\n min: 0,\n },\n {\n name: 'numberOfCustomers',\n label: 'numberOfCustomersLabel',\n type: 'number',\n min: 0,\n },\n {\n name: 'customers',\n label: 'customersLabel',\n type: 'select',\n mode: 'tags',\n },\n {\n name: 'classifications',\n label: 'majorIndustryClassificationsLabel',\n type: 'select',\n mode: 'multiple',\n tagRender: tagRender,\n options: getClassificationsOptions(),\n fullWidth: true,\n },\n {\n name: 'productCapabilities',\n label: 'productCapabilitiesLabel',\n type: 'text',\n },\n {\n name: 'productionCapabilities',\n label: 'productionCapabilitiesLabel',\n type: 'text',\n },\n {\n name: 'marketRegions',\n label: 'marketRegionsLabel',\n type: 'select',\n mode: 'tags',\n },\n {\n name: 'produceNationalBrands',\n label: 'produceNationalBrandsLabel',\n type: 'checkbox',\n },\n {\n name: 'exportRegions',\n label: 'exportRegionsLabel',\n type: 'select',\n mode: 'tags',\n },\n {\n name: 'exportPercentage',\n label: 'exportPercentageLabel',\n type: 'number',\n min: 0,\n format: '%',\n },\n {\n name: 'exportCountries',\n label: 'exportCountriesLabel',\n type: 'select',\n mode: 'multiple',\n options: getCountryOptions(),\n placement: 'topLeft',\n },\n {\n name: 'certifications',\n label: 'certificationsLabel',\n type: 'custom',\n },\n {\n name: 'privateLabel',\n label: 'privateLabelLabel',\n type: 'checkbox',\n },\n {\n name: 'privateLabelBusinessPercentage',\n label: 'privateLabelBusinessPercentageLabel',\n type: 'number',\n format: '%',\n min: 0,\n },\n {\n name: 'privateLabelClassifications',\n label: 'privateLabelClassificationsLabel',\n type: 'select',\n mode: 'multiple',\n tagRender: tagRender,\n options: getClassificationsOptions(),\n fullWidth: true,\n placement: 'topLeft',\n filterOption: (input, option) => {\n return (option?.label?.toLowerCase() ?? '').includes(\n input?.toLowerCase()\n );\n },\n },\n {\n name: 'autoSendAcceptCic',\n label: 'autoSendAcceptCicLabel',\n type: 'checkbox',\n },\n // {\n // name: 'fiscalYearStartDate',\n // label: 'fiscalYearStartDateLabel',\n // type: 'datePicker',\n // dateFormat: fiscalYearStartDateFormat,\n // },\n // {\n // name: 'fiscalYearStartDate',\n // label: 'fiscalYearStartDateLabel',\n // type: 'datePicker',\n // dateFormat: fiscalYearStartDateFormat,\n // },\n];\n\nexport default editFormSchema;\n","import React from 'react';\nimport { Form, Input, Typography } from 'antd';\nimport {\n CATEGORY_FORM_ITEM_INPUT,\n CATEGORY_LEVEL_1,\n CATEGORY_LEVEL_2,\n CATEGORY_LEVEL_3,\n CATEGORY_LEVEL_4,\n} from 'pages/company-profile/components/tabs/system/category-management/constant';\nimport {\n checkEmptyChildCategoryInAddMode,\n resetFieldError,\n} from 'pages/company-profile/components/tabs/system/category-management/utils';\n\nimport './ProductCategoryForm.less';\n\nconst { Text } = Typography;\n\nconst ProductCategoryForm = ({\n mode,\n formName,\n getMap,\n nodeSelected,\n disableForm,\n}) => {\n const form = Form.useFormInstance();\n const isModeNullOrBulkReassignMode = !mode || mode === 'bulkReassignProducts';\n\n const checkDisabled = (level, node, mode) => {\n if (disableForm) return true;\n if (level !== node?.level && mode === 'edit') return true;\n\n if (mode === 'add') {\n let levelList = [];\n for (let i = 1; i <= node?.level; i++) {\n levelList.push(i);\n }\n return levelList.includes(level);\n }\n return false;\n };\n\n const handleSetRefForEachCategoryInput = (input, formItem) => {\n const map = getMap ? getMap() : null;\n if (!map) return;\n input ? map?.set(formItem.level, input) : map?.delete(formItem.level);\n };\n\n const handleChangeValueForm = (e, mode, level) => {\n const errorMessage = 'Category Name is required';\n\n if (mode === 'edit') {\n const errors = e.target.value === '' ? [errorMessage] : [];\n form.setFields([{ name: `category${level}`, errors }]);\n }\n\n if (mode === 'add') {\n const emptyChildLevel = checkEmptyChildCategoryInAddMode(\n form.getFieldsValue()\n );\n if (!emptyChildLevel) {\n resetFieldError(form);\n return;\n }\n const validFields = [];\n const errorFields = [];\n\n [\n CATEGORY_LEVEL_1,\n CATEGORY_LEVEL_2,\n CATEGORY_LEVEL_3,\n CATEGORY_LEVEL_4,\n ].forEach((level) => {\n const fieldName = `category${level}`;\n const errorsExist = emptyChildLevel.includes(level);\n\n if (errorsExist) {\n errorFields.push({ name: fieldName, errors: [errorMessage] });\n } else {\n validFields.push({ name: fieldName, errors: [] });\n }\n });\n\n form.setFields([...validFields, ...errorFields]);\n return;\n }\n };\n\n return (\n <>\n {CATEGORY_FORM_ITEM_INPUT.map((formItem) => {\n return (\n \n {formItem.label}\n \n }\n name={\n mode === 'bulkReassignProducts'\n ? [[formName], `${formItem.name}`]\n : `${formItem.name}`\n }\n >\n handleSetRefForEachCategoryInput(input, formItem)}\n onChange={(e) => handleChangeValueForm(e, mode, formItem.level)}\n />\n \n );\n })}\n \n );\n};\n\nexport default ProductCategoryForm;\n","import Messages from 'i18n/messages/member-profile';\nimport * as categoryManagement from 'services/categoryManagement';\n\nexport const CATEGORY_LEVEL_1 = 1;\nexport const CATEGORY_LEVEL_2 = 2;\nexport const CATEGORY_LEVEL_3 = 3;\nexport const CATEGORY_LEVEL_4 = 4;\n\nexport const BULK_REASSIGN_PRODUCTS = {\n from: {\n key: 'from',\n title: 'Source',\n },\n to: {\n key: 'to',\n title: 'Destination',\n },\n};\n\nexport const PRODUCT_CATEGORY_LEVEL = {\n 1: 'I',\n 2: 'II',\n 3: 'III',\n 4: 'IV',\n};\n\nexport const CATEGORY_FORM_ITEM_INPUT = [\n {\n label: 'Category I',\n name: 'category1',\n level: CATEGORY_LEVEL_1,\n },\n {\n label: 'Category II',\n name: 'category2',\n level: CATEGORY_LEVEL_2,\n },\n {\n label: 'Category III',\n name: 'category3',\n level: CATEGORY_LEVEL_3,\n },\n {\n label: 'Category IV',\n name: 'category4',\n level: CATEGORY_LEVEL_4,\n },\n];\n\nexport const MODE_SAVE_PRODUCT_CATEGORY_FORM = {\n add: {\n successMessage: Messages.addCategorySuccess,\n errorMessage: Messages.addCategoryFailed,\n apiService: categoryManagement.createCategory,\n },\n edit: {\n successMessage: Messages.editCategorySuccess,\n errorMessage: Messages.editCategoryFailed,\n apiService: categoryManagement.editCategory,\n },\n};\n\nexport const LOADING_TYPE = {\n add: 'add',\n edit: 'edit',\n delete: 'delete',\n download: 'download',\n 'bulk-reassign': 'bulk-reassign',\n};\n","import { useEffect, useState } from 'react';\n\nimport { getCategoryTreeView } from 'services/categoryManagement';\nimport { sortCategories } from 'common/components/product-category-tree/utils';\nimport { mapDataToTree } from '../utils';\n\nexport const useGetProductCategoryTreeView = (\n memberId,\n visible,\n isPrefetching,\n setIsPrefetching\n) => {\n const [nestedCategory, setNestedCategory] = useState([]);\n const [status, setStatus] = useState('idle');\n\n useEffect(() => {\n if (!isPrefetching) return;\n\n if (memberId && visible) {\n setStatus('loading');\n\n getCategoryTreeView({ memberId })\n .then((res) => {\n if (res.isSuccess) {\n setStatus('success');\n\n const sortedTreeData = sortCategories(res.data.categories);\n setNestedCategory(\n sortedTreeData.map((categoryItem) =>\n mapDataToTree(categoryItem, null, null)\n )\n );\n setIsPrefetching && setIsPrefetching(false);\n } else {\n setStatus('error');\n setNestedCategory([]);\n }\n })\n .catch((err) => {\n setStatus('error');\n setNestedCategory([]);\n setIsPrefetching && setIsPrefetching(false);\n });\n }\n }, [memberId, visible, setIsPrefetching, isPrefetching]);\n\n return {\n nestedCategory,\n isLoading: status === 'loading',\n setNestedCategory,\n };\n};\n","import { getTargetNodesById } from 'common/components/product-category-tree/utils';\nimport {\n CATEGORY_LEVEL_4,\n CATEGORY_LEVEL_1,\n CATEGORY_LEVEL_2,\n CATEGORY_LEVEL_3,\n} from './constant';\n\nexport const isNotSupportMaximumLevel = (mode, nodeSelected) => {\n return mode === 'add' && nodeSelected?.categoryLevel === CATEGORY_LEVEL_4;\n};\n\nexport const allowResetModeWhenSelect = (info, mode) => {\n if (isNotSupportMaximumLevel(mode, info)) {\n return true;\n }\n\n if (!info && mode === 'edit') {\n return true;\n }\n\n return false;\n};\n\nexport const findCategoryNodeById = (id, tree) => {\n let categoryItem = null;\n\n for (let i = 0; i < tree.length; i++) {\n if (tree[i].id === id) {\n categoryItem = tree[i];\n break;\n } else if (tree[i]?.children?.length > 0) {\n categoryItem = findCategoryNodeById(id, tree[i]?.children);\n }\n\n if (categoryItem) {\n return categoryItem;\n }\n }\n return categoryItem;\n};\n\nexport const getParentKey = (key, tree) => {\n let parentKey;\n for (let i = 0; i < tree.length; i++) {\n const node = tree[i];\n if (node.children.length) {\n if (node.children.some((item) => item.key === key)) {\n parentKey = node.key;\n } else if (getParentKey(key, node.children)) {\n parentKey = getParentKey(key, node.children);\n }\n }\n }\n return parentKey;\n};\n\nexport const getParentNode = (key, tree) => {\n let parentNode;\n for (let i = 0; i < tree.length; i++) {\n const node = tree[i];\n if (node.children.length) {\n if (node.children.some((item) => item.key === key)) {\n parentNode = node;\n } else if (getParentKey(key, node.children)) {\n parentNode = getParentNode(key, node.children);\n }\n }\n }\n return parentNode;\n};\n\nexport const getKeyExpanded = (treeData) => {\n const keyExpanded = [];\n const traverseTree = (tree) => {\n for (let i = 0; i < tree.length; i++) {\n const node = tree[i];\n if (!node.isLeaf) {\n keyExpanded.push(node.key);\n }\n if (node.children) {\n traverseTree(node.children);\n }\n }\n };\n traverseTree(treeData);\n return keyExpanded;\n};\n\nexport const getListKeySearch = (keySearch, searchText, tree) => {\n for (let i = 0; i < tree.length; i++) {\n if (tree[i].key.toLowerCase().includes(searchText.toLowerCase())) {\n keySearch.push(tree[i].key);\n }\n if (tree[i].children) {\n getListKeySearch(keySearch, searchText, tree[i].children);\n }\n }\n};\n\nconst convertParentPath = (parent, current) => {\n if (parent === null) return current.toString();\n return `${parent}-${current}`;\n};\n\nexport const mapDataToTree = (data, parent_path_id, parent_path_name) => {\n if (!data.children.length) {\n return {\n ...data,\n title: data.categoryName,\n titleValue: data.categoryName,\n namePath: convertParentPath(parent_path_name, data.categoryName),\n key: convertParentPath(parent_path_id, data.id),\n categoryLevel: convertParentPath(parent_path_id, data.id)\n .toString()\n .split('-').length,\n isLeaf: !data.children.length,\n children: data.children,\n };\n }\n if (Array.isArray(data.children)) {\n const key = convertParentPath(parent_path_id, data.id);\n const namePath = convertParentPath(parent_path_name, data.categoryName);\n const children = data.children.map((d) => mapDataToTree(d, key, namePath));\n return {\n ...data,\n title: data.categoryName,\n titleValue: data.categoryName,\n key,\n namePath,\n categoryLevel: key.toString().split('-').length,\n isLeaf: false,\n children,\n };\n }\n};\n\nexport const generateIdsBySelectedKey = (key) => {\n if (key) return key.split('-').map((item) => Number(item));\n return [];\n};\n\nexport const getCategoryObjectWhenSelectNode = (nestedCategory, nodeFound) => {\n const { key, categoryLevel } = nodeFound || {};\n const idList = generateIdsBySelectedKey(key);\n\n let nodeList = getTargetNodesById(nestedCategory, idList);\n\n const fieldsValues = {\n category1: nodeList?.[0]?.categoryName,\n category2: categoryLevel >= 2 ? nodeList?.[1].categoryName : undefined,\n category3: categoryLevel >= 3 ? nodeList?.[2].categoryName : undefined,\n category4: categoryLevel === 4 ? nodeList?.[3].categoryName : undefined,\n };\n return fieldsValues;\n};\n\nconst checkFormValueSelectedNodeEqualFormUserInputWhenEdit = (\n formUserInput,\n nestedCategory,\n nodeFound\n) => {\n const fieldValuesOfNodeSelected = getCategoryObjectWhenSelectNode(\n nestedCategory,\n nodeFound\n );\n\n return (\n JSON.stringify(formUserInput) === JSON.stringify(fieldValuesOfNodeSelected)\n );\n};\n\nexport const getCategoryLevelByKey = (categoryFormInput, categoryKey) => {\n const categoryFormItem = categoryFormInput.find(\n (item) => item.name === categoryKey\n );\n return categoryFormItem?.level;\n};\n\nexport const mapObjectFormValueToArrayFormValue = (\n categoryFormInput,\n valueForm\n) => {\n return Object.entries(valueForm)\n .filter(([_, value]) => {\n return value?.trim();\n })\n .map(([key, value]) => {\n const level = getCategoryLevelByKey(categoryFormInput, key.toString());\n\n return { categoryName: value.trim(), level };\n });\n};\n\nexport const getCategoryItemByLevel = (categoryFormInput, valueForm, level) => {\n const arrValueMappingForm = mapObjectFormValueToArrayFormValue(\n categoryFormInput,\n valueForm\n );\n return arrValueMappingForm.find((item) => item.level === level);\n};\n\nexport const checkExistNamePathInCategory = (path, tree) => {\n if (!path) return null;\n\n let categoryItem = null;\n\n for (let i = 0; i < tree.length; i++) {\n if (tree[i].namePath === path) {\n return true;\n } else if (tree[i]?.children?.length > 0) {\n categoryItem = checkExistNamePathInCategory(path, tree[i]?.children);\n }\n\n if (categoryItem) return true;\n }\n return categoryItem;\n};\n\nexport const checkIsMissingCategoryParent = (formValue) => {\n const formValueList = Object.values(formValue);\n\n for (let i = formValueList.length - 1; i >= 1; i--) {\n if (formValueList[i] && !formValueList[i - 1]) {\n return true;\n }\n }\n return false;\n};\n\nconst checkNameAlreadyExistInSignleTree = (nodeSelected, valueEdited) => {\n for (let i = 0; i < nodeSelected.length; i++) {\n if (nodeSelected[i].categoryName === valueEdited) {\n return true;\n }\n\n if (nodeSelected[i].children.length) {\n const isExistName = checkNameAlreadyExistInSignleTree(\n nodeSelected[i].children,\n valueEdited\n );\n\n if (isExistName) return isExistName;\n }\n }\n};\n\nexport const checkIsDuplicateValue = (nodeSelected, formValue) => {\n const formValueList = Object.values(formValue).filter((item) => item);\n const isDuplicateValueForm =\n new Set(formValueList).size !== formValueList.length;\n\n const valueEdited = formValueList[formValueList.length - 1]?.trim();\n\n if (!nodeSelected) {\n return isDuplicateValueForm;\n }\n\n const isNameAlreadyExist = checkNameAlreadyExistInSignleTree(\n [nodeSelected],\n valueEdited\n );\n\n return isDuplicateValueForm || isNameAlreadyExist;\n};\n\nexport const autoFocusInput = (mode, nodeSelected, getMap) => {\n const isNotSupportLevel = isNotSupportMaximumLevel(mode, nodeSelected);\n const isCancelAutoFocus =\n isNotSupportLevel || !mode || (!nodeSelected && mode === 'edit');\n\n if (isCancelAutoFocus) {\n return;\n }\n\n const map = getMap();\n\n if (!nodeSelected) {\n map.get(CATEGORY_LEVEL_1).focus();\n return;\n }\n\n const level =\n mode === 'edit'\n ? nodeSelected.categoryLevel\n : nodeSelected.categoryLevel + 1;\n\n const node = map.get(level);\n\n node.focus();\n};\n\nexport const checkIsShowMessageInValidCategory = (\n pathName,\n nestedCategory,\n valueForm,\n nodeSelected,\n categoryValue,\n mode\n) => {\n const isExistCategory = checkExistNamePathInCategory(\n pathName,\n nestedCategory\n );\n const isValueOfNodeSelectedEqualFormUserInput = checkFormValueSelectedNodeEqualFormUserInputWhenEdit(\n valueForm,\n nestedCategory,\n nodeSelected\n );\n\n if (isValueOfNodeSelectedEqualFormUserInput) return false;\n\n const isMissingParentCategory = checkIsMissingCategoryParent(valueForm);\n const isDuplicateValue = checkIsDuplicateValue(nodeSelected, valueForm);\n if (isMissingParentCategory) {\n return 'missingParentCategoryLevelMessage';\n }\n if (mode === 'edit' && !categoryValue) {\n return 'valueBlankMessage';\n }\n if (isExistCategory) {\n return 'existCategoryNameMessage';\n }\n if (isDuplicateValue) {\n return 'duplicateCategoryMessage';\n }\n\n return false;\n};\n\nexport const getPathByFormValue = (formValue) => {\n if (!formValue) return;\n return Object.values(formValue)\n .filter((item) => item)\n .join('-');\n};\n\nexport const findCategoryNodeByPathName = (path, tree) => {\n if (!path) return null;\n\n let categoryItem = null;\n\n for (let i = 0; i < tree.length; i++) {\n if (tree[i].namePath === path) {\n categoryItem = tree[i];\n break;\n } else if (tree[i]?.children?.length > 0) {\n categoryItem = findCategoryNodeByPathName(path, tree[i]?.children);\n }\n\n if (categoryItem) {\n return categoryItem;\n }\n }\n return categoryItem;\n};\n\nexport const generateCategoryIdForm = (idList) => {\n if (!idList) return null;\n let params = {};\n\n for (let i = 0; i < idList.length; i++) {\n params[`category${i + 1}Id`] = Number(idList[i]);\n }\n return params;\n};\n\nexport const generateCategoryIdByKey = (key) => {\n return key.split('-').map((item) => Number(item));\n};\n\nexport const getCategoryPath = (node) => {\n if (node.children.length === 0) {\n return node.categoryName;\n }\n const childCategoryPath = getCategoryPath(node.children[0]);\n return `${node.categoryName}-${childCategoryPath}`;\n};\n\nexport const checkEmptyChildCategoryInAddMode = (formValue) => {\n const formValueList = Object.values(formValue);\n\n let levelError = [];\n let maxLevelHasValue = null;\n for (let i = formValueList.length - 1; i >= 0; i--) {\n if (formValueList[i] && !formValueList[i - 1]) {\n maxLevelHasValue = i;\n break;\n }\n }\n if (!maxLevelHasValue) return null;\n for (let k = maxLevelHasValue; k >= 0; k--) {\n if (!formValueList[k]) {\n const level = k + 1;\n levelError.push(level);\n }\n }\n return levelError;\n};\n\nexport const resetFieldError = (form) => {\n const fieldEmptyErrorMapping = [\n CATEGORY_LEVEL_1,\n CATEGORY_LEVEL_2,\n CATEGORY_LEVEL_3,\n CATEGORY_LEVEL_4,\n ].map((item) => ({\n name: `category${item}`,\n errors: [],\n }));\n form.setFields(fieldEmptyErrorMapping);\n};\n","import { useState, useEffect, useMemo, useCallback } from 'react';\n\nimport { useAsync, useFetch } from 'hooks';\n\nimport {\n getInteropConnections,\n getDropboxCallbackService,\n testInteropConnection,\n getListConnections,\n} from 'services/interoperability';\n\nimport {\n getListStatusInterop,\n saveAuthDataIntoLocalStorage,\n removeInteropLocalStorage,\n AUTH_DATA_KEY,\n} from './utils';\n\nimport { CustomNotification } from 'common/components';\nimport { useGetMemberId } from 'hooks/useGetMemberId';\n\nexport const useVisibleModal = () => {\n const [visible, setVisible] = useState(false);\n\n const handler = useMemo(\n () => ({\n onModal: () => setVisible(true),\n offModal: () => setVisible(false),\n toggle: () => setVisible((modal) => !modal),\n }),\n []\n );\n\n return [visible, handler];\n};\n\nconst PAGE_SIZE = 9999;\nconst PAGE_INDEX = 1;\n\nexport const useGetInteropConnections = () => {\n const { data, run } = useAsync();\n\n const { memberId } = useGetMemberId();\n\n useEffect(() => {\n run(\n getInteropConnections({\n pageSize: PAGE_SIZE,\n pageIndex: PAGE_INDEX,\n memberId,\n })\n );\n }, [memberId, run]);\n\n const refetchDropboxConnections = useCallback(() => {\n run(\n getInteropConnections({\n pageSize: PAGE_SIZE,\n pageIndex: PAGE_INDEX,\n memberId,\n })\n );\n }, [memberId, run]);\n\n return {\n interoperabilities: data?.gridData ?? [],\n refetchDropboxConnections,\n };\n};\n\nexport const useGetListConnections = ({ storageServiceType }) => {\n const { data, run } = useAsync();\n\n const { memberId } = useGetMemberId();\n\n useEffect(() => {\n run(\n getListConnections({\n pageSize: PAGE_SIZE,\n pageIndex: PAGE_INDEX,\n storageServiceType,\n })\n );\n }, [memberId, run, storageServiceType]);\n\n return {\n interoperabilities: data?.gridData ?? [],\n };\n};\n\nexport const useGetInteropParams = ({\n isEnabled,\n code,\n stateInterop,\n formInstance,\n forceRender,\n}) => {\n const { data, status, resetData, run } = useAsync();\n const isAuthenticated = status === 'resolved';\n\n useEffect(() => {\n if (data?.authData && data?.state && isEnabled) {\n const { AccessToken: accessToken } = JSON.parse(data.authData);\n formInstance.setFieldsValue({\n accessToken,\n status: 'Connected',\n });\n forceRender();\n saveAuthDataIntoLocalStorage(data.authData, data.state);\n }\n }, [data, forceRender, formInstance, isEnabled]);\n\n useEffect(() => {\n if (!isEnabled) return;\n\n // Prevent calling multiple times api when switching other tabs\n if (isAuthenticated) return;\n\n const fetchDropboxParamsCb = async () => {\n return await getDropboxCallbackService({\n code,\n state: stateInterop,\n });\n };\n\n run(fetchDropboxParamsCb());\n }, [code, isAuthenticated, isEnabled, run, stateInterop]);\n\n return {\n isAuthenticating: status === 'pending',\n isAuthenticated,\n authData: data?.authData ?? null,\n state: data?.state,\n status: data?.status,\n resetStateAuthentication: () => resetData(),\n };\n};\n\n// Track active state when switching between tab. Use for the authentication\nexport const useTabActive = () => {\n const [visibilityState, setVisibilityState] = useState(true);\n\n const handleVisibilityChange = useCallback(() => {\n setVisibilityState(document.visibilityState === 'visible');\n }, []);\n\n useEffect(() => {\n document.addEventListener('visibilitychange', handleVisibilityChange);\n return () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n };\n }, [handleVisibilityChange]);\n\n return visibilityState;\n};\n\nexport const useFocusPage = () => {\n const [tabHasFocus, setTabHasFocus] = useState(true);\n\n useEffect(() => {\n const handleFocus = () => {\n setTabHasFocus(true);\n };\n\n const handleBlur = () => {\n setTabHasFocus(false);\n };\n\n window.addEventListener('focus', handleFocus);\n window.addEventListener('blur', handleBlur);\n\n return () => {\n window.removeEventListener('focus', handleFocus);\n window.removeEventListener('blur', handleBlur);\n };\n }, []);\n\n return tabHasFocus;\n};\n\n// Check status of list connection\nexport const useCheckStatusConnections = (interop) => {\n const { data, status: statusFetching, run } = useFetch();\n\n useEffect(() => {\n const getStatusInteropCb = () => {\n return getListStatusInterop(interop);\n };\n run(getStatusInteropCb());\n }, [interop, run]);\n\n return {\n statusConnections:\n data?.map((result) => ({\n statusResponse: result.status,\n statusConnection: result.value.message,\n id: result?.value.data?.id,\n })) ?? [],\n\n isAuthenticating: statusFetching === 'pending',\n };\n};\n\n// Only check on edit mode\nexport const useCheckStatusConnection = ({\n isEnabled,\n selectedInterop,\n formInstance,\n forceRender,\n}) => {\n const { data, status, resetData, run } = useFetch();\n const isError =\n status === 'rejected' ||\n data?.isSuccess === false ||\n data?.message?.toLowerCase() === 'disconnected';\n\n const isConnected =\n status === 'resolved' &&\n data?.isSuccess &&\n data?.message?.toLowerCase() === 'connected';\n\n useEffect(() => {\n if (isEnabled) {\n const params = {\n id: selectedInterop.id,\n storageServiceType: selectedInterop.storageServiceType,\n authData: selectedInterop.authData,\n };\n run(testInteropConnection(params));\n }\n }, [selectedInterop, run, isEnabled]);\n\n // Save authData into localStorage for editing and testing the interop\n useEffect(() => {\n if (isEnabled && isConnected) {\n const { authData } = selectedInterop;\n const parseAuthData = JSON.parse(authData);\n\n formInstance.setFieldsValue({\n ...formInstance.getFieldsValue(),\n status: 'Connected',\n });\n\n localStorage.setItem(\n AUTH_DATA_KEY,\n JSON.stringify({ authData: parseAuthData, state: null })\n );\n }\n }, [isConnected, isEnabled, selectedInterop]);\n\n // reset data form when authentication is error\n useEffect(() => {\n if (isEnabled && isError) {\n formInstance.setFieldsValue({\n accessToken: null,\n status: null,\n });\n CustomNotification.error(\n 'The connection has been disconnected. Please authorize your account to connect!'\n );\n forceRender();\n removeInteropLocalStorage();\n }\n }, [forceRender, formInstance, isEnabled, isError]);\n\n return {\n isCheckingStatus: status === 'pending',\n isError,\n isConnected,\n resetStatusConnection: () => resetData(),\n };\n};\n","import React from 'react';\nimport dropbox from 'assets/system/dropbox.png';\n\nimport {\n CloudSyncOutlined,\n CheckCircleOutlined,\n WarningOutlined,\n LoadingOutlined,\n} from '@ant-design/icons';\n\nimport * as interoperabilityServices from 'services/interoperability';\n\nexport const filterImage = (type) => {\n switch (type?.toLowerCase()) {\n case 'dropbox':\n return dropbox;\n default:\n return '';\n }\n};\n\n// export const openNewTabUrl = (url) => window.open(url, '_blank');\nexport const openNewTabUrl = (url) =>\n window.open(\n url,\n 'popUpWindow',\n 'height=700,width=700,left=50,top=50,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=yes,directories=no,status=yes'\n );\n\nexport const AUTH_DATA_KEY = 'interop_auth_data';\n\nexport const saveAuthDataIntoLocalStorage = (authDatStringify, state) => {\n const parseAuthData = JSON.parse(authDatStringify);\n\n localStorage.setItem(\n AUTH_DATA_KEY,\n JSON.stringify({ authData: parseAuthData, state })\n );\n};\n\nexport const getInteropAuthDataFromLocalStorage = () => {\n const stringifyAuthData = localStorage.getItem(AUTH_DATA_KEY);\n\n if (!stringifyAuthData) {\n return {\n authData: null,\n state: null,\n };\n }\n return JSON.parse(stringifyAuthData);\n};\n\nexport const removeInteropLocalStorage = () => {\n localStorage.removeItem(AUTH_DATA_KEY);\n localStorage.removeItem(INTEROP_KEY);\n};\n\nexport const getParamsDropboxCallback = async (code, state) => {\n try {\n const response = await interoperabilityServices.getDropboxCallbackService({\n code,\n state,\n });\n\n if (response?.isSuccess && response?.data) {\n return await response.data;\n } else {\n return null;\n }\n } catch (error) {\n return null;\n }\n};\n\nexport const INTEROP_KEY = 'interop_key';\n\nexport const getParamsDropboxCallbackFromLocalStorage = () => {\n const stringifyInteropParams = localStorage.getItem(INTEROP_KEY);\n\n if (!stringifyInteropParams) return {};\n\n const { code, state, status } = JSON.parse(stringifyInteropParams) ?? {};\n\n return {\n code,\n stateInterop: state,\n status,\n };\n};\n\nconst getAuthInfo = async (id) => {\n return await interoperabilityServices.getDetailInteropConnection({ id });\n};\n\nconst checkStatusConnection = async (params) => {\n return await interoperabilityServices.testInteropConnection(params);\n};\n\nconst getListPromiseStatusConnection = (data) => {\n let promises = [];\n\n data.forEach((authInfo) => {\n promises.push(\n checkStatusConnection({\n id: authInfo.id,\n storageServiceType: authInfo.storageServiceType,\n authData: authInfo.authData,\n })\n );\n });\n\n return promises;\n};\n\nconst getListPromiseAuthInfo = (authInfoList) => {\n let promises = [];\n\n authInfoList.forEach((id) => {\n promises.push(getAuthInfo(id));\n });\n\n return promises;\n};\n\nexport const getListAuthInfoInterop = async (ids) => {\n const promisesAuthInfo = getListPromiseAuthInfo(ids);\n\n return await Promise.allSettled(promisesAuthInfo);\n};\n\nexport const getListStatusInterop = async (interop) => {\n const ids = interop.map((item) => item.id);\n\n const response = await getListAuthInfoInterop(ids);\n\n const authInfoList = response?.map((result) => result.value.data);\n\n const promisesStatusInterop = getListPromiseStatusConnection(authInfoList);\n\n return await Promise.allSettled(promisesStatusInterop);\n};\n\nexport const getIconTestConnection = (status) => {\n if (status === 'loading') return ;\n if (status === 'connected') return ;\n if (status === 'disconnected') return ;\n return ;\n};\n\nexport const getTextTestConnection = (status) => {\n if (status === 'loading') return 'Loading...';\n if (status === 'disconnected') return 'Fail connection';\n if (status === 'connected') return 'Connected';\n return 'Test Connection';\n};\n\nexport const getInitFormValues = ({\n isEditMode,\n selectedInterop,\n authData,\n}) => {\n if (isEditMode && selectedInterop) {\n const {\n status,\n storageServiceName: connectionName,\n storageServiceType: connectionType,\n } = selectedInterop;\n\n const { AccessToken: accessToken } =\n JSON.parse(selectedInterop?.authData) ?? {};\n\n return {\n connectionName,\n connectionType,\n accessToken,\n status,\n };\n } else {\n // Not authenticated\n if (!authData) return {};\n\n const { AccessToken: accessToken } = JSON.parse(authData);\n return {\n accessToken,\n status: 'Connected',\n };\n }\n};\n","import * as types from './constants';\n\n/**\n * Get member profile data\n *\n * @param {object} data member profile\n */\nexport function getMemberProfileHeader(MemberId) {\n return {\n type: types.GET_MEMBER_PENDING,\n MemberId,\n };\n}\n\n/**\n * Loading member profile data to store\n *\n * @param {object} data member profile\n *\n */\nexport function loadMemberProfile(data) {\n return {\n type: types.GET_MEMBER_SUCCESS,\n data,\n };\n}\n\n/**\n * Set member profile data error\n *\n * @param {object} data member profile\n *\n */\nexport function errorMemberProfile(error) {\n return {\n type: types.GET_MEMBER_ERROR,\n error,\n };\n}\n\n/**\n * Get member contact history data\n *\n * @param {object} data member contact history\n */\nexport function getMemberContactHistory(payload) {\n return {\n type: types.GET_MEMBER_CONTACT_HISTORY,\n payload,\n };\n}\n\n/**\n * Loading member contact history data to store\n *\n * @param {object} data member contact history success\n *\n */\nexport function getMemberContactHistorySuccess(data) {\n return {\n type: types.GET_MEMBER_CONTACT_HISTORY_SUCCESS,\n data,\n };\n}\n\n/**\n * Set member contact history data error\n *\n * @param {object} data member contact history error\n *\n */\nexport function getMemberContactHistoryError(error) {\n return {\n type: types.GET_MEMBER_CONTACT_HISTORY_ERROR,\n error,\n };\n}\n\nexport function fetchMemberDocument(payload) {\n return {\n type: types.FETCH_MEMBER_OVERVIEW_DOCUMENT,\n payload,\n };\n}\n\nexport function fetchMemberDocumentSuccess(data) {\n return {\n type: types.FETCH_MEMBER_OVERVIEW_DOCUMENT_SUCCESS,\n data,\n };\n}\n\nexport function fetchMemberDocumentError(error) {\n return {\n type: types.FETCH_MEMBER_OVERVIEW_DOCUMENT_ERROR,\n error,\n };\n}\n\n/******************************************************************** */\n/* ******************* Grid Columns Actions ************************ */\n/******************************************************************** */\nexport function gridColumnMemberContact(gridName, MemberId) {\n return {\n type: types.GET_MEMBER_CONTACT_GRID,\n gridName,\n MemberId,\n };\n}\n\nexport function gridColumnMemberContactSuccess(columns) {\n return {\n type: types.GET_MEMBER_CONTACT_GRID_SUCCESS,\n columns,\n };\n}\n\nexport function gridColumnMemberContactError(error) {\n return {\n type: types.GET_MEMBER_CONTACT_GRID_ERROR,\n error,\n };\n}\n\nexport function gridColumnContactLocation(gridName, MemberId) {\n return {\n type: types.GET_CONTACT_LOCATION_GRID,\n gridName,\n MemberId,\n };\n}\n\nexport function gridColumnContactLocationSuccess(columns) {\n return {\n type: types.GET_CONTACT_LOCATION_GRID_SUCCESS,\n columns,\n };\n}\n\nexport function gridColumnContactLocationError(error) {\n return {\n type: types.GET_CONTACT_LOCATION_GRID_ERROR,\n error,\n };\n}\n\nexport function gridColumnMemberBilling(gridName, MemberId) {\n return {\n type: types.GET_MEMBER_BILLING_GRID,\n gridName,\n MemberId,\n };\n}\n\nexport function gridColumnMemberBillingSuccess(columns) {\n return {\n type: types.GET_MEMBER_BILLING_GRID_SUCCESS,\n columns,\n };\n}\n\nexport function gridColumnMemberBillingError(error) {\n return {\n type: types.GET_MEMBER_BILLING_GRID_ERROR,\n error,\n };\n}\n\nexport function gridColumnActivityLog(gridName, MemberId) {\n return {\n type: types.GET_MEMBER_ACTIVITY_LOG_GRID,\n gridName,\n MemberId,\n };\n}\n\nexport function gridColumnActivityLogSuccess(columns) {\n return {\n type: types.GET_MEMBER_ACTIVITY_LOG_GRID_SUCCESS,\n columns,\n };\n}\n\nexport function gridColumnActivityLogError(error) {\n return {\n type: types.GET_MEMBER_ACTIVITY_LOG_GRID_ERROR,\n error,\n };\n}\n\nexport function gridColumnMemberContactHistory(gridName) {\n return {\n type: types.GET_MEMBER_CONTACT_HISTORY_GRID,\n gridName,\n };\n}\n\nexport function gridColumnMemberContactHistorySuccess(columns) {\n return {\n type: types.GET_MEMBER_CONTACT_HISTORY_GRID_SUCCESS,\n columns,\n };\n}\n\nexport function gridColumnMemberContactHistoryError(error) {\n return {\n type: types.GET_MEMBER_CONTACT_HISTORY_GRID_ERROR,\n error,\n };\n}\n\n//* toggle upload media box\nexport function toggleUploadTagLineMedia(status) {\n return {\n type: types.TOGGLE_TAG_LINE_UPLOAD_MEDIA,\n status,\n };\n}\n\n//* toggle upload media box PREVIEW\nexport function togglePreviewUploadTagLineMedia(status) {\n return {\n type: types.TOGGLE_PREVIEW_TAG_LINE_UPLOAD_MEDIA,\n status,\n };\n}\n//* show upload media box\nexport function showUploadTagLineMedia(status) {\n return {\n type: types.IS_SHOW_LINE_UPLOAD_MEDIA,\n status,\n };\n}\n\nexport function getMemberShortDetailPreview(id) {\n return {\n type: types.GET_MEMBER_SHORT_DETAIL_PREVIEW,\n id,\n };\n}\n\nexport function getMemberShortDetailPreviewSuccess(data) {\n return {\n type: types.GET_MEMBER_SHORT_DETAIL_PREVIEW_SUCCESS,\n data,\n };\n}\n\nexport function getMemberShortDetailPreviewError(error) {\n return {\n type: types.GET_MEMBER_SHORT_DETAIL_PREVIEW_ERROR,\n error,\n };\n}\n\nexport function gridColumnPublicContact(gridName) {\n return {\n type: types.GET_PUBLIC_CONTACT_COLUMN,\n gridName,\n };\n}\n\nexport function gridColumnPublicContactSuccess(columns) {\n return {\n type: types.GET_PUBLIC_CONTACT_COLUMN_SUCCESS,\n columns,\n };\n}\n\nexport function gridColumnPublicContactError(error) {\n return {\n type: types.GET_PUBLIC_CONTACT_COLUMN_ERROR,\n error,\n };\n}\n\nexport function getPublicContact(memberId) {\n return {\n type: types.GET_PUBLIC_CONTACT,\n memberId,\n };\n}\n\nexport function getPublicContactSuccess(data) {\n return {\n type: types.GET_PUBLIC_CONTACT_SUCCESS,\n data,\n };\n}\n\nexport function getPublicContactError(error) {\n return {\n type: types.GET_PUBLIC_CONTACT_ERROR,\n error,\n };\n}\n\nexport function updatePublicContact(data) {\n return {\n type: types.UPDATE_PUBLIC_CONTACT,\n data,\n };\n}\n\nexport function getMemberContacts(params) {\n return {\n type: types.GET_MEMBER_CONTACTS,\n params,\n };\n}\n\nexport function getMemberContactsSuccess(data) {\n return {\n type: types.GET_MEMBER_CONTACTS_SUCCESS,\n data,\n };\n}\n\nexport function getMemberContactsError(error) {\n return {\n type: types.GET_MEMBER_CONTACTS_ERROR,\n error,\n };\n}\n\n// get member brands\n\nexport function getMemberBrands(params) {\n return {\n type: types.GET_MEMBER_OVERVIEW_BRANDS,\n params,\n };\n}\n\nexport function getMemberBrandsSuccess(data) {\n return {\n type: types.GET_MEMBER_OVERVIEW_BRANDS_SUCCESS,\n data,\n };\n}\n\nexport function getMemberBrandsError(error) {\n return {\n type: types.GET_MEMBER_OVERVIEW_BRANDS_ERROR,\n error,\n };\n}\n\n// get information sheet\nexport function getMemberInformationSheet(params) {\n return {\n type: types.GET_MEMBER_INFORMATION_SHEET,\n params,\n };\n}\n\nexport function getMemberInformationSheetSuccess(data) {\n return {\n type: types.GET_MEMBER_INFORMATION_SHEET_SUCCESS,\n data,\n };\n}\n\nexport function getMemberInformationSheetError(error) {\n return {\n type: types.GET_MEMBER_INFORMATION_SHEET_ERROR,\n error,\n };\n}\n\nexport function documentDetailColumnInfo(gridName) {\n return {\n type: types.DOCUMENT_DETAIL_COLUMN_INFO,\n gridName,\n };\n}\n\nexport function documentDetailColumnInfoSuccess(columns) {\n return {\n type: types.DOCUMENT_DETAIL_COLUMN_INFO_SUCCESS,\n columns,\n };\n}\n\nexport function documentDetailColumnInfoError(error) {\n return {\n type: types.DOCUMENT_DETAIL_COLUMN_INFO_ERROR,\n };\n}\n\nexport function getDocumentDetail(dataParams) {\n return {\n type: types.GET_DOCUMENT_DETAIL,\n dataParams,\n };\n}\n\nexport function getDocumentDetailSuccess(data) {\n return {\n type: types.GET_DOCUMENT_DETAIL_SUCCESS,\n data,\n };\n}\n\nexport function getDocumentDetailError(error) {\n return {\n type: types.GET_DOCUMENT_DETAIL_ERROR,\n };\n}\n\nexport function deleteDocumentDetail(dataParams) {\n return {\n type: types.DELETE_DOCUMENT_DETAIL,\n dataParams,\n };\n}\n\nexport function deleteDocumentDetailError(error) {\n return {\n type: types.DELETE_DOCUMENT_DETAIL_ERROR,\n };\n}\n","// Action Types\nexport const GET_MEMBER_PENDING = 'GET_MEMBER_PENDING';\nexport const GET_MEMBER_SUCCESS = 'GET_MEMBER_SUCCESS';\nexport const GET_MEMBER_ERROR = 'GET_MEMBER_ERROR';\n\nexport const FETCH_MEMBER_OVERVIEW_DOCUMENT = 'FETCH_MEMBER_OVERVIEW_DOCUMENT';\nexport const FETCH_MEMBER_OVERVIEW_DOCUMENT_SUCCESS =\n 'FETCH_MEMBER_OVERVIEW_DOCUMENT_SUCCESS';\nexport const FETCH_MEMBER_OVERVIEW_DOCUMENT_ERROR =\n 'FETCH_MEMBER_OVERVIEW_DOCUMENT_ERROR';\nexport const GET_MEMBER_CONTACT_HISTORY = 'GET_MEMBER_CONTACT_HISTORY';\nexport const GET_MEMBER_CONTACT_HISTORY_SUCCESS =\n 'GET_MEMBER_CONTACT_HISTORY_SUCCESS';\nexport const GET_MEMBER_CONTACT_HISTORY_ERROR =\n 'GET_MEMBER_CONTACT_HISTORY_ERROR';\n\n/**********************************************************************/\n/********************** Grid MEMBER COLUMN CONSTANTS ******************/\n/**********************************************************************/\nexport const GET_MEMBER_CONTACT_GRID = 'GET_MEMBER_CONTACT_GRID';\nexport const GET_MEMBER_CONTACT_GRID_SUCCESS =\n 'GET_MEMBER_CONTACT_GRID_SUCCESS';\nexport const GET_MEMBER_CONTACT_GRID_ERROR = 'GET_MEMBER_CONTACT_GRID_ERROR';\nexport const GET_CONTACT_LOCATION_GRID = 'GET_CONTACT_LOCATION_GRID';\nexport const GET_CONTACT_LOCATION_GRID_SUCCESS =\n 'GET_CONTACT_LOCATION_GRID_SUCCESS';\nexport const GET_CONTACT_LOCATION_GRID_ERROR =\n 'GET_CONTACT_LOCATION_GRID_ERROR';\nexport const GET_MEMBER_BILLING_GRID = 'GET_MEMBER_BILLING_GRID';\nexport const GET_MEMBER_BILLING_GRID_SUCCESS =\n 'GET_MEMBER_BILLING_GRID_SUCCESS';\nexport const GET_MEMBER_BILLING_GRID_ERROR = 'GET_MEMBER_BILLING_GRID_ERROR';\nexport const GET_MEMBER_ACTIVITY_LOG_GRID = 'GET_MEMBER_ACTIVITY_LOG_GRID';\nexport const GET_MEMBER_ACTIVITY_LOG_GRID_SUCCESS =\n 'GET_MEMBER_ACTIVITY_LOG_GRID_SUCCESS';\nexport const GET_MEMBER_ACTIVITY_LOG_GRID_ERROR =\n 'GET_MEMBER_ACTIVITY_LOG_GRID_ERROR';\nexport const GET_MEMBER_CONTACT_HISTORY_GRID =\n 'GET_MEMBER_CONTACT_HISTORY_GRID';\nexport const GET_MEMBER_CONTACT_HISTORY_GRID_SUCCESS =\n 'GET_MEMBER_CONTACT_HISTORY_GRID_SUCCESS';\nexport const GET_MEMBER_CONTACT_HISTORY_GRID_ERROR =\n 'GET_MEMBER_CONTACT_HISTORY_GRID_ERROR';\n\n// tag line upload media\nexport const TOGGLE_TAG_LINE_UPLOAD_MEDIA = 'TOGGLE_TAG_LINE_UPLOAD_MEDIA';\nexport const TOGGLE_PREVIEW_TAG_LINE_UPLOAD_MEDIA =\n 'TOGGLE_PREVIEW_TAG_LINE_UPLOAD_MEDIA';\nexport const IS_SHOW_LINE_UPLOAD_MEDIA = 'IS_SHOW_LINE_UPLOAD_MEDIA';\nexport const GET_MEMBER_SHORT_DETAIL_PREVIEW =\n 'GET_MEMBER_SHORT_DETAIL_PREVIEW';\nexport const GET_MEMBER_SHORT_DETAIL_PREVIEW_SUCCESS =\n 'GET_MEMBER_SHORT_DETAIL_PREVIEW_SUCCESS';\nexport const GET_MEMBER_SHORT_DETAIL_PREVIEW_ERROR =\n 'GET_MEMBER_SHORT_DETAIL_PREVIEW_ERROR';\nexport const GET_PUBLIC_CONTACT_COLUMN = 'GET_PUBLIC_CONTACT_COLUMN';\nexport const GET_PUBLIC_CONTACT_COLUMN_SUCCESS =\n 'GET_PUBLIC_CONTACT_COLUMN_SUCCESS';\nexport const GET_PUBLIC_CONTACT_COLUMN_ERROR =\n 'GET_MEMBER_SHORT_DETAIL_PREVIEW_ERROR';\nexport const GET_PUBLIC_CONTACT = 'GET_PUBLIC_CONTACT';\nexport const GET_PUBLIC_CONTACT_SUCCESS = 'GET_PUBLIC_CONTACT_SUCCESS';\nexport const GET_PUBLIC_CONTACT_ERROR = 'GET_PUBLIC_CONTACT_ERROR';\nexport const UPDATE_PUBLIC_CONTACT = 'UPDATE_PUBLIC_CONTACT';\n\n// get contacts by memberId\nexport const GET_MEMBER_CONTACTS = 'GET_MEMBER_CONTACTS';\nexport const GET_MEMBER_CONTACTS_SUCCESS = 'GET_MEMBER_CONTACTS_SUCCESS';\nexport const GET_MEMBER_CONTACTS_ERROR = 'GET_MEMBER_CONTACTS_ERROR';\n\n// get member brands\nexport const GET_MEMBER_OVERVIEW_BRANDS = 'GET_MEMBER_OVERVIEW_BRANDS';\nexport const GET_MEMBER_OVERVIEW_BRANDS_SUCCESS =\n 'GET_MEMBER_OVERVIEW_BRANDS_SUCCESS';\nexport const GET_MEMBER_OVERVIEW_BRANDS_ERROR =\n 'GET_MEMBER_OVERVIEW_BRANDS_ERROR';\n\nexport const DOCUMENT_DETAIL_COLUMN_INFO = 'DOCUMENT_DETAIL_COLUMN_INFO';\nexport const DOCUMENT_DETAIL_COLUMN_INFO_SUCCESS =\n 'DOCUMENT_DETAIL_COLUMN_INFO_SUCCESS';\nexport const DOCUMENT_DETAIL_COLUMN_INFO_ERROR =\n 'DOCUMENT_DETAIL_COLUMN_INFO_ERROR';\nexport const GET_DOCUMENT_DETAIL = 'GET_DOCUMENT_DETAIL';\nexport const GET_DOCUMENT_DETAIL_SUCCESS = 'GET_DOCUMENT_DETAIL_SUCCESS';\nexport const GET_DOCUMENT_DETAIL_ERROR = 'GET_DOCUMENT_DETAIL_ERROR';\nexport const DELETE_DOCUMENT_DETAIL = 'DELETE_DOCUMENT_DETAIL';\nexport const DELETE_DOCUMENT_DETAIL_ERROR = 'DELETE_DOCUMENT_DETAIL_ERROR';\n// Information sheet\nexport const GET_MEMBER_INFORMATION_SHEET = 'GET_MEMBER_INFORMATION_SHEET';\nexport const GET_MEMBER_INFORMATION_SHEET_SUCCESS =\n 'GET_MEMBER_INFORMATION_SHEET_SUCCESS';\nexport const GET_MEMBER_INFORMATION_SHEET_ERROR =\n 'GET_MEMBER_INFORMATION_SHEET_ERROR';\n","import produce from 'immer';\nimport * as types from '../constants';\n\nexport const initialState = {\n loading: false,\n memberInfo: null,\n error: null,\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst memberProfileReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_MEMBER_PENDING:\n draft.loading = true;\n draft.error = null;\n break;\n case types.GET_MEMBER_SUCCESS:\n draft.loading = false;\n draft.memberInfo = action.data;\n draft.error = null;\n break;\n case types.GET_MEMBER_ERROR:\n draft.loading = false;\n draft.error = action.error;\n draft.memberInfo = null;\n break;\n }\n });\n\nexport default memberProfileReducer;\n","import produce from 'immer';\nimport * as types from '../constants';\n\nexport const initialState = {\n loading: false,\n brand: null,\n document: null,\n asset: null,\n error: null,\n documentDetail: null,\n loadingDocumentGrid: false,\n loadingGetDocument: false,\n memberContact: {\n loading: false,\n pageIndex: 1,\n pageSize: 10000,\n totalItems: 0,\n data: [],\n columns: [],\n memberId: null,\n },\n brands: {\n loading: false,\n pageIndex: 1,\n pageSize: 20,\n totalItems: 0,\n brandsList: [],\n columns: [],\n memberId: null,\n },\n informationSheet: {\n loading: false,\n pageIndex: 1,\n pageSize: 20,\n totalItems: 0,\n informationSheetList: [],\n memberId: null,\n },\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst memberOverviewReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.FETCH_MEMBER_OVERVIEW_DOCUMENT:\n draft.loading = true;\n draft.error = null;\n break;\n case types.FETCH_MEMBER_OVERVIEW_DOCUMENT_SUCCESS:\n draft.loading = false;\n draft.error = null;\n draft.document = action.data;\n break;\n case types.FETCH_MEMBER_OVERVIEW_DOCUMENT_ERROR:\n draft.loading = false;\n draft.error = action.error;\n break;\n case types.GET_DOCUMENT_DETAIL:\n draft.loadingGetDocument = true;\n draft.loadingDocumentGrid = false;\n draft.error = null;\n\n break;\n case types.GET_DOCUMENT_DETAIL_SUCCESS:\n draft.loadingGetDocument = false;\n draft.error = null;\n draft.documentDetail = action.data;\n break;\n case types.DELETE_DOCUMENT_DETAIL:\n draft.loadingDocumentGrid = true;\n draft.error = null;\n break;\n case types.DELETE_DOCUMENT_DETAIL_ERROR:\n draft.loadingDocumentGrid = false;\n draft.error = action.data;\n break;\n case types.GET_DOCUMENT_DETAIL_ERROR:\n draft.loading = false;\n draft.error = action.error;\n break;\n case types.GET_MEMBER_CONTACTS:\n draft.memberContact['loading'] = true;\n break;\n case types.GET_MEMBER_CONTACTS_SUCCESS:\n draft.memberContact['loading'] = false;\n draft.memberContact['data'] = action.data.gridData;\n draft.memberContact['pageIndex'] = action.data.paging.currentPageIndex;\n draft.memberContact['pageSize'] = action.data.paging.currentPageSize;\n draft.memberContact['totalItems'] = action.data.paging.totalRecord;\n break;\n case types.GET_MEMBER_CONTACTS_ERROR:\n draft.memberContact['loading'] = false;\n break;\n case types.GET_MEMBER_OVERVIEW_BRANDS:\n draft.brands['loading'] = true;\n break;\n case types.GET_MEMBER_OVERVIEW_BRANDS_SUCCESS:\n draft.brands['loading'] = false;\n draft.brands['brandsList'] = action?.data?.gridData || [];\n draft.brands['pageIndex'] =\n action?.data?.paging?.currentPageIndex ||\n initialState.brands.pageIndex;\n draft.brands['pageSize'] =\n action?.data?.paging?.currentPageSize || initialState.brands.pageSize;\n draft.brands['totalItems'] =\n action?.data?.paging?.totalRecord || initialState.brands.totalItems;\n break;\n case types.GET_MEMBER_OVERVIEW_BRANDS_ERROR:\n draft.brands['loading'] = false;\n break;\n case types.GET_MEMBER_INFORMATION_SHEET:\n draft.informationSheet['loading'] = true;\n break;\n case types.GET_MEMBER_INFORMATION_SHEET_SUCCESS:\n draft.informationSheet['loading'] = false;\n draft.informationSheet['informationSheetList'] =\n action?.data?.gridData || [];\n draft.informationSheet['pageIndex'] =\n action?.data?.paging?.currentPageIndex ||\n initialState.brands.pageIndex;\n draft.informationSheet['pageSize'] =\n action?.data?.paging?.currentPageSize ||\n initialState.informationSheet.pageSize;\n draft.informationSheet['totalItems'] =\n action?.data?.paging?.totalRecord ||\n initialState.informationSheet.totalItems;\n break;\n case types.GET_MEMBER_INFORMATION_SHEET_ERROR:\n draft.informationSheet['loading'] = false;\n break;\n }\n });\n\nexport default memberOverviewReducer;\n","import produce from 'immer';\nimport * as types from '../constants';\n\nexport const initialState = {\n loading: false,\n memberContactHistory: null,\n error: null,\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst memberContactHistoryReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_MEMBER_CONTACT_HISTORY:\n draft.loading = true;\n draft.error = null;\n break;\n case types.GET_MEMBER_CONTACT_HISTORY_SUCCESS:\n draft.loading = false;\n draft.memberContactHistory = action.data;\n draft.error = null;\n break;\n case types.GET_MEMBER_CONTACT_HISTORY_ERROR:\n draft.loading = false;\n draft.error = action.error;\n draft.memberContactHistory = null;\n break;\n }\n });\n\nexport default memberContactHistoryReducer;\n","import produce from 'immer';\nimport * as types from '../constants';\n\nexport const initialState = {\n loading: false,\n memberContact: null,\n contactLocation: null,\n memberBilling: null,\n activityLog: null,\n contactHistory: null,\n error: null,\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst memberColumnGridReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_MEMBER_CONTACT_GRID:\n draft.loading = true;\n draft.error = null;\n break;\n case types.GET_MEMBER_CONTACT_GRID_SUCCESS:\n draft.loading = false;\n draft.memberContact = action.columns;\n draft.error = null;\n break;\n case types.GET_MEMBER_CONTACT_GRID_ERROR:\n draft.loading = false;\n draft.memberContact = null;\n draft.error = action.error;\n break;\n case types.GET_CONTACT_LOCATION_GRID:\n draft.loading = true;\n draft.error = null;\n break;\n case types.GET_CONTACT_LOCATION_GRID_SUCCESS:\n draft.loading = false;\n draft.contactLocation = action.columns;\n draft.error = null;\n break;\n case types.GET_CONTACT_LOCATION_GRID_ERROR:\n draft.loading = false;\n draft.contactLocation = null;\n draft.error = action.error;\n break;\n case types.GET_MEMBER_BILLING_GRID:\n draft.loading = true;\n draft.error = null;\n break;\n case types.GET_MEMBER_BILLING_GRID_SUCCESS:\n draft.loading = false;\n draft.memberBilling = action.columns;\n draft.error = null;\n break;\n case types.GET_MEMBER_BILLING_GRID_ERROR:\n draft.loading = false;\n draft.memberBilling = null;\n draft.error = action.error;\n break;\n case types.GET_MEMBER_ACTIVITY_LOG_GRID:\n draft.loading = true;\n draft.error = null;\n break;\n case types.GET_MEMBER_ACTIVITY_LOG_GRID_SUCCESS:\n draft.loading = false;\n draft.activityLog = action.columns;\n draft.error = null;\n break;\n case types.GET_MEMBER_ACTIVITY_LOG_GRID_ERROR:\n draft.loading = false;\n draft.activityLog = null;\n draft.error = action.error;\n break;\n case types.GET_MEMBER_CONTACT_HISTORY_GRID:\n draft.loading = true;\n draft.error = null;\n break;\n case types.GET_MEMBER_CONTACT_HISTORY_GRID_SUCCESS:\n draft.loading = false;\n draft.contactHistory = action.columns;\n draft.error = null;\n break;\n case types.GET_MEMBER_CONTACT_HISTORY_GRID_ERROR:\n draft.loading = false;\n draft.contactHistory = null;\n draft.error = action.error;\n break;\n }\n });\n\nexport default memberColumnGridReducer;\n","import produce from 'immer';\nimport * as types from '../constants';\n\nexport const initialState = {\n isUploadTagLineMediaOpen: false,\n isShowUploadTagLineMedia: false,\n isShowPreviewUploadTagLineMedia: false,\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst memberTagLineReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.TOGGLE_TAG_LINE_UPLOAD_MEDIA:\n draft.isUploadTagLineMediaOpen = action.status;\n break;\n case types.TOGGLE_PREVIEW_TAG_LINE_UPLOAD_MEDIA:\n draft.isShowPreviewUploadTagLineMedia = action.status;\n break;\n case types.IS_SHOW_LINE_UPLOAD_MEDIA:\n draft.isShowUploadTagLineMedia = action.status;\n break;\n }\n });\n\nexport default memberTagLineReducer;\n","import produce from 'immer';\nimport * as types from '../constants';\n\nexport const initialState = {\n loading: false,\n memberShortDetail: null,\n error: null,\n initialPublicContact: null,\n publicContact: null,\n publicContactList: null,\n};\n/* eslint-disable default-case, no-param-reassign */\nconst memberPreviewReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_MEMBER_SHORT_DETAIL_PREVIEW:\n draft.loading = true;\n draft.error = null;\n break;\n case types.GET_MEMBER_SHORT_DETAIL_PREVIEW_SUCCESS:\n draft.loading = false;\n draft.memberShortDetail = action.data;\n break;\n case types.GET_MEMBER_SHORT_DETAIL_PREVIEW_ERROR:\n draft.loading = false;\n draft.error = action.error;\n break;\n case types.GET_PUBLIC_CONTACT_COLUMN:\n draft.loading = true;\n draft.error = null;\n break;\n case types.GET_PUBLIC_CONTACT_COLUMN_SUCCESS:\n draft.loading = false;\n draft.publicContact = action.columns;\n draft.error = null;\n break;\n case types.GET_PUBLIC_CONTACT_COLUMN_ERROR:\n draft.loading = false;\n draft.publicContact = null;\n draft.error = action.error;\n break;\n case types.GET_PUBLIC_CONTACT:\n draft.loading = true;\n draft.error = null;\n break;\n case types.GET_PUBLIC_CONTACT_SUCCESS:\n draft.loading = false;\n draft.publicContactList = action.data;\n draft.initialPublicContact = action.data;\n draft.error = null;\n break;\n case types.GET_PUBLIC_CONTACT_ERROR:\n draft.loading = false;\n draft.publicContactList = null;\n draft.error = action.error;\n break;\n case types.UPDATE_PUBLIC_CONTACT:\n draft.publicContactList = action.data;\n break;\n }\n });\nexport default memberPreviewReducer;\n","import { combineReducers } from 'redux';\nimport memberProfileReducer, {\n initialState as initialStateProfile,\n} from './reducers/memberProfileReducer';\nimport memberOverviewReducer, {\n initialState as initialStateOverview,\n} from './reducers/memberOverviewReducer';\nimport memberContactHistoryReducer, {\n initialState as initialContactHistory,\n} from './reducers/memberContactHistoryReducer';\nimport memberColumnGridReducer, {\n initialState as initialStateMemberColumnGridReducer,\n} from './reducers/memberColumnGridReducer';\nimport memberTagLineReducer, {\n initialState as initialStateTagLineReducer,\n} from './reducers/memberTagLineReducer';\nimport memberPreviewReducer, {\n initialState as initialStatePreviewReducer,\n} from './reducers/memberPreviewReducer';\n\nconst initialStateMember = {\n profile: null,\n contactHistory: {},\n overview: {},\n gridColumn: null,\n tagLine: {},\n};\n\nexport {\n initialStateMember,\n initialStateProfile,\n initialStateOverview,\n initialContactHistory,\n initialStateMemberColumnGridReducer,\n initialStateTagLineReducer,\n initialStatePreviewReducer,\n};\n\nexport default combineReducers({\n profile: memberProfileReducer,\n contactHistory: memberContactHistoryReducer,\n overview: memberOverviewReducer,\n gridColumn: memberColumnGridReducer,\n tagLine: memberTagLineReducer,\n preview: memberPreviewReducer,\n});\n","import React from 'react';\nimport { Space } from 'antd';\nimport {\n ArrowDownOutlined,\n ArrowUpOutlined,\n FileExclamationOutlined,\n MailOutlined,\n MessageOutlined,\n FileImageOutlined,\n IdcardOutlined,\n} from '@ant-design/icons';\n\nconst IconRenderer = (props) => {\n const { item } = props;\n return (\n \n {item &&\n item.data &&\n (item.data.isInBound ? (\n \n ) : (\n \n ))}\n {item &&\n item.data &&\n (item.data.type === 'DAM' ? (\n \n ) : item.data.type === 'Email' ? (\n \n ) : item.data.type === 'Request' ? (\n \n ) : item.data.type === 'Registration' ? (\n \n ) : (\n \n ))}\n \n );\n};\nexport default IconRenderer;\n","import { call } from 'redux-saga/effects';\n\nexport function* getColumnAndFilterGridTable(gridColInfoApiService, param) {\n const response = yield call(gridColInfoApiService, param.gridName);\n\n return response;\n}\n","import React from 'react';\nimport { put, call, takeLatest, all } from 'redux-saga/effects';\nimport * as types from './constants';\nimport * as actions from './actions';\nimport { DEFAULT_SORT } from 'static/Constants';\n\nimport {\n getMemberProfileHeader,\n getMemberOverviewDocument,\n getMemberContactHistory,\n getMemberShortDetail,\n getPublicContact,\n getMemberDocument,\n deleteMemberDocument,\n} from 'services/members';\nimport * as services from 'services/members';\nimport * as servicesGrid from 'services/grid';\nimport * as memberFulltypes from 'pages/home/ribbon/member-full/controllers/constants';\nimport moment from 'moment';\nimport IconRenderer from '../components/tabs/crm/activity/IconRenderer';\nimport {\n MemberBillingIconRenderer,\n MemberContactIconRenderer,\n MemberLocationIconRenderer,\n} from 'common/components/icon-renderer/IconRenderer';\nimport * as filterService from './filterService';\nimport { formatMDYWithParam } from 'utils/formatDate';\n\nexport function* memberProfileHeaderSaga(action) {\n try {\n const response = yield call(getMemberProfileHeader, {\n MemberId: action.MemberId,\n });\n\n if (response.isSuccess && response.data) {\n yield put(actions.loadMemberProfile(response.data));\n return;\n }\n\n yield put({ type: types.GET_MEMBER_ERROR, error: 'no-data' });\n } catch (error) {\n yield put({ type: types.GET_MEMBER_ERROR, error });\n }\n}\n\n// BP 08/31/2020: TODO need to review more carefully\nexport function* memberContactHistorySaga(payload) {\n try {\n const response = yield call(getMemberContactHistory, { ...payload });\n yield put(actions.getMemberContactHistorySuccess(response));\n } catch (error) {\n yield put({ type: types.GET_MEMBER_CONTACT_HISTORY_ERROR, error });\n }\n}\n\nexport function* fetchMemberDocument(payload) {\n try {\n const props = payload.payload;\n const response = yield call(getMemberOverviewDocument, {\n MemberId: props.memberId,\n PageIndex: props.currentPage,\n PageSize: props.pageSize,\n });\n yield put({\n type: types.FETCH_MEMBER_OVERVIEW_DOCUMENT_SUCCESS,\n data: response,\n });\n } catch (error) {\n yield put({\n type: types.FETCH_MEMBER_OVERVIEW_DOCUMENT_ERROR,\n error,\n });\n }\n}\n\nexport function* fetchPublicContact(payload) {\n try {\n const response = yield call(getPublicContact, {\n memberId: Number(payload.memberId),\n pageIndex: 1,\n pageSize: 10,\n });\n yield put({\n type: types.GET_PUBLIC_CONTACT_SUCCESS,\n data: response?.data?.gridData,\n });\n } catch (error) {\n yield put({\n type: types.GET_PUBLIC_CONTACT_ERROR,\n error,\n });\n }\n}\n\n// get contacts by memberId\nexport function* getContactMemberSaga(payload) {\n try {\n const response = yield call(services.getMemberContact, {\n ...payload.params,\n memberId: Number(payload.params.memberId),\n });\n yield put(actions.getMemberContactsSuccess(response.data));\n } catch (error) {\n yield put(actions.getMemberContactsError(error));\n }\n}\n\nexport function* getMemberBrandsSaga(payload) {\n try {\n const response = yield call(services.getMemberOverviewBrands, {\n ...payload.params,\n memberId: Number(payload.params.memberId),\n sort: DEFAULT_SORT,\n });\n const { isSuccess, data, message } = response;\n if (isSuccess) {\n yield put(actions.getMemberBrandsSuccess(data));\n } else {\n yield put(actions.getMemberBrandsError(message));\n }\n } catch (error) {\n yield put(actions.getMemberBrandsError(error));\n }\n}\n\nexport function* getMemberInformationSheetSaga(payload) {\n try {\n const response = yield call(services.getMemberInformationSheetGrid, {\n ...payload.params,\n memberId: Number(payload.params.memberId),\n sort: DEFAULT_SORT,\n });\n const { isSuccess, data, message } = response;\n if (isSuccess) {\n yield put(actions.getMemberInformationSheetSuccess(data));\n } else {\n yield put(actions.getMemberInformationSheetError(message));\n }\n } catch (error) {\n yield put(actions.getMemberInformationSheetError(error));\n }\n}\n\n// Date Formatter\nfunction dateFormatter(params) {\n return moment(params.value).format('MM/DD/YYYY');\n}\n\n// GET MEMBER BILLING GRID\nconst renderIconBilling = (params) => {\n return ;\n};\n\nexport function* gridColumnMemberBilling(payload) {\n try {\n const response = yield call(\n filterService.getColumnAndFilterGridTable,\n servicesGrid.gridColumnInfo,\n payload\n );\n\n let columns = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n width: 50,\n resizable: true,\n },\n ];\n\n if (response?.columns?.length > 0) {\n response.columns.forEach((col) => {\n if (col.fieldNameCamelCase === 'id') {\n col = { ...col, width: 120 };\n } else if (col.dataType === 'datetime') {\n col = {\n ...col,\n flex: 1,\n cellRenderer: dateFormatter,\n sort: col.displayName === 'TransactionDate' ? 'desc' : '',\n minWidth: col.displayName === 'TransactionDate' && 200,\n };\n } else if (col.fieldNameCamelCase === 'type') {\n col = {\n ...col,\n headerName: '',\n cellRenderer: renderIconBilling,\n width: 100,\n };\n } else if (col.fieldNameCamelCase === 'balance') {\n col = { ...col, width: 150 };\n } else {\n col = { ...col, flex: 1 };\n }\n columns.push({ ...col, resizable: true });\n });\n\n [columns[1], columns[2]] = [columns[2], columns[1]];\n }\n yield put(actions.gridColumnMemberBillingSuccess(columns));\n } catch (error) {\n yield put(actions.gridColumnMemberBillingError(error));\n }\n}\n\nexport function* getColumnDocumentDetailList(payload) {\n try {\n const { response } = yield call(\n servicesGrid.gridColumnInfo,\n payload.gridName\n );\n\n const checkboxColumn = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n resizable: true,\n },\n ];\n\n let result = [];\n\n if (response && response.columns && response.columns.length > 0) {\n response.columns.forEach((val, index) => {\n if (\n val.fieldNameCamelCase === 'banByMemberName' ||\n val.fieldNameCamelCase === 'bannedMemberName'\n ) {\n result.push({ ...val, resizable: true, width: 240 });\n } else if (val.fieldNameCamelCase === 'banByUserId') {\n result.push({\n ...val,\n resizable: true,\n width: 100,\n headerName: 'Owner',\n });\n }\n });\n }\n yield put(\n actions.documentDetailColumnInfoSuccess([...checkboxColumn, ...result])\n );\n } catch (error) {\n yield put(actions.documentDetailColumnInfoError(error));\n }\n}\n\n// GET MEMBER CONTACT GRID\nconst renderIconContact = (params) => {\n return ;\n};\n\nconst renderCityState = (params) => {\n if (params?.data?.city || params?.data?.state)\n return (\n <>\n {params.data.city}, {params.data.state}\n \n );\n else return <>;\n};\n\nexport function* gridColumnMemberContact(payload) {\n try {\n const response = yield call(\n filterService.getColumnAndFilterGridTable,\n servicesGrid.gridColumnInfo,\n payload\n );\n let columns = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n width: 50,\n resizable: true,\n },\n {\n field: '',\n separateFieldName: ['status', 'isPrimaryContact'],\n isShowFilter: 'none',\n width: 100,\n cellRenderer: renderIconContact,\n resizable: true,\n },\n ];\n if (response?.columns?.length > 0) {\n const hiddenCol = ['id', 'isPublic', 'status', 'isPrimaryContact'];\n response.columns.forEach((col, index) => {\n if (!hiddenCol.includes(col.fieldNameCamelCase)) {\n if ('accountExpires' === col?.fieldNameCamelCase)\n col = { ...col, minWidth: 250, cellRenderer: formatMDYWithParam };\n columns.push({ ...col, flex: 1, resizable: true });\n }\n });\n }\n [columns[2], columns[3], columns[4], columns[5], columns[6], columns[7]] = [\n columns[2],\n columns[3],\n columns[4],\n columns[6],\n columns[7],\n columns[5],\n ];\n yield put(actions.gridColumnMemberContactSuccess(columns));\n } catch (error) {\n yield put(actions.gridColumnMemberContactError(error));\n }\n}\n\n// GET MEMBER LOCATION GRID\nconst renderIconLocation = (params) => {\n return ;\n};\n\nexport function* gridColumnMemberCompanyLocation(payload) {\n try {\n const response = yield call(\n filterService.getColumnAndFilterGridTable,\n servicesGrid.gridColumnInfo,\n payload\n );\n\n let columns = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n width: 50,\n resizable: true,\n },\n {\n field: '',\n width: 120,\n isShowFilter: 'none',\n separateFieldName: ['isPrimaryAddress', 'status', 'addressType'],\n cellRenderer: renderIconLocation,\n resizable: true,\n },\n ];\n\n if (response?.columns?.length > 0) {\n // BP 12/28/2020 - add latitude, longitude into removed columns\n let hiddenCol = [\n 'id',\n 'isPrimaryAddress',\n 'status',\n 'addressType',\n 'latitude',\n 'longitude',\n ];\n response.columns.forEach((col, index) => {\n if (hiddenCol.indexOf(col.fieldNameCamelCase) === -1) {\n col = { ...col, flex: 1, resizable: true };\n columns.push(col);\n }\n });\n }\n\n yield put(actions.gridColumnContactLocationSuccess(columns));\n } catch (error) {\n yield put(actions.gridColumnContactLocationError(error));\n }\n}\n\n// GET MEMBER ACTIVITY LOG GRID\nconst renderIcon = (params) => {\n return ;\n};\n\nexport function* gridColumnMemberActivityLog(payload) {\n try {\n const response = yield call(\n filterService.getColumnAndFilterGridTable,\n servicesGrid.gridColumnInfo,\n payload\n );\n let columns = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n width: 50,\n resizable: true,\n },\n {\n field: '',\n cellRenderer: renderIcon,\n width: 100,\n resizable: true,\n },\n ];\n\n if (response && response.columns && response.columns.length > 0) {\n response.columns.forEach((val, index) => {\n if (\n val.fieldNameCamelCase !== 'id' &&\n val.fieldNameCamelCase !== 'isInBound' &&\n val.fieldNameCamelCase !== 'originatorUserId' &&\n val.fieldNameCamelCase !== 'mostRecentUserId'\n ) {\n if (\n val.fieldNameCamelCase === 'messageDate' ||\n val.fieldNameCamelCase === 'lastActivity'\n ) {\n if (val.fieldNameCamelCase === 'messageDate') {\n val = { ...val, fieldNameCamelCase: 'date' };\n }\n val = { ...val, cellRenderer: dateFormatter, width: 130 };\n } else if (val.fieldNameCamelCase === 'description') {\n val = { ...val };\n } else if (val.fieldNameCamelCase === 'member') {\n val = { ...val, headerName: 'Company', minWidth: 150, flex: 1 };\n } else if (val.fieldNameCamelCase === 'originatorUser') {\n val = { ...val, headerName: 'Originator' };\n } else if (val.fieldNameCamelCase === 'mostRecentUser') {\n val = { ...val, headerName: 'Most Recent' };\n } else if (val.fieldName === 'Type') {\n val = { ...val, width: 100 };\n }\n columns.push({ ...val, resizable: true });\n }\n });\n [columns[2], columns[3], columns[4]] = [\n columns[3],\n columns[4],\n columns[2],\n ];\n }\n yield put(actions.gridColumnActivityLogSuccess(columns));\n } catch (error) {\n yield put(actions.gridColumnActivityLogError(error));\n }\n}\n\n// GET MEMBER CONTACT HISTORY\nexport function* gridColumnMemberContactHistory(payload) {\n try {\n const response = yield call(servicesGrid.gridColumnInfo, payload.gridName);\n let columns = [];\n\n if (response.columns && response.columns.length > 0) {\n let columns = [];\n response.columns.forEach((val) => {\n columns.push({ fieldName: val.fieldName });\n });\n }\n yield put(actions.gridColumnMemberContactHistorySuccess(columns));\n } catch (error) {\n yield put(actions.gridColumnMemberContactHistoryError(error));\n }\n}\n\nexport function* gridColumnPublicContact(payload) {\n try {\n const response = yield call(servicesGrid.gridColumnInfo, payload.gridName);\n let columns = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n width: 50,\n resizable: true,\n },\n ];\n if (response.columns && response.columns.length > 0) {\n response.columns.forEach((val) => {\n if (\n val.fieldNameCamelCase !== 'visibility' &&\n val.fieldNameCamelCase !== 'showInMemberPreview' &&\n val.fieldNameCamelCase !== 'id' &&\n val.fieldNameCamelCase !== 'name' &&\n val.fieldNameCamelCase !== 'latitude' &&\n val.fieldNameCamelCase !== 'longitude'\n ) {\n // if (val.fieldNameCamelCase !== 'showInMemberPreview') {\n // columns.push({ ...val });\n // } else\n columns.push({ ...val, filter: false, suppressMenu: true });\n }\n });\n }\n\n yield put(actions.gridColumnPublicContactSuccess(columns));\n } catch (error) {\n yield put(actions.gridColumnPublicContactError(error));\n }\n}\n\nexport function* getMemberShortDetailPreview(payload) {\n try {\n const response = yield call(getMemberShortDetail, {\n Id: payload.id,\n });\n const { isSuccess, data, message } = response;\n if (isSuccess) {\n yield put(actions.getMemberShortDetailPreviewSuccess(data));\n } else {\n yield put(actions.getMemberShortDetailPreviewError(message));\n }\n } catch (error) {\n yield put(actions.getMemberShortDetailPreviewError(error));\n }\n}\n\nexport function* getMemberDocumentDetail(payload) {\n try {\n const { dataParams } = payload;\n const response = yield call(getMemberDocument, {\n pageIndex: dataParams?.pageIndex,\n pageSize: dataParams?.pageSize,\n memberId: dataParams?.memberId,\n });\n const { data, isSuccess } = response;\n if (isSuccess) {\n yield put(actions.getDocumentDetailSuccess(data));\n } else {\n yield put(actions.getDocumentDetailError('error'));\n }\n } catch (error) {\n yield put(actions.getDocumentDetailError(error));\n }\n}\n\nexport function* deleteMemberDocumentDetail(payload) {\n try {\n const { dataParams } = payload;\n const response = yield call(deleteMemberDocument, {\n ids: dataParams?.idList,\n isRemovedFromShowcase: dataParams?.isRemove,\n memberId: dataParams?.memberId,\n forMemberDocument: dataParams?.forMemberDocument,\n });\n const { data, isSuccess } = response;\n if (isSuccess) {\n yield put(\n actions.getDocumentDetail({\n memberId: dataParams.memberId,\n pageIndex: dataParams.currentPage,\n pageSize: dataParams.pageSize,\n })\n );\n } else {\n yield put(actions.deleteDocumentDetailError('error'));\n }\n } catch (error) {\n yield put(actions.deleteDocumentDetailError(error));\n }\n}\n\nfunction* watchAll() {\n yield all([\n takeLatest(types.GET_MEMBER_CONTACT_HISTORY, memberContactHistorySaga),\n takeLatest(types.GET_MEMBER_PENDING, memberProfileHeaderSaga),\n takeLatest(memberFulltypes.FINISH_EDIT_MEMBER, memberProfileHeaderSaga),\n takeLatest(types.GET_MEMBER_CONTACT_GRID, gridColumnMemberContact),\n takeLatest(types.GET_MEMBER_BILLING_GRID, gridColumnMemberBilling),\n takeLatest(\n types.GET_CONTACT_LOCATION_GRID,\n gridColumnMemberCompanyLocation\n ),\n takeLatest(types.GET_MEMBER_ACTIVITY_LOG_GRID, gridColumnMemberActivityLog),\n takeLatest(\n types.GET_MEMBER_CONTACT_HISTORY_GRID,\n gridColumnMemberContactHistory\n ),\n takeLatest(types.GET_PUBLIC_CONTACT_COLUMN, gridColumnPublicContact),\n takeLatest(\n types.GET_MEMBER_SHORT_DETAIL_PREVIEW,\n getMemberShortDetailPreview\n ),\n takeLatest(types.GET_PUBLIC_CONTACT, fetchPublicContact),\n takeLatest(types.GET_MEMBER_CONTACTS, getContactMemberSaga),\n takeLatest(types.GET_MEMBER_OVERVIEW_BRANDS, getMemberBrandsSaga),\n takeLatest(\n types.GET_MEMBER_INFORMATION_SHEET,\n getMemberInformationSheetSaga\n ),\n takeLatest(types.DOCUMENT_DETAIL_COLUMN_INFO, getColumnDocumentDetailList),\n takeLatest(types.GET_DOCUMENT_DETAIL, getMemberDocumentDetail),\n takeLatest(types.DELETE_DOCUMENT_DETAIL, deleteMemberDocumentDetail),\n ]);\n}\n\nexport default watchAll;\n","// Action Types\nexport const EDIT_MEMBER = 'EDIT_MEMBER';\nexport const CANCEL_EDIT_MEMBER = 'CANCEL_EDIT_MEMBER';\nexport const SAVING_MEMBER_FULL = 'SAVING_MEMBER_FULL';\nexport const SAVE_MEMBER_FULL = 'SAVE_MEMBER_FULL';\nexport const SAVE_MEMBER_FULL_SUCCESS = 'SAVE_MEMBER_FULL_SUCCESS';\nexport const SAVE_MEMBER_FULL_ERROR = 'SAVE_MEMBER_FULL_ERROR';\nexport const FINISH_EDIT_MEMBER = 'FINISH_EDIT_MEMBER';\n","import { createSelector } from 'reselect';\nimport {\n initialStateMember,\n initialStateProfile,\n initialStateOverview,\n initialContactHistory,\n initialStateMemberColumnGridReducer,\n initialStateTagLineReducer,\n initialStatePreviewReducer,\n} from './reducer';\n\nconst member = (state) => {\n return state.member || initialStateMember;\n};\n\nconst profile = (state) => {\n if (state && state.member) {\n return state.member.profile || initialStateProfile;\n } else {\n return initialStateProfile;\n }\n};\n\nconst contactHistory = (state) => {\n if (state && state.member) {\n return state.member.contactHistory || initialContactHistory;\n } else {\n return initialContactHistory;\n }\n};\n\nconst overview = (state) => {\n if (state && state.member) {\n return state.member.overview || initialStateOverview;\n } else {\n return initialStateOverview;\n }\n};\n\nconst gridColumn = (state) => {\n if (state && state.member) {\n return state.member.gridColumn || initialStateMemberColumnGridReducer;\n } else {\n return initialStateMemberColumnGridReducer;\n }\n};\n\nconst tagLine = (state) => {\n if (state && state.member) {\n return state.member.tagLine || initialStatePreviewReducer;\n } else {\n return initialStatePreviewReducer;\n }\n};\n\nconst preview = (state) => {\n if (state && state.member) {\n return state.member.preview || initialStateTagLineReducer;\n } else {\n return initialStateTagLineReducer;\n }\n};\n\n// Member Profile\nconst selectMemberProfile = () =>\n createSelector(profile, (memberState) => {\n return memberState.memberInfo;\n });\n\nconst selectMemberError = () =>\n createSelector(member, (memberState) => memberState.profile.error);\n\nconst selectMemberProfileLoading = () =>\n createSelector(profile, (memberState) => memberState.loading);\n\n// Member Contact history\nconst selectMemberContactHistory = () =>\n createSelector(contactHistory, (memberState) => {\n return memberState.memberContactHistory;\n });\n\nconst selectMemberContactHistoryError = () =>\n createSelector(\n contactHistory,\n (memberState) => memberState.contactHistory.error\n );\n\nconst selectMemberContactHistoryLoading = () =>\n createSelector(\n contactHistory,\n (memberState) => memberState.contactHistory.loading\n );\n\nconst selectMemberContact = () => {\n return createSelector(overview, (memberState) => memberState.memberContact);\n};\n\nconst selectBrands = () => {\n return createSelector(overview, (memberState) => memberState.brands);\n};\n\nconst selectInformationSheet = () => {\n return createSelector(\n overview,\n (memberState) => memberState.informationSheet\n );\n};\n\nconst selectBrand = () => {\n return createSelector(overview, (memberState) => memberState.brand);\n};\n\nconst selectAsset = () => {\n return createSelector(overview, (memberState) => memberState.asset);\n};\n\nconst selectDocument = () => {\n return createSelector(overview, (memberState) => memberState.document);\n};\n\nconst selectDocumentDetail = () => {\n return createSelector(overview, (memberState) => memberState.documentDetail);\n};\n\nconst selectLoadingDocumentGrid = () => {\n return createSelector(\n overview,\n (memberState) => memberState.loadingDocumentGrid\n );\n};\nconst selectLoadingGetDocument = () => {\n return createSelector(\n overview,\n (memberState) => memberState.loadingGetDocument\n );\n};\nconst selectLoadingPreview = () => {\n return createSelector(preview, (memberState) => memberState.loading);\n};\n\nconst selectErrorPreview = () => {\n return createSelector(preview, (memberState) => memberState.error);\n};\n\nconst selectShortDetailPreview = () => {\n return createSelector(\n preview,\n (memberState) => memberState.memberShortDetail\n );\n};\n\nconst selectPublicContactColumn = () => {\n return createSelector(preview, (memberState) => memberState.publicContact);\n};\n\nconst selectPublicContactList = () => {\n return createSelector(\n preview,\n (memberState) => memberState.publicContactList\n );\n};\n\nconst selectInitialPublicContactList = () => {\n return createSelector(\n preview,\n (memberState) => memberState.initialPublicContact\n );\n};\n\n/**********************************************************************/\n/************************ Grid Selectors *******************************/\n/**********************************************************************/\nconst selectMemberContactColumns = () =>\n createSelector(gridColumn, (memColState) => memColState.memberContact);\n\nconst selectContactLocationColumns = () =>\n createSelector(gridColumn, (memColState) => memColState.contactLocation);\n\nconst selectMemberBillingColumns = () =>\n createSelector(gridColumn, (memColState) => memColState.memberBilling);\n\nconst selectMemberActivityLogColumns = () =>\n createSelector(gridColumn, (memColState) => memColState.activityLog);\n\nconst selectMemberContactHistoryColumns = () =>\n createSelector(gridColumn, (memColState) => memColState.contactHistory);\n\n// tag line\nconst selectMemberIsTagLineUploadMediaOpen = () =>\n createSelector(\n tagLine,\n (tagLineState) => tagLineState.isUploadTagLineMediaOpen\n );\n\nconst selectMemberIsPreviewTagLineUploadMediaOpen = () =>\n createSelector(\n tagLine,\n (tagLineState) => tagLineState.isShowPreviewUploadTagLineMedia\n );\n\nconst selectMemberIsShowUploadTagLineMedia = () =>\n createSelector(\n tagLine,\n (tagLineState) => tagLineState.isShowUploadTagLineMedia\n );\n\nexport {\n selectMemberProfile,\n selectMemberError,\n selectMemberProfileLoading,\n selectMemberContact,\n selectBrands,\n selectBrand,\n selectDocument,\n selectInformationSheet,\n selectAsset,\n selectMemberContactHistory,\n selectMemberContactHistoryError,\n selectMemberContactHistoryLoading,\n selectMemberContactColumns,\n selectContactLocationColumns,\n selectMemberBillingColumns,\n selectMemberActivityLogColumns,\n selectMemberContactHistoryColumns,\n selectMemberIsTagLineUploadMediaOpen,\n selectMemberIsShowUploadTagLineMedia,\n selectErrorPreview,\n selectLoadingPreview,\n selectShortDetailPreview,\n selectPublicContactColumn,\n selectMemberIsPreviewTagLineUploadMediaOpen,\n selectPublicContactList,\n selectInitialPublicContactList,\n selectDocumentDetail,\n selectLoadingDocumentGrid,\n selectLoadingGetDocument,\n};\n","export const GET_COMPANY_INFO = 'GET_COMPANY_INFO';\nexport const GET_COMPANY_INFO_SUCCESS = 'GET_COMPANY_INFO_SUCCESS';\nexport const GET_COMPANY_INFO_ERROR = 'GET_COMPANY_INFO_ERROR';\nexport const GET_COMPANY_INFO_SHOWCASED_MEDIA_GRID =\n 'GET_COMPANY_INFO_SHOWCASED_MEDIA_GRID';\nexport const GET_COMPANY_INFO_OVERVIEW_SHOWCASED_MEDIA_SUCCESS =\n 'GET_COMPANY_INFO_OVERVIEW_SHOWCASED_MEDIA_SUCCESS';\nexport const GET_COMPANY_INFO_SHOWCASED_MEDIA_GRID_ERROR =\n 'GET_COMPANY_INFO_SHOWCASED_MEDIA_GRID_ERROR';\nexport const GET_OFFICES_AND_FACILITIES = 'GET_OFFICES_AND_FACILITIES';\nexport const GET_OFFICES_AND_FACILITIES_SUCCESS =\n 'GET_OFFICES_AND_FACILITIES_SUCCESS';\nexport const GET_OFFICES_AND_FACILITIES_ERROR =\n 'GET_OFFICES_AND_FACILITIES_ERROR';\n\n// get member brands\nexport const GET_MEMBER_COMPANY_BRANDS = 'GET_MEMBER_COMPANY_BRANDS';\nexport const GET_MEMBER_COMPANY_BRANDS_SUCCESS =\n 'GET_MEMBER_COMPANY_BRANDS_SUCCESS';\nexport const GET_MEMBER_COMPANY_BRANDS_ERROR =\n 'GET_MEMBER_COMPANY_BRANDS_ERROR';\n\nexport const GET_MEMBER_ID = 'GET_MEMBER_ID';\nexport const RESET_COMPANY_INFO_ERROR = 'RESET_COMPANY_INFO_ERROR';\n","import produce from 'immer';\nimport * as types from './constants';\n\n// initial state\nexport const initialState = {\n loadingCompanyInfo: false,\n errorCompanyInfo: false,\n loadingOffice: false,\n companyInfo: null,\n loadingShowcasedAsset: false,\n // overviewShowcasedAssets: [], // overview showcased\n // showcasedAssets: [], // showcased on tab showcase\n errorShowcasedAssets: null,\n officesList: null,\n errorOffice: false,\n totalOffice: null,\n overviewShowcasedAssets: {\n items: [],\n pagination: [],\n totalRecord: 0,\n pageIndex: 0,\n loading: false,\n error: null,\n },\n brands: {\n loading: false,\n pageIndex: 1,\n pageSize: 20,\n totalItems: 0,\n brandsList: [],\n columns: [],\n memberId: null,\n },\n memberId: null,\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst companyReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_COMPANY_INFO:\n draft.loadingCompanyInfo = true;\n break;\n case types.GET_COMPANY_INFO_SUCCESS:\n draft.loadingCompanyInfo = false;\n draft.companyInfo = action.data;\n break;\n case types.GET_COMPANY_INFO_ERROR:\n draft.loadingCompanyInfo = false;\n draft.companyInfo = null;\n draft.errorCompanyInfo = action.error;\n break;\n case types.RESET_COMPANY_INFO_ERROR:\n draft.errorCompanyInfo = false;\n break;\n case types.GET_COMPANY_INFO_SHOWCASED_MEDIA_GRID:\n draft.overviewShowcasedAssets.loading = true;\n break;\n case types.GET_COMPANY_INFO_OVERVIEW_SHOWCASED_MEDIA_SUCCESS:\n draft.overviewShowcasedAssets.loading = false;\n draft.overviewShowcasedAssets.items = action.payload.gridData;\n draft.overviewShowcasedAssets.pagination = action.payload.paging;\n break;\n case types.GET_COMPANY_INFO_SHOWCASED_MEDIA_GRID_ERROR:\n draft.overviewShowcasedAssets.loading = false;\n draft.overviewShowcasedAssets.items = [];\n draft.overviewShowcasedAssets.pagination = null;\n draft.overviewShowcasedAssets.error = action.error;\n break;\n case types.GET_OFFICES_AND_FACILITIES:\n draft.loadingOffice = true;\n break;\n case types.GET_OFFICES_AND_FACILITIES_SUCCESS:\n draft.loadingOffice = false;\n draft.officesList = action?.data?.gridData;\n draft.totalOffice = action?.data?.paging?.totalRecord;\n break;\n case types.GET_OFFICES_AND_FACILITIES_ERROR:\n draft.loadingOffice = false;\n draft.officesList = null;\n draft.errorOffice = action.error;\n break;\n case types.GET_MEMBER_COMPANY_BRANDS:\n draft.brands['loading'] = true;\n break;\n case types.GET_MEMBER_COMPANY_BRANDS_SUCCESS:\n draft.brands['loading'] = false;\n draft.brands['brandsList'] = action?.data?.gridData || [];\n draft.brands['pageIndex'] =\n action?.data?.paging?.currentPageIndex ||\n initialState.brands.pageIndex;\n draft.brands['pageSize'] =\n action?.data?.paging?.currentPageSize || initialState.brands.pageSize;\n draft.brands['totalItems'] =\n action?.data?.paging?.totalRecord || initialState.brands.totalItems;\n break;\n case types.GET_MEMBER_COMPANY_BRANDS_ERROR:\n draft.brands['loading'] = false;\n break;\n case types.GET_MEMBER_ID:\n draft.memberId = action.memberId;\n break;\n }\n });\n\nexport default companyReducer;\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\nconst companyState = (state) => state.company || initialState;\n\nconst setlectCompanyLoading = () =>\n createSelector(companyState, (state) => state.loadingCompanyInfo);\nconst setlectCompanyInfo = () =>\n createSelector(companyState, (state) => state.companyInfo);\nconst setlectCompanyError = () =>\n createSelector(companyState, (state) => state.errorCompanyInfo);\n\nconst selectShowcasedAssetLoading = () =>\n createSelector(companyState, (state) => state.loadingShowcasedAsset);\n\nconst selectOverviewShowcasedAsset = () =>\n createSelector(companyState, (state) => state.overviewShowcasedAssets);\n\nconst selectShowcasedAssetError = () =>\n createSelector(companyState, (state) => state.errorShowcasedAssets);\nconst selectLoadingOffice = () =>\n createSelector(companyState, (state) => state.errorShowcasedAssets);\nconst selectOfficeList = () =>\n createSelector(companyState, (state) => state.officesList);\nconst selectTotalOffice = () =>\n createSelector(companyState, (state) => state.totalOffice);\n// select member Brands\nconst selectBrands = () => {\n return createSelector(companyState, (state) => state.brands);\n};\nconst makeSelectMemberId = () =>\n createSelector(companyState, (state) => state.memberId);\n\nexport {\n setlectCompanyLoading,\n setlectCompanyInfo,\n setlectCompanyError,\n selectShowcasedAssetLoading,\n selectOverviewShowcasedAsset,\n selectShowcasedAssetError,\n selectLoadingOffice,\n selectOfficeList,\n selectTotalOffice,\n selectBrands,\n makeSelectMemberId,\n};\n","import * as types from './constants';\n\nexport function toggleEditLayout(payload) {\n return {\n type: types.TOGGLE_EDIT_LAYOUT,\n payload,\n };\n}\n\nexport function updateLayoutChanged(payload) {\n return {\n type: types.UPDATE_LAYOUT_CHANGED,\n payload,\n };\n}\n\nexport function calendarDayView(calendarView) {\n return {\n type: types.CALENDAR_DAY_VIEW,\n calendarView,\n };\n}\n\nexport function calendarWeekView(calendarView) {\n return {\n type: types.CALENDAR_WEEK_VIEW,\n calendarView,\n };\n}\n\nexport function calendarMonthView(calendarView) {\n return {\n type: types.CALENDAR_MONTH_VIEW,\n calendarView,\n };\n}\n\nexport function calendarScheduleView(calendarView) {\n return {\n type: types.CALENDAR_SCHEDULE_VIEW,\n calendarView,\n };\n}\n\nexport function getMeetingList(fromDate, toDate) {\n return {\n type: types.GET_MEETING_LIST,\n fromDate,\n toDate,\n };\n}\n\nexport function getMeetingListSuccess(meetingList) {\n return {\n type: types.GET_MEETING_LIST_SUCCESS,\n meetingList,\n };\n}\n\nexport function getMeetingListError(error) {\n return {\n type: types.GET_MEETING_LIST_ERROR,\n error,\n };\n}\n\nexport function updateCalendarDate(calendarDate) {\n return {\n type: types.UPDATE_CALENDAR_DATE,\n calendarDate,\n };\n}\n\nexport const getScheduleList = (params) => ({\n type: types.GET_SCHEDULE_LIST,\n payload: params,\n});\n\nexport const getScheduleListSuccess = (params) => {\n return {\n type: types.GET_SCHEDULE_LIST_SUCCESS,\n payload: params,\n };\n};\n\nexport const getScheduleListError = (error) => ({\n type: types.GET_SCHEDULE_LIST_ERROR,\n payload: error,\n});\n\nexport const getProjectsGrid = () => ({\n type: types.GET_PROJECTS_GRID,\n});\n\nexport const getProjectsGridSuccess = (data) => {\n return {\n type: types.GET_PROJECTS_GRID_SUCCESS,\n data,\n };\n};\n\nexport const getProjectsGridError = (error) => ({\n type: types.GET_PROJECTS_GRID_ERROR,\n error,\n});\n\nexport const saveIdMeeting = (meetingId) => ({\n type: types.SAVE_ID_MEETING,\n meetingId,\n});\n\nexport const getMeetingDetails = (params) => ({\n type: types.GET_MEETING_DETAILS,\n params,\n});\n\nexport const getMeetingDetailsSuccess = (params) => {\n return {\n type: types.GET_MEETING_DETAILS_SUCCESS,\n payload: params,\n };\n};\n\nexport const getMeetingDetailsError = (error) => ({\n type: types.GET_MEETING_DETAILS_ERROR,\n payload: error,\n});\n\nexport const resetMeetingDetails = (params) => ({\n type: types.RESET_MEETING_DETAILS,\n payload: params,\n});\n","// Action Types\nexport const TOGGLE_EDIT_LAYOUT = 'TOGGLE_EDIT_LAYOUT';\n\nexport const UPDATE_LAYOUT_CHANGED = 'UPDATE_LAYOUT_CHANGED';\n\nexport const CALENDAR_DAY_VIEW = 'CALENDAR_DAY_VIEW';\nexport const CALENDAR_WEEK_VIEW = 'CALENDAR_WEEK_VIEW';\nexport const CALENDAR_MONTH_VIEW = 'CALENDAR_MONTH_VIEW';\nexport const CALENDAR_SCHEDULE_VIEW = 'CALENDAR_SCHEDULE_VIEW';\n\nexport const GET_MEETING_LIST = 'GET_MEETING_LIST';\nexport const GET_MEETING_LIST_SUCCESS = 'GET_MEETING_LIST_SUCCESS';\nexport const GET_MEETING_LIST_ERROR = 'GET_MEETING_LIST_ERROR';\n\nexport const GET_SCHEDULE_LIST = 'GET_SCHEDULE_LIST';\nexport const GET_SCHEDULE_LIST_SUCCESS = 'GET_SCHEDULE_LIST_SUCCESS';\nexport const GET_SCHEDULE_LIST_ERROR = 'GET_SCHEDULE_LIST_ERROR';\n\nexport const GET_PROJECTS_GRID = 'GET_PROJECTS_GRID';\nexport const GET_PROJECTS_GRID_SUCCESS = 'GET_PROJECTS_GRID_SUCCESS';\nexport const GET_PROJECTS_GRID_ERROR = 'GET_PROJECTS_GRID_ERROR';\n\nexport const UPDATE_CALENDAR_DATE = 'UPDATE_CALENDAR_DATE';\n\nexport const SAVE_ID_MEETING = 'SAVE_ID_MEETING';\nexport const SET_SELECTED_DATE = 'SET_SELECTED_DATE';\n\nexport const GET_MEETING_DETAILS = 'GET_MEETING_DETAILS';\nexport const GET_MEETING_DETAILS_SUCCESS = 'GET_MEETING_DETAILS_SUCCESS';\nexport const GET_MEETING_DETAILS_ERROR = 'GET_MEETING_DETAILS_ERROR';\nexport const RESET_MEETING_DETAILS = 'RESET_MEETING_DETAILS';\n","import produce from 'immer';\nimport * as types from './constants';\n\n// initial state\nexport const initialState = {\n editingLayout: false,\n isLayoutChanged: false,\n calendarView: 'day',\n calendarDate: new Date(),\n loadingCalendar: false,\n meetingList: [],\n errorCalendar: false,\n scheduleList: {\n loading: false,\n data: [],\n error: null,\n },\n projectList: {\n loading: false,\n data: [],\n error: false,\n },\n meetingId: null,\n\n selectedDate: {\n meetingId: null,\n startTime: null,\n endTime: null,\n },\n\n meetingDetails: {\n loading: false,\n data: null,\n error: null,\n },\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst productReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.TOGGLE_EDIT_LAYOUT:\n draft.editingLayout = action.payload;\n break;\n case types.UPDATE_LAYOUT_CHANGED:\n draft.isLayoutChanged = action.payload;\n break;\n case types.CALENDAR_DAY_VIEW:\n case types.CALENDAR_WEEK_VIEW:\n case types.CALENDAR_MONTH_VIEW:\n case types.CALENDAR_SCHEDULE_VIEW:\n draft.calendarView = action.calendarView;\n break;\n case types.GET_MEETING_LIST:\n draft.loadingCalendar = true;\n draft.errorCalendar = false;\n draft.meetingList = [];\n break;\n case types.GET_MEETING_LIST_SUCCESS:\n draft.loadingCalendar = false;\n draft.meetingList = action.meetingList;\n break;\n case types.GET_MEETING_LIST_ERROR:\n draft.loadingCalendar = false;\n draft.errorCalendar = action.error;\n break;\n\n case types.UPDATE_CALENDAR_DATE:\n draft.calendarDate = action.calendarDate;\n break;\n\n case types.GET_SCHEDULE_LIST:\n draft['scheduleList'].loading = true;\n draft['scheduleList'].data = [];\n draft['scheduleList'].error = null;\n break;\n case types.GET_SCHEDULE_LIST_SUCCESS:\n draft['scheduleList'].loading = false;\n draft['scheduleList'].data = action.payload;\n break;\n case types.GET_SCHEDULE_LIST_ERROR:\n draft['scheduleList'].loading = false;\n draft['scheduleList'].error = action.payload;\n break;\n case types.GET_PROJECTS_GRID:\n draft.projectList['loading'] = true;\n break;\n case types.GET_PROJECTS_GRID_SUCCESS:\n draft.projectList['loading'] = false;\n draft.projectList['data'] = action.data;\n break;\n case types.GET_PROJECTS_GRID_ERROR:\n draft.projectList['loading'] = false;\n draft.projectList['error'] = action.error;\n break;\n\n case types.SAVE_ID_MEETING:\n draft['meetingId'] = action.meetingId;\n break;\n\n case types.SET_SELECTED_DATE:\n draft.selectedDate['meetingId'] = action.payload?.id;\n draft.selectedDate['startTime'] = action.payload?.startTime;\n draft.selectedDate['endTime'] = action.payload?.endTime;\n break;\n\n case types.GET_MEETING_DETAILS:\n draft['meetingDetails'].loading = true;\n draft['meetingDetails'].data = [];\n draft['meetingDetails'].error = null;\n break;\n case types.GET_MEETING_DETAILS_SUCCESS:\n draft['meetingDetails'].loading = false;\n draft['meetingDetails'].data = action.payload;\n break;\n case types.GET_MEETING_DETAILS_ERROR:\n draft['meetingDetails'].loading = false;\n draft['meetingDetails'].error = action.payload;\n break;\n case types.RESET_MEETING_DETAILS:\n draft['meetingDetails'].loading = false;\n draft['meetingDetails'].data = null;\n draft['meetingDetails'].error = null;\n draft.meetingList = [];\n break;\n }\n });\n\nexport default productReducer;\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\nconst selectDashboard = (state) => state.dashboard || initialState;\n\nconst makeSelectEditingLayout = () =>\n createSelector(\n selectDashboard,\n (dashboardState) => dashboardState.editingLayout\n );\n\nconst makeSelectLayoutChanged = () =>\n createSelector(\n selectDashboard,\n (dashboardState) => dashboardState.isLayoutChanged\n );\nconst makeSelectCalendarView = () =>\n createSelector(\n selectDashboard,\n (dashboardState) => dashboardState.calendarView\n );\nconst makeSelectCalendarDate = () =>\n createSelector(\n selectDashboard,\n (dashboardState) => dashboardState.calendarDate\n );\nconst makeSelectMeetingList = () =>\n createSelector(\n selectDashboard,\n (dashboardState) => dashboardState.meetingList\n );\nconst makeSelectScheduleList = () =>\n createSelector(\n selectDashboard,\n (dashboardState) => dashboardState.scheduleList\n );\n\nconst makeSelectProjectsList = () =>\n createSelector(\n selectDashboard,\n (dashboardState) => dashboardState.projectList\n );\n\nconst makeSelectMeetingId = () =>\n createSelector(selectDashboard, (dashboardState) => dashboardState.meetingId);\n\nconst makeSelectedDate = () =>\n createSelector(\n selectDashboard,\n (dashboardState) => dashboardState.selectedDate\n );\n\nconst makeSelectLoadingCalendar = () =>\n createSelector(\n selectDashboard,\n (dashboardState) => dashboardState.loadingCalendar\n );\n\nconst makeSelectMeetingDetails = () =>\n createSelector(\n selectDashboard,\n (dashboardState) => dashboardState.meetingDetails\n );\n\nexport {\n makeSelectEditingLayout,\n makeSelectLayoutChanged,\n makeSelectScheduleList,\n makeSelectProjectsList,\n makeSelectCalendarView,\n makeSelectMeetingList,\n makeSelectCalendarDate,\n makeSelectMeetingId,\n makeSelectedDate,\n makeSelectLoadingCalendar,\n makeSelectMeetingDetails,\n};\n","import React from 'react';\nimport Messages from 'i18n/messages/maintenance';\nimport { LogoutOutlined } from '@ant-design/icons';\nimport { forwardTo } from 'utils/common/route';\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nconst BackToEula = () => {\n return (\n }\n label={Messages.backToEula}\n onClick={() => forwardTo('/maintenance/eula/list')}\n />\n );\n};\n\nexport default BackToEula;\n","import React from 'react';\n\nimport { SaveOutlined, CloseCircleOutlined } from '@ant-design/icons';\n\nimport { RibbonBar, RibbonButton, RibbonDivider } from 'common/components';\nimport { Can } from 'context/Can';\nimport {\n AdvanceStack,\n DetailSection,\n ManageSharingSection,\n ViewLayout,\n} from 'pages/home/ribbon/components';\n\nimport Messages from 'i18n/messages/maintenance';\n\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\nimport BackToEula from 'pages/home/ribbon/components/controls/maintenance/eula/BackToEula';\nimport { forwardTo } from 'utils/common/route';\n\nconst EulaRibbon = (props) => {\n const { loading, disabled, onSubmit } = props;\n\n const handleCancelEula = () => {\n forwardTo('/maintenance/eula/list');\n };\n\n return (\n \n \n \n \n \n \n }\n label={Messages.saveEula}\n onClick={onSubmit}\n loading={loading}\n />\n }\n label={Messages.cancelEula}\n onClick={handleCancelEula}\n />\n \n \n \n \n \n );\n};\n\nexport default EulaRibbon;\n","import * as types from './constants';\n\n//* get grid columns\nexport const getEulaGridColumns = (gridName) => ({\n type: types.GET_EULA_MAINTENANCE_GRID_COLUMNS,\n gridName,\n});\n\nexport const getEulaGridColumnsSuccess = (data) => ({\n type: types.GET_EULA_MAINTENANCE_GRID_COLUMNS_SUCCESS,\n payload: data,\n});\n\nexport const getEulaGridColumnsFailure = () => ({\n type: types.GET_EULA_MAINTENANCE_GRID_COLUMNS_FAILURE,\n});\n\nexport const createEula = (params) => ({\n type: types.CREATE_EULA,\n payload: params,\n});\n\nexport const createEulaSuccess = (id) => ({\n type: types.CREATE_EULA_SUCCESS,\n id,\n});\n\nexport const createEulaError = (error) => ({\n type: types.CREATE_EULA_ERROR,\n error,\n});\n\nexport const cloneEula = (params) => ({\n type: types.CLONE_EULA,\n payload: params,\n});\n\nexport const cloneEulaSuccess = (id) => ({\n type: types.CLONE_EULA_SUCCESS,\n id,\n});\n\nexport const cloneEulaError = (error) => ({\n type: types.CLONE_EULA_ERROR,\n error,\n});\n\nexport const resetSaveEula = () => ({\n type: types.RESET_SAVE_EULA,\n});\n\nexport const enableEditEula = () => ({\n type: types.ENABLE_EULA_MAINTENANCE_EDIT,\n});\n\nexport const disableEditEula = () => ({\n type: types.DISABLE_EULA_MAINTENANCE_EDIT,\n});\n\nexport const enableCreateEula = () => ({\n type: types.ENABLE_EULA_MAINTENANCE_CREATE,\n});\n\nexport const disableCreateEula = () => ({\n type: types.DISABLE_EULA_MAINTENANCE_CREATE,\n});\n\nexport const confirmCloneEula = () => ({\n type: types.CONFIRM_CLONE_EULA_MAINTENANCE,\n});\n\n\nexport const resetConfirmCloneEula = () => ({\n type: types.RESET_CONFIRM_CLONE_EULA_MAINTENANCE,\n});\n\n\n\nexport const saveIdEula = (id) => ({\n type: types.SAVE_ID_EULA,\n data: id,\n});\n\n//* get grid data\nexport const getEulaList = ({ pageSize, pageNumber, search }) => ({\n type: types.GET_EULA_MAINTENANCE_LIST,\n pageSize: pageSize,\n pageIndex: pageNumber,\n search,\n});\n\nexport const getEulaListSuccess = (data, total) => ({\n type: types.GET_EULA_MAINTENANCE_LIST_SUCCESS,\n payload: data,\n total,\n});\n\nexport const getEulaListFailure = () => ({\n type: types.GET_EULA_MAINTENANCE_LIST_FAILURE,\n});\nexport function updateIsDetailsViewEula(isDetailsView) {\n return {\n type: types.EULA_DISABLED_VIEW_MODE,\n isDetailsView,\n };\n}\n\nexport const getEulaContentDetail = (params) => {\n return {\n type: types.GET_EULA_CONTENT_DETAIL,\n params,\n };\n};\nexport function getEulaContentDetailSuccess(data) {\n return {\n type: types.GET_EULA_CONTENT_DETAIL_SUCCESS,\n data,\n };\n}\n\nexport function getEulaContentDetailError(error) {\n return {\n type: types.GET_EULA_CONTENT_DETAIL_ERROR,\n error,\n };\n}\n\n//* toggle upload media box\nexport function toggleUploadEulaMedia(status) {\n return {\n type: types.TOGGLE_EULA_UPLOAD_MEDIA,\n status,\n };\n}\n\n//* get accepted user eula grid columns\nexport const getAcceptedUserEulaGridColumns = (gridName) => ({\n type: types.GET_ACCEPTED_USER_EULA_GRID_COLUMNS,\n gridName,\n});\n\nexport const getAcceptedUserEulaGridColumnsSuccess = (columns) => ({\n type: types.GET_ACCEPTED_USER_EULA_GRID_COLUMNS_SUCCESS,\n columns,\n});\n\nexport const getAcceptedUserEulaGridColumnsError = (error) => ({\n type: types.GET_ACCEPTED_USER_EULA_GRID_COLUMNS_ERROR,\n error,\n});\n\nexport function getAcceptedUserEulaList(pageNumber, pageSize, search) {\n return {\n type: types.GET_ACCEPTED_USER_EULA_LIST,\n pageIndex: pageNumber,\n pageSize,\n 'Search.SearchText': search,\n };\n}\n\nexport function getAcceptedUserEulaListSuccess(acceptedUserEula, total) {\n return {\n type: types.GET_ACCEPTED_USER_EULA_LIST_SUCCESS,\n acceptedUserEula,\n total,\n };\n}\n\nexport function getAcceptedUserEulaListError(error) {\n return {\n type: types.GET_ACCEPTED_USER_EULA_LIST_ERROR,\n error,\n };\n}\n","//* get grid columns\nexport const GET_EULA_MAINTENANCE_GRID_COLUMNS =\n 'GET_EULA_MAINTENANCE_GRID_COLUMN';\nexport const GET_EULA_MAINTENANCE_GRID_COLUMNS_SUCCESS =\n 'GET_EULA_MAINTENANCE_GRID_COLUMNS_SUCCESS';\nexport const GET_EULA_MAINTENANCE_GRID_COLUMNS_FAILURE =\n 'GET_EULA_MAINTENANCE_GRID_COLUMNS_FAILURE';\n\nexport const CREATE_EULA = 'CREATE_EULA';\nexport const CREATE_EULA_SUCCESS = 'CREATE_EULA_SUCCESS';\nexport const CREATE_EULA_ERROR = 'CREATE_EULA_ERROR';\n\nexport const CLONE_EULA = 'CLONE_CREATE';\nexport const CLONE_EULA_SUCCESS = 'CLONE_EULA_SUCCESS';\nexport const CLONE_EULA_ERROR = 'CLONE_EULA_ERROR';\n\nexport const RESET_SAVE_EULA = 'RESET_SAVE_EULA';\n\nexport const ENABLE_EULA_MAINTENANCE_EDIT = 'ENABLE_EULA_MAINTENANCE_EDIT_POST';\nexport const DISABLE_EULA_MAINTENANCE_EDIT =\n 'DISABLE_EULA_MAINTENANCE_EDIT_POST';\n\nexport const ENABLE_EULA_MAINTENANCE_CREATE =\n 'ENABLE_EULA_MAINTENANCE_EDIT_CREATE';\nexport const DISABLE_EULA_MAINTENANCE_CREATE =\n 'ENABLE_EULA_MAINTENANCE_EDIT_CREATE';\n\nexport const CONFIRM_CLONE_EULA_MAINTENANCE = 'CONFIRM_CLONE_EULA_MAINTENANCE';\nexport const RESET_CONFIRM_CLONE_EULA_MAINTENANCE = 'RESET_CONFIRM_CLONE_EULA_MAINTENANCE';\n\n\nexport const SAVE_ID_EULA = 'SAVE_ID_EULA';\n\n//* get data list\nexport const GET_EULA_MAINTENANCE_LIST = 'GET_EULA_MAINTENANCE_LIST';\nexport const GET_EULA_MAINTENANCE_LIST_SUCCESS =\n 'GET_EULA_MAINTENANCE_LIST_SUCCESS';\nexport const GET_EULA_MAINTENANCE_LIST_FAILURE =\n 'GET_EULA_MAINTENANCE_LIST_FAILURE';\n\n// Only Eula Detail View\nexport const EULA_DISABLED_VIEW_MODE = 'EULA_DISABLED_VIEW_MODE';\n//* get detail data\nexport const GET_EULA_CONTENT_DETAIL = 'GET_EULA_CONTENT_DETAIL';\nexport const GET_EULA_CONTENT_DETAIL_SUCCESS =\n 'GET_EULA_CONTENT_DETAIL_SUCCESS';\nexport const GET_EULA_CONTENT_DETAIL_ERROR = 'GET_EULA_CONTENT_DETAIL_ERROR';\n\nexport const TOGGLE_EULA_UPLOAD_MEDIA = 'TOGGLE_EULA_UPLOAD_MEDIA';\n\n// Accepted user eula grid columns\nexport const GET_ACCEPTED_USER_EULA_GRID_COLUMNS =\n 'GET_ACCEPTED_USER_EULA_GRID_COLUMNS';\nexport const GET_ACCEPTED_USER_EULA_GRID_COLUMNS_SUCCESS =\n 'GET_ACCEPTED_USER_EULA_GRID_COLUMNS_SUCCESS';\nexport const GET_ACCEPTED_USER_EULA_GRID_COLUMNS_ERROR =\n 'GET_ACCEPTED_USER_EULA_GRID_COLUMNS_ERROR';\n// Accepted user eula list\nexport const GET_ACCEPTED_USER_EULA_LIST = 'GET_ACCEPTED_USER_EULA_LIST';\nexport const GET_ACCEPTED_USER_EULA_LIST_SUCCESS =\n 'GET_ACCEPTED_USER_EULA_LIST_SUCCESS';\nexport const GET_ACCEPTED_USER_EULA_LIST_ERROR =\n 'GET_ACCEPTED_USER_EULA_LIST_ERROR';\n","import produce from 'immer';\nimport * as types from './constants';\n\nexport const initialState = {\n gridLoading: false,\n gridColumns: [],\n eulaList: [],\n\n eulaForm: {\n id: null,\n statusSubmit: 'idle',\n statusClone: 'idle',\n error: null,\n\n isEdit: false,\n isCreate: false,\n isClone: false,\n },\n pageSize: 20,\n pageNumber: 1,\n gridTotal: 0,\n detailData: {},\n detailError: null,\n isUploadEulaMediaOpen: false,\n acceptedEulaLoading: false,\n acceptedEulaColumns: [],\n acceptedUserEula: [],\n acceptedEulaPageSize: 20,\n acceptedEulaPageNumber: 1,\n acceptedEulaTotal: 0,\n acceptedEulaError: false,\n acceptedSearch: '',\n reloadAcceptedEulaPage: false,\n};\n\n/* eslint-disable default-case, no-param-reassign */\nconst helpMaintenanceReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_EULA_MAINTENANCE_GRID_COLUMNS:\n draft.gridLoading = true;\n break;\n case types.GET_EULA_MAINTENANCE_GRID_COLUMNS_SUCCESS:\n draft.gridLoading = false;\n draft.gridColumns = action.payload;\n break;\n case types.GET_EULA_MAINTENANCE_GRID_COLUMNS_FAILURE:\n draft.gridLoading = false;\n break;\n\n case types.CREATE_EULA:\n draft['eulaForm'].statusSubmit = 'loading';\n draft['eulaForm'].statusClone = 'idle';\n draft['eulaForm'].isClone = false;\n draft['eulaForm'].isCreate = false;\n break;\n case types.CREATE_EULA_SUCCESS:\n draft['eulaForm'].statusSubmit = 'success';\n draft['eulaForm'].id = action.id;\n break;\n case types.CREATE_EULA_ERROR:\n draft['eulaForm'].statusSubmit = 'error';\n draft['eulaForm'].error = action.error;\n break;\n\n case types.CLONE_EULA:\n draft['eulaForm'].statusClone = 'loading';\n break;\n case types.CLONE_EULA_SUCCESS:\n draft['eulaForm'].statusClone = 'success';\n break;\n case types.CLONE_EULA_ERROR:\n draft['eulaForm'].statusClone = 'error';\n break;\n\n case types.RESET_SAVE_EULA:\n draft['eulaForm'].statusSubmit = 'idle';\n draft['eulaForm'].statusClone = 'idle';\n draft['eulaForm'].isClone = false;\n draft['eulaForm'].isCreate = false;\n break;\n\n case types.ENABLE_EULA_MAINTENANCE_EDIT:\n draft['eulaForm'].isCreate = false;\n draft['eulaForm'].isEdit = true;\n break;\n\n case types.DISABLE_EULA_MAINTENANCE_EDIT:\n draft['eulaForm'].isEdit = false;\n break;\n\n case types.ENABLE_EULA_MAINTENANCE_CREATE:\n draft['eulaForm'].isCreate = true;\n draft['eulaForm'].isEdit = false;\n break;\n\n case types.CONFIRM_CLONE_EULA_MAINTENANCE:\n draft['eulaForm'].isClone = true;\n break;\n\n \n case types.RESET_CONFIRM_CLONE_EULA_MAINTENANCE:\n draft['eulaForm'].isClone = false;\n break;\n\n\n case types.SAVE_ID_EULA:\n draft['eulaForm'].id = action.data;\n break;\n\n case types.GET_EULA_MAINTENANCE_LIST:\n draft.gridLoading = true;\n draft.pageSize = action.pageSize;\n draft.pageNumber = action.pageIndex;\n break;\n case types.GET_EULA_MAINTENANCE_LIST_SUCCESS:\n draft.gridLoading = false;\n draft.eulaList = action.payload;\n draft.gridTotal = action.total;\n break;\n case types.GET_EULA_MAINTENANCE_LIST_FAILURE:\n draft.gridLoading = false;\n break;\n case types.EULA_DISABLED_VIEW_MODE:\n draft.isDetailsView = action.isDetailsView;\n break;\n case types.GET_EULA_CONTENT_DETAIL:\n draft.detailLoading = true;\n draft.detailData = null;\n draft.detailError = null;\n break;\n case types.GET_EULA_CONTENT_DETAIL_SUCCESS:\n draft.detailLoading = false;\n draft.detailData = action.data;\n break;\n case types.GET_EULA_CONTENT_DETAIL_ERROR:\n draft.detailLoading = false;\n draft.detailData = null;\n draft.detailError = action.error;\n break;\n case types.TOGGLE_EULA_UPLOAD_MEDIA:\n draft.isUploadEulaMediaOpen = action.status;\n break;\n // Accepted user eula\n case types.GET_ACCEPTED_USER_EULA_GRID_COLUMNS:\n draft.acceptedEulaLoading = true;\n draft.acceptedEulaColumns = [];\n break;\n case types.GET_ACCEPTED_USER_EULA_GRID_COLUMNS_SUCCESS:\n draft.acceptedEulaLoading = false;\n draft.acceptedEulaColumns = action.columns;\n break;\n case types.GET_ACCEPTED_USER_EULA_GRID_COLUMNS_ERROR:\n draft.acceptedEulaLoading = false;\n draft.acceptedEulaColumns = [];\n draft.acceptedEulaError = action.error;\n break;\n case types.GET_ACCEPTED_USER_EULA_LIST:\n draft.acceptedEulaLoading = true;\n draft.acceptedEulaError = false;\n draft.acceptedEulaPageSize = action.pageSize;\n draft.acceptedEulaPageNumber = action.pageIndex;\n draft.acceptedSearch = action['Search.SearchText'];\n draft.reloadAcceptedEulaPage = false;\n\n break;\n case types.GET_ACCEPTED_USER_EULA_LIST_SUCCESS:\n draft.acceptedEulaLoading = false;\n draft.acceptedUserEula = action.acceptedUserEula;\n draft.acceptedEulaTotal = action.total;\n break;\n case types.GET_ACCEPTED_USER_EULA_LIST_ERROR:\n draft.acceptedEulaLoading = false;\n draft.acceptedEulaTotal = 0;\n draft.acceptedUserEula = [];\n draft.acceptedEulaError = action.error;\n break;\n default:\n break;\n }\n });\n\nexport default helpMaintenanceReducer;\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\nconst selectEulaMaintenance = (state) => state.eulaMaintenance || initialState;\n\nconst selectEulaGridLoading = () =>\n createSelector(selectEulaMaintenance, (eulaState) => eulaState.gridLoading);\n\nconst selectEulaForm = () =>\n createSelector(selectEulaMaintenance, (eulaState) => eulaState.eulaForm);\n\nconst selectEulaGridPageSize = () =>\n createSelector(selectEulaMaintenance, (eulaState) => eulaState.pageSize);\n\nconst selectEulaGridPageNumber = () =>\n createSelector(selectEulaMaintenance, (eulaState) => eulaState.pageNumber);\n\nconst selectEulaGridSearch = () =>\n createSelector(selectEulaMaintenance, (eulaState) => eulaState.search);\n\nconst selectEulaList = () =>\n createSelector(selectEulaMaintenance, (eulaState) => eulaState.eulaList);\n\nconst selectEulaGridColumns = () =>\n createSelector(selectEulaMaintenance, (eulaState) => eulaState.gridColumns);\n\nconst selectEulaGridTotal = () =>\n createSelector(selectEulaMaintenance, (eulaState) => eulaState.gridTotal);\n\nconst selectEulaDetailData = () =>\n createSelector(selectEulaMaintenance, (eulaState) => eulaState.detailData);\n\nconst selectIsDetailsViewEula = () =>\n createSelector(selectEulaMaintenance, (eulaState) => eulaState.isDetailsView);\n\nconst selectIsEulaUploadMediaOpen = () =>\n createSelector(\n selectEulaMaintenance,\n (eulaState) => eulaState.isUploadEulaMediaOpen\n );\n\n// Accepted user eula\nconst selectAcceptedUserEulaLoading = () =>\n createSelector(\n selectEulaMaintenance,\n (eulaState) => eulaState.acceptedEulaLoading\n );\nconst selectAcceptedUserEulaColumns = () =>\n createSelector(\n selectEulaMaintenance,\n (eulaState) => eulaState.acceptedEulaColumns\n );\nconst selectAcceptedUserEula = () =>\n createSelector(\n selectEulaMaintenance,\n (eulaState) => eulaState.acceptedUserEula\n );\nconst selectAcceptedUserEulaPageSize = () =>\n createSelector(\n selectEulaMaintenance,\n (eulaState) => eulaState.acceptedEulaPageSize\n );\nconst selectAcceptedUserEulaPageNumber = () =>\n createSelector(\n selectEulaMaintenance,\n (eulaState) => eulaState.acceptedEulaPageNumber\n );\nconst selectAcceptedUserEulaTotal = () =>\n createSelector(\n selectEulaMaintenance,\n (eulaState) => eulaState.acceptedEulaTotal\n );\nconst selectAcceptedUserEulaError = () =>\n createSelector(\n selectEulaMaintenance,\n (eulaState) => eulaState.acceptedEulaError\n );\nconst selectAcceptedUserEulaSearch = () =>\n createSelector(\n selectEulaMaintenance,\n (eulaState) => eulaState.acceptedSearch\n );\n\nexport {\n selectEulaGridLoading,\n selectEulaGridPageSize,\n selectEulaGridPageNumber,\n selectEulaGridSearch,\n selectEulaList,\n selectEulaGridColumns,\n selectEulaGridTotal,\n selectEulaDetailData,\n selectIsDetailsViewEula,\n selectEulaForm,\n selectIsEulaUploadMediaOpen,\n selectAcceptedUserEulaLoading,\n selectAcceptedUserEulaColumns,\n selectAcceptedUserEula,\n selectAcceptedUserEulaPageSize,\n selectAcceptedUserEulaPageNumber,\n selectAcceptedUserEulaTotal,\n selectAcceptedUserEulaError,\n selectAcceptedUserEulaSearch,\n};\n","import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport PropTypes from 'prop-types';\n\nimport { notification } from 'antd';\n\nimport { forwardTo } from 'utils/common/route';\nimport { ThumbnailItem } from 'common/components';\n\nimport AssetQuery from 'assets/query/AssetQuery.png';\nimport ProductQuery from 'assets/query/ProductQuery.png';\nimport MemberQuery from 'assets/query/MemberQuery.png';\nimport FolderQuery from 'assets/query/FolderQuery.png';\nimport ReportQuery from 'assets/query/ReportQuery.png';\n\nimport { RIBBON_TYPES } from 'static/Constants';\nimport * as actionsRibbon from '@redux/ribbon/actions';\nimport * as ribbonSelectors from '@redux/ribbon/selectors';\nimport * as actionsGlobal from '@redux/global/actions';\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\nimport { updateSearchText } from 'pages/home/utils';\n\nimport {\n updateQueryConditions,\n updateQueryAdvance,\n updateIdQuery,\n} from 'utils/queryCondition';\nimport { Images } from 'config/assets';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/home';\n\nconst QueryThumbnail = (props) => {\n const intl = useIntl();\n const dispatch = useDispatch();\n\n const { dataDetail, selected, onClickItemGrid, onClickCheckboxItem } = props;\n\n const {\n queryConditions,\n columns,\n ribbonTypes,\n urlForwardTo,\n searchText,\n primaryFieldsOnly,\n } = JSON.parse(dataDetail?.query);\n\n const closeDetailStack = useSelector(\n ribbonSelectors.selectCloseDetailStack()\n );\n\n const onDoubleClick = (item) => {\n dispatch(actionsGridView.myQueryDoubleClick(true));\n\n const invalidQuery = !urlForwardTo;\n\n if (invalidQuery) {\n showErrorMessage();\n return;\n }\n\n pushCloseDetailStack(urlForwardTo);\n forwardTo(`${urlForwardTo}?query=1`);\n\n if (ribbonTypes === RIBBON_TYPES.DETAILSVIEW) {\n dispatch(actionsGridView.chooseGridColumns(columns, dataDetail?.id));\n } else {\n dispatch(actionsGridView.chooseGridColumns([], dataDetail?.id));\n }\n updateQueryConditions(dispatch, queryConditions, urlForwardTo, true);\n updateQueryAdvance(dispatch, queryConditions, urlForwardTo, true);\n updateIdQuery(dispatch, dataDetail?.id, urlForwardTo, true);\n\n dispatch(actionsRibbon.changeType(ribbonTypes));\n dispatch(actionsGridView.updateVisible(false));\n dispatch(actionsGlobal.updateIsBackFromQuery(true));\n updateSearchText(\n dispatch,\n searchText,\n urlForwardTo,\n true,\n primaryFieldsOnly\n );\n dispatch(actionsGridView.checkQueryCondition(true));\n\n setTimeout(() => {\n dispatch(actionsGridView.toggleRefreshQuery(true));\n dispatch(actionsGridView.updatePrevPathnameQuery(urlForwardTo));\n }, 200);\n };\n\n const showErrorMessage = () => {\n notification.error({\n message: intl.formatMessage(Messages.queryOpenError),\n });\n };\n\n const pushCloseDetailStack = (urlForwardTo) => {\n const { name, stack } = closeDetailStack;\n dispatch(\n actionsRibbon.updateCloseDetailStack({\n name,\n stack: [...stack, urlForwardTo],\n })\n );\n };\n\n let image =\n dataDetail?.gridName === 'member-detail-grid'\n ? MemberQuery\n : dataDetail?.gridName === 'digital-asset-detail-grid'\n ? AssetQuery\n : dataDetail?.gridName === 'folder-detail-grid'\n ? FolderQuery\n : dataDetail?.gridName === 'products-for-member' ||\n dataDetail?.gridName === 'product-detail-grid'\n ? ProductQuery\n : dataDetail?.gridName === 'assets-for-member'\n ? AssetQuery\n : dataDetail?.gridName === 'query-reporting-grid'\n ? ReportQuery\n : Images.RIVIR_LOGO_DEFAULT;\n\n return (\n \n );\n};\n\nQueryThumbnail.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default React.memo(QueryThumbnail);\n","import React from 'react';\nimport { Typography, Space, Row } from 'antd';\nimport { get } from 'lodash';\nimport PropTypes from 'prop-types';\nimport { FormattedMessage } from 'react-intl';\nimport Messages from 'i18n/messages/folder';\nimport { formatSizeUnits } from 'utils/formatSizeUnits';\n\nconst { Paragraph, Title, Text } = Typography;\n\nconst QueryTileBody = (props) => {\n const { dataDetail } = props;\n\n const name = get(dataDetail, 'name', '');\n // const folderSize = get(dataDetail, 'folderSize', 0);\n // const productCount = get(dataDetail, 'productCount', 0);\n // const assetCount = get(dataDetail, 'assetCount', 0);\n const ownerName = get(dataDetail, 'ownerFullName', '');\n // const memberName = get(dataDetail, 'memberName', '');\n\n const infoText = [\n {\n field: 'name',\n value: name,\n },\n {\n field: 'ownerName',\n value: ownerName,\n },\n // {\n // field: 'memberName',\n // value: memberName,\n // },\n // {\n // field: 'folderSize',\n // value: folderSize,\n // },\n // {\n // field: 'productCount',\n // value: productCount,\n // },\n // {\n // field: 'assetCount',\n // value: assetCount,\n // },\n ];\n\n const renderQueryBodyInfo = (infoText) => {\n return infoText.map(({ field, value }, index) => {\n if (field === 'name') {\n return (\n \n {value}\n \n );\n } else if (field === 'folderSize') {\n return (\n \n {formatSizeUnits(value)}\n \n );\n } else if (field === 'productCount' || field === 'assetCount') {\n let text;\n if (field === 'productCount') {\n text =\n value > 0 ? (\n \n ) : (\n \n );\n } else {\n text =\n value > 0 ? (\n \n ) : (\n \n );\n }\n return value > 0 ? (\n \n {value} {text}\n \n ) : null;\n } else {\n return (\n value && (\n \n {value}\n \n )\n );\n }\n });\n };\n\n return (\n
\n \n \n {renderQueryBodyInfo(infoText)}\n \n \n
\n );\n};\n\nQueryTileBody.propTypes = {\n dataDetail: PropTypes.object,\n};\n\nexport default QueryTileBody;\n","import React from 'react';\nimport { Row, Col } from 'antd';\n\nimport { formatMDY } from 'utils/formatDate';\nimport { get } from 'lodash';\nimport PropTypes from 'prop-types';\nimport { FormattedMessage } from 'react-intl';\nimport Messages from 'i18n/messages/folder';\n\nconst QueryTileFooter = (props) => {\n const { dataDetail } = props;\n\n const dateCreated = get(dataDetail, 'created', '');\n const lastUpdated = get(dataDetail, 'lastModified', '');\n\n return (\n \n \n \n \n \n \n {dateCreated && formatMDY(dateCreated)}\n \n \n \n \n \n {lastUpdated && formatMDY(lastUpdated)}\n \n \n \n );\n};\n\nQueryTileFooter.propTypes = {\n size: PropTypes.string,\n lastUpdate: PropTypes.string,\n};\n\nexport default QueryTileFooter;\n","import React from 'react';\nimport { Row, Avatar } from 'antd';\nimport PropTypes from 'prop-types';\n\nimport AssetQuery from 'assets/query/AssetQuery.png';\nimport ProductQuery from 'assets/query/ProductQuery.png';\nimport MemberQuery from 'assets/query/MemberQuery.png';\nimport FolderQuery from 'assets/query/FolderQuery.png';\nimport ReportQuery from 'assets/query/ReportQuery.png';\nimport { Images } from 'config/assets';\n\nconst QueryTileHeader = (props) => {\n const { dataDetail } = props;\n let image =\n dataDetail?.gridName === 'member-detail-grid'\n ? MemberQuery\n : dataDetail?.gridName === 'digital-asset-detail-grid'\n ? AssetQuery\n : dataDetail?.gridName === 'folder-detail-grid'\n ? FolderQuery\n : dataDetail?.gridName === 'products-for-member' ||\n dataDetail?.gridName === 'product-detail-grid'\n ? ProductQuery\n : dataDetail?.gridName === 'assets-for-member'\n ? AssetQuery\n : dataDetail?.gridName === 'query-reporting-grid'\n ? ReportQuery\n : Images.RIVIR_LOGO_DEFAULT;\n\n return (\n \n
\n\n
\n \n
\n
\n );\n};\n\nQueryTileHeader.propTypes = {\n dataDetail: PropTypes.object,\n};\n\nexport default QueryTileHeader;\n","import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Tooltip, notification } from 'antd';\nimport { QueryTileBody, QueryTileFooter, QueryTileHeader } from '../index';\nimport { get } from 'lodash';\nimport useDoubleClick from 'hooks/useDoubleClick';\nimport './QueryTile.less';\n\nimport { forwardTo } from 'utils/common/route';\n\nimport { RIBBON_TYPES } from 'static/Constants';\nimport * as actionsRibbon from '@redux/ribbon/actions';\nimport * as ribbonSelectors from '@redux/ribbon/selectors';\nimport * as actionsGlobal from '@redux/global/actions';\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\nimport { updateSearchText } from 'pages/home/utils';\n\nimport {\n updateQueryConditions,\n updateQueryAdvance,\n updateIdQuery,\n} from 'utils/queryCondition';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/home';\n\nconst QueryTile = (props) => {\n const intl = useIntl();\n const dispatch = useDispatch();\n\n const { dataDetail, disableEvent } = props;\n const { onClickItemGrid } = props.clickEvents;\n const name = get(dataDetail, 'name', '');\n\n const pathname = window.location.pathname;\n const {\n queryConditions,\n columns,\n ribbonTypes,\n urlForwardTo,\n searchText,\n primaryFieldsOnly,\n } = JSON.parse(dataDetail?.query);\n\n const closeDetailStack = useSelector(\n ribbonSelectors.selectCloseDetailStack()\n );\n\n const divRef = React.useRef();\n useDoubleClick({\n onSingleClick: (e) => {\n if (onClickItemGrid) onClickItemGrid(dataDetail, e);\n },\n onDoubleClick: (e) => {\n const invalidQuery = !urlForwardTo;\n\n if (invalidQuery) {\n showErrorMessage();\n return;\n }\n\n pushCloseDetailStack(urlForwardTo);\n forwardTo(`${urlForwardTo}?query=1`);\n\n dispatch(actionsGridView.myQueryDoubleClick(true));\n if (ribbonTypes === RIBBON_TYPES.DETAILSVIEW) {\n dispatch(actionsGridView.chooseGridColumns(columns, dataDetail?.id));\n } else {\n dispatch(actionsGridView.chooseGridColumns([], dataDetail?.id));\n }\n\n updateQueryConditions(\n dispatch,\n queryConditions,\n window.location.pathname,\n true\n );\n updateQueryAdvance(\n dispatch,\n queryConditions,\n window.location.pathname,\n true\n );\n updateIdQuery(dispatch, dataDetail?.id, window.location.pathname, true);\n\n dispatch(actionsRibbon.changeType(ribbonTypes));\n dispatch(actionsGridView.updateVisible(false));\n dispatch(actionsGlobal.updateIsBackFromQuery(true));\n updateSearchText(\n dispatch,\n searchText,\n urlForwardTo,\n true,\n primaryFieldsOnly\n );\n dispatch(actionsGridView.checkQueryCondition(true));\n\n setTimeout(() => {\n dispatch(actionsGridView.toggleRefreshQuery(true));\n dispatch(actionsGridView.updatePrevPathnameQuery(urlForwardTo));\n }, 200);\n },\n ref: divRef,\n latency: 250,\n });\n\n const showErrorMessage = () => {\n notification.error({\n message: intl.formatMessage(Messages.queryOpenError),\n });\n };\n\n const pushCloseDetailStack = (urlForwardTo) => {\n const { name, stack } = closeDetailStack;\n dispatch(\n actionsRibbon.updateCloseDetailStack({\n name,\n stack: [...stack, urlForwardTo],\n })\n );\n };\n\n return (\n \n
\n {/*Placeholder for click events*/}\n \n \n \n \n
\n
\n );\n};\n\nexport default QueryTile;\n","import React, { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Image, Typography } from 'antd';\n\nimport AssetQuery from 'assets/query/AssetQuery.png';\nimport ProductQuery from 'assets/query/ProductQuery.png';\nimport MemberQuery from 'assets/query/MemberQuery.png';\nimport FolderQuery from 'assets/query/FolderQuery.png';\nimport ReportQuery from 'assets/query/ReportQuery.png';\nimport { Images } from 'config/assets';\n\nimport { InfoWithLabel } from 'common/components';\nimport { formatMDY } from 'utils/formatDate';\n\nimport AdvancedSearchTitle from 'common/components/advanced-search/AdvancedSearchTitle';\nimport QueryConditions from 'common/components/grid-view/components/content-pane/advancedFilter/QueryConditions';\nimport PropertyAdvancedFilter from 'common/components/grid-view/components/content-pane/advancedFilter/PropertyAdvancedFilter';\nimport { useAdvanceFilter } from 'common/components/nested-advance-Search/hook/hook';\n\nimport './QueryPanel.less';\n\nconst QueryPanel = ({ dataDetail }) => {\n const [propertiesData, setPropertiesData] = useState();\n\n let image =\n dataDetail?.gridName === 'member-detail-grid'\n ? MemberQuery\n : dataDetail?.gridName === 'digital-asset-detail-grid'\n ? AssetQuery\n : dataDetail?.gridName === 'folder-detail-grid'\n ? FolderQuery\n : dataDetail?.gridName === 'products-for-member' ||\n dataDetail?.gridName === 'product-detail-grid'\n ? ProductQuery\n : dataDetail?.gridName === 'assets-for-member'\n ? AssetQuery\n : dataDetail?.gridName === 'query-reporting-grid'\n ? ReportQuery\n : Images.RIVIR_LOGO_DEFAULT;\n\n const infoColProps = {\n infoColProps: {\n flex: 'auto',\n },\n labelColProps: {\n flex: '130px',\n },\n boldInfo: true,\n labelAlign: 'right',\n };\n\n const query = JSON.parse(dataDetail?.query || {});\n\n const { fetchEntityAttribute } = useAdvanceFilter({});\n const emptyFunc = () => {};\n\n const handleGetEntity = async () => {\n try {\n const data = await fetchEntityAttribute(dataDetail?.queryType);\n if (data) {\n setPropertiesData(data);\n }\n } catch (error) {}\n };\n\n useEffect(() => {\n handleGetEntity();\n }, [dataDetail?.queryType]);\n\n return (\n \n \n \n \n \n \n \n {/* */}\n {dataDetail?.name}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nQueryPanel.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nexport default QueryPanel;\n","import { Space } from 'antd';\n\nimport { AgGridIcons } from 'common/components';\n\nimport { renderPathname } from 'pages/folders/folder-details/utils';\n\nimport { TooltipParagraph } from 'common/components';\n\nimport { Images } from 'config/assets';\nimport { ITEM_TYPE } from 'static/Constants';\n\nimport reactCSS from 'reactcss';\n\nexport const QueryLink = (props) => {\n const { value, data } = props;\n\n const { id } = data || {};\n\n const onClickLink = (e) => {\n const url = `/execute-query/${id}`;\n\n window.open(url).focus();\n //* query execution is handled in execute-query/index\n };\n\n return (\n \n {value}\n \n );\n};\n\nconst NormalDetailLink = (props) => {\n const { data, value } = props;\n const pathname = renderPathname(data?.type);\n\n const url = pathname ? `/${pathname}/${data?.id}` : window.location.pathname;\n\n const onClickLink = () => {\n window.open(url, '_blank').focus();\n };\n\n return (\n \n \n {value}\n \n \n );\n};\n\nconst renderLink = (params) => {\n const { data } = params;\n\n const { type } = data || {};\n\n if (ITEM_TYPE.query.includes(type.toLowerCase())) {\n return ;\n }\n\n return ;\n};\n\nconst renderFavSharePackIcons = (params) => {\n const data = params?.data;\n\n return (\n \n );\n};\n\nconst renderFolderOptionIcon = (params) => {\n const { isOwner, items } = params?.data || {};\n\n const styles = reactCSS({\n default: {\n img: { width: 'auto', height: 'auto', maxWidth: 24, maxHeight: 24 },\n },\n });\n\n return (\n \n {isOwner ? (\n items > 0 ? (\n owner\n ) : (\n owner\n )\n ) : (\n shared\n )}\n \n );\n};\n\nconst customCellComponents = {\n renderLink,\n renderFavSharePackIcons,\n renderFolderOptionIcon,\n};\n\nexport default customCellComponents;\n","import React from 'react';\n\nimport { Tooltip } from 'antd';\nimport { ClockCircleOutlined } from '@ant-design/icons';\n\nconst FolderDownloadScheduledIcon = (props) => {\n const { visible = false } = props;\n\n return visible ? (\n \n \n \n ) : null;\n};\n\nexport default FolderDownloadScheduledIcon;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { ThumbnailItem } from 'common/components';\nimport FolderDownloadScheduledIcon from '../icons/FolderDownloadScheduledIcon';\n\nimport * as getLink from 'utils/common/linkBuilder';\n\nimport './FolderThumbnail.less';\nimport { getThumbnailImage } from '../utils';\n\n/**\n * Folder thumbnail is inherit from thumbnail item\n * @param {object} props\n */\nconst FolderThumbnailCard = (props) => {\n const {\n dataDetail,\n selected,\n onClickItemGrid,\n onClickCheckboxItem,\n disableEvent,\n } = props;\n\n const type = dataDetail?.type?.toLowerCase();\n const image = getThumbnailImage(dataDetail, type);\n\n const alink = getLink.folderLink(\n dataDetail?.id,\n dataDetail?.folderName,\n dataDetail?.type\n );\n\n return (\n ,\n ]}\n />\n );\n};\n\nFolderThumbnailCard.propTypes = {\n dataDetail: PropTypes.object.isRequired,\n};\n\nFolderThumbnailCard.defaultProps = {\n disableEvent: false,\n};\n\nexport default React.memo(FolderThumbnailCard);\n","import React from 'react';\n\nimport { Tooltip } from 'antd';\nimport { get } from 'lodash';\n\nimport { FolderTileBody, FolderTileFooter, FolderTileHeader } from '../index';\n\nimport useDoubleClick from 'hooks/useDoubleClick';\n\nimport { forwardTo } from 'utils/common/route';\nimport './FolderTile.less';\n\nconst FolderTile = (props) => {\n const { dataDetail, pathname, disableEvent } = props;\n const { onClickItemGrid, onDoubleClick } = props?.clickEvents || {};\n\n const folderName = get(dataDetail, 'folderName', '');\n\n const divRef = React.useRef();\n\n useDoubleClick({\n onSingleClick: (e) => {\n if (disableEvent) return;\n if (onClickItemGrid) onClickItemGrid(dataDetail, e);\n },\n onDoubleClick: (e) => {\n if (disableEvent) return;\n if (onDoubleClick) {\n forwardTo(`${pathname}/${dataDetail?.id}`);\n }\n },\n ref: divRef,\n latency: 250,\n isEnabled: !disableEvent,\n });\n\n return (\n \n
\n {disableEvent ? null : (\n \n )}\n \n \n \n
\n
\n );\n};\n\nexport default FolderTile;\n","import React from 'react';\nimport { Row, Avatar } from 'antd';\nimport PropTypes from 'prop-types';\nimport { Images } from 'config/assets';\nimport { getThumbnailImage } from '../utils';\n\nconst FolderTileHeader = (props) => {\n const { dataDetail } = props;\n\n const type = dataDetail?.type?.toLowerCase();\n const image = getThumbnailImage(dataDetail, type);\n\n return (\n \n
\n\n
\n \n
\n
\n );\n};\n\nFolderTileHeader.propTypes = {\n dataDetail: PropTypes.object,\n};\n\nexport default FolderTileHeader;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Typography, Space, Row, Tooltip } from 'antd';\nimport { get, capitalize } from 'lodash';\n\nimport FolderDownloadScheduledIcon from '../icons/FolderDownloadScheduledIcon';\n\nimport { formatSizeUnits } from 'utils/formatSizeUnits';\nimport { entityTypeIcon } from 'utils/entityTypeIcon';\n\nimport { FormattedMessage } from 'react-intl';\nimport Messages from 'i18n/messages/folder';\n\nconst { Paragraph, Title, Text } = Typography;\n\nconst FolderTileBody = (props) => {\n const { dataDetail } = props;\n\n const folderName = get(dataDetail, 'folderName', '');\n const folderSize = get(dataDetail, 'folderSize', 0);\n const productCount = get(dataDetail, 'productCount', 0);\n const assetCount = get(dataDetail, 'assetCount', 0);\n const ownerName = get(dataDetail, 'ownerName', '');\n const memberName = get(dataDetail, 'memberName', '');\n\n const isFolder = dataDetail?.type?.toLowerCase() === 'folder';\n\n const infoText = [\n {\n field: 'folderName',\n value: folderName,\n },\n {\n field: 'ownerName',\n value: ownerName,\n },\n {\n field: 'memberName',\n value: memberName,\n },\n {\n field: 'folderSize',\n value: folderSize,\n },\n {\n field: 'productCount',\n value: productCount,\n },\n {\n field: 'assetCount',\n value: assetCount,\n },\n ];\n\n const renderFolderBodyInfo = (infoText) => {\n return infoText.map(({ field, value }, index) => {\n if (field === 'folderName') {\n return (\n \n {value}\n \n );\n } else if (isFolder) {\n if (field === 'folderSize') {\n return (\n \n {formatSizeUnits(value)}\n \n );\n } else if (field === 'productCount' || field === 'assetCount') {\n let text;\n if (field === 'productCount') {\n text =\n value > 0 ? (\n \n ) : (\n \n );\n } else {\n text =\n value > 0 ? (\n \n ) : (\n \n );\n }\n return value > 0 ? (\n \n {value} {text}\n \n ) : null;\n } else {\n return (\n value && (\n \n {value}\n \n )\n );\n }\n }\n });\n };\n\n return (\n
\n \n \n {renderFolderBodyInfo(infoText)}\n \n \n \n {!isFolder ? (\n \n \n {entityTypeIcon(dataDetail?.type)}\n \n \n ) : null}\n \n \n
\n );\n};\n\nFolderTileBody.propTypes = {\n dataDetail: PropTypes.object,\n};\n\nexport default FolderTileBody;\n","import React from 'react';\nimport { Row, Col } from 'antd';\n\nimport { formatMDY } from 'utils/formatDate';\nimport { get } from 'lodash';\nimport PropTypes from 'prop-types';\nimport { FormattedMessage } from 'react-intl';\nimport Messages from 'i18n/messages/folder';\n\nconst FolderTileFooter = (props) => {\n const { dataDetail } = props;\n\n const dateCreated = get(dataDetail, 'dateCreated', '');\n const lastUpdated = get(dataDetail, 'lastUpdated', '');\n\n return (\n \n \n \n \n \n \n {dateCreated && formatMDY(dateCreated)}\n \n \n \n \n \n {lastUpdated && formatMDY(lastUpdated)}\n \n \n \n );\n};\n\nFolderTileFooter.propTypes = {\n size: PropTypes.string,\n lastUpdate: PropTypes.string,\n};\n\nexport default FolderTileFooter;\n","import React, { useEffect } from 'react';\n\nimport { useSelector, useDispatch } from 'react-redux';\n\nimport PropTypes from 'prop-types';\nimport { formatMDY } from 'utils/formatDate';\nimport { Input, Checkbox, Col, Row, Spin, DatePicker, Select } from 'antd';\n\nimport { Form, WrapperSelect } from 'common/components';\n\nimport { FormattedMessage } from 'react-intl';\nimport Message from 'i18n/messages/folder';\nimport { Images } from 'config/assets';\nimport moment from 'moment';\nimport { getDateFormat } from 'utils/formatDate';\n\nimport * as companySelectors from 'pages/company-profile/controllers/selectors';\n\nimport userSelectors from '@redux/user/selectors';\n\nimport * as memberActions from 'pages/company-profile/controllers/actions';\n\nimport memberReducer from 'pages/company-profile/controllers/reducer';\nimport saga from 'pages/company-profile/controllers/saga';\n\nimport { useInjectSaga } from 'utils/common/injectSaga';\nimport { useInjectReducer } from 'utils/common/injectedReducers';\n\nimport {\n PRIVATE_FOLDER_VISIBILITY,\n FOLDER_VISIBILITY,\n DATE_FORMAT,\n} from 'static/Constants';\n\nimport './FolderPanelEditContent.less';\n\nconst formItemLayout = {\n labelCol: { span: 10 },\n wrapperCol: { span: 14 },\n};\n\nconst dateFormat = 'YYYY/MM/DD';\n\nconst FolderPanelEditContent = (props) => {\n useInjectReducer({ key: 'member', reducer: memberReducer });\n useInjectSaga({ key: 'member', saga });\n\n const dispatch = useDispatch();\n\n const {\n folderInfo,\n onFinish,\n onFinishFailed,\n onValuesChange,\n form,\n ownerFolder,\n loading,\n } = props;\n\n const userInfo = useSelector(userSelectors.makeSelectUserInfo());\n\n useEffect(() => {\n dispatch(memberActions.getMemberProfileHeader(userInfo?.member?.id));\n }, [dispatch, userInfo?.member?.id]);\n\n const memberInfo = useSelector(companySelectors.selectMemberProfile());\n\n const isPrivateVisibilityFolder = memberInfo?.folders === 'Private';\n\n const RenderFolderImg = () => {\n let img = !ownerFolder\n ? Images.sharedFolder\n : folderInfo?.items > 0\n ? Images.folder\n : Images.emptyFolder;\n\n return (\n folder\n );\n };\n\n function disabledDate(current) {\n // Can not select days before today and today\n return current && current < moment().endOf('day');\n }\n\n const FieldItemInputDisabled = ({ data }) => {\n return (\n }\n >\n \n \n );\n };\n\n const FieldItemInputCanEdit = ({ data }) => {\n return (\n }\n >\n }\n />\n \n );\n };\n\n const FieldItemCheckboxDisabled = ({ data }) => {\n return (\n }\n valuePropName='checked'\n >\n \n \n );\n };\n\n const FieldItemCheckbox = ({ data }) => {\n return (\n }\n valuePropName='checked'\n >\n \n \n );\n };\n const FieldItemRangePicker = ({ data }) => {\n return (\n }\n >\n \n \n );\n };\n return (\n \n \n \n \n \n \n \n }\n rules={[\n {\n required: true,\n message: (\n \n ),\n },\n {\n whitespace: true,\n message: (\n \n ),\n },\n ]}\n className='folder-panel-edit-content__folder-name'\n >\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {isPrivateVisibilityFolder\n ? PRIVATE_FOLDER_VISIBILITY?.slice()\n .sort()\n .map((visibility) => (\n \n {visibility}\n \n ))\n : FOLDER_VISIBILITY?.slice()\n .sort()\n .map((visibility) => (\n \n {visibility}\n \n ))}\n \n \n \n \n \n \n \n \n );\n};\n\nFolderPanelEditContent.propTypes = {\n folderInfo: PropTypes.object,\n onFinish: PropTypes.func,\n onFinishFailed: PropTypes.func,\n onValuesChange: PropTypes.func,\n form: PropTypes.object,\n ownerFolder: PropTypes.bool,\n};\n\nexport default FolderPanelEditContent;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Button, Row, Space } from 'antd';\nimport { StopOutlined, SaveOutlined } from '@ant-design/icons';\nimport { FormattedMessage } from 'react-intl';\nimport Message from 'i18n/messages/folder';\nimport './FolderPanelEditHeader.less';\n\nconst FolderPanelEditHeader = (props) => {\n const { onCancelClick, onSaveClick, disableSaveBtn } = props;\n return (\n \n \n }\n >\n \n \n }\n >\n \n \n \n \n );\n};\n\nFolderPanelEditHeader.propTypes = {\n onCancelClick: PropTypes.func,\n onSaveClick: PropTypes.func,\n disableSaveBtn: PropTypes.bool,\n};\n\nFolderPanelEditHeader.defaultProps = {\n disableSaveBtn: true,\n};\n\nexport default FolderPanelEditHeader;\n","import React, { useState, useEffect } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { Row, Typography, Tooltip, Pagination, notification, Col } from 'antd';\nimport { AgGridReact, AgGridColumn } from 'ag-grid-react';\nimport moment from 'moment';\nimport { dialogFunction } from 'common/components/index';\nimport { LicenseManager } from 'ag-grid-enterprise';\nimport 'ag-grid-enterprise';\nimport 'ag-grid-community/dist/styles/ag-grid.css';\nimport 'ag-grid-community/dist/styles/ag-theme-alpine.css';\nimport { injectIntl } from 'react-intl';\nimport Messages from 'i18n/messages/folder';\nimport * as folderService from 'services/folder';\nimport DigitalRightIcon from 'common/components/digital-right-icon/DigitalRightIcon';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\n\nimport {\n DeleteOutlined,\n CodeSandboxOutlined,\n PlaySquareOutlined,\n UserOutlined,\n QuestionOutlined,\n SearchOutlined,\n SnippetsOutlined,\n} from '@ant-design/icons';\n\nLicenseManager.setLicenseKey(\n 'Using_this_AG_Grid_Enterprise_key_( AG-040843 )_in_excess_of_the_licence_granted_is_not_permitted___Please_report_misuse_to_( legal@ag-grid.com )___For_help_with_changing_this_key_please_contact_( info@ag-grid.com )___( Global Vertical Innovations, LLC )_is_granted_a_( Multiple Applications )_Developer_License_for_( 1 ))_Front-End_JavaScript_developer___All_Front-End_JavaScript_developers_need_to_be_licensed_in_addition_to_the_ones_working_with_AG_Grid_Enterprise___This_key_has_not_been_granted_a_Deployment_License_Add-on___This_key_works_with_AG_Grid_Enterprise_versions_released_before_( 11 May 2024 )____[v2]_MTcxNTM4MjAwMDAwMA==d035e6c32ae72202e23beccd712ab105'\n);\n\nconst { Title } = Typography;\n\nfunction iconRenderer(params) {\n if (params.data.type.toLowerCase() === 'product')\n return (\n <>\n \n \n \n {params.data.drm && (\n \n )}\n \n );\n else if (params.data.type === 'asset')\n return (\n <>\n \n \n \n {params.data.drm && (\n \n )}\n \n );\n else if (params.data.type === 'member')\n return (\n <>\n \n \n \n {params.data.drm && (\n \n )}\n \n );\n else if (params.data.type === 'Query')\n return (\n <>\n \n \n \n {params.data.drm && (\n \n )}\n \n );\n else if (params.data.type === 'Reporting')\n return (\n <>\n \n \n \n {params.data.drm && (\n \n )}\n \n );\n else return ;\n}\n\n// function digitalRightIconRender(params) {\n// if (params.data.drm)\n// return (\n// \n// );\n// else return null;\n// }\n\nfunction dateFormatter(params) {\n return moment(params.value).format('MM/DD/YYYY');\n}\n\nfunction convertNodeData(nodes) {\n const result = nodes.map((node) => node.data);\n return result;\n}\n\nfunction coverNewData(rowsSelection, gridRowsSelection, itemSelection) {\n let result = rowsSelection;\n\n const idxRows = result.findIndex((row) => row.id === itemSelection.id);\n const idxGridRows = gridRowsSelection.findIndex(\n (row) => row.id === itemSelection.id\n );\n\n if (idxRows !== -1 && idxGridRows === -1) {\n result = result.filter((row) => row.id !== itemSelection.id);\n return result;\n }\n\n // Set value: { {}, {} } -> Array.from -> [{}, {}]\n result = Array.from(new Set([...rowsSelection, ...gridRowsSelection]));\n return result;\n}\n\nconst PanelContent = (props) => {\n const dispatch = useDispatch();\n const reloadPage = useDispatchReloadPage();\n\n const { ownerFolder, shortDetail, seePreview, isEdit, intl } = props;\n const [currentPage, setCurrentPage] = useState(1);\n const [currentPageSize, setCurrentPageSize] = useState(10);\n\n const [gridApi, setGridApi] = useState();\n const [selectedRows, setSelectedRows] = useState([]);\n const [selectedItem, setSelectedItem] = useState();\n\n useEffect(() => {\n if (!gridApi) return;\n\n gridApi.forEachNode((node) => {\n const idxRow = selectedRows.findIndex(\n (selectedRow) => selectedRow.id === node.data.id\n );\n if (idxRow !== -1) {\n node.setSelected(true);\n } else {\n node.setSelected(false);\n }\n });\n setSelectedItem({});\n }, [currentPage, gridApi, selectedRows]);\n\n const getAgGridProps = (rowData = []) => {\n return {\n headerHeight: 32,\n rowHeight: 32,\n rowSelection: 'multiple',\n // rowMultiSelectWithClick: true,\n rowData: rowData.filter((item, index) => {\n return (\n index >= (currentPage - 1) * currentPageSize &&\n index <= currentPageSize * currentPage - 1\n );\n }),\n pivotPanelShow: 'never',\n onRowClicked: (params) => {\n setSelectedItem(params.data);\n // setSelectedRows([params.data]);\n },\n onRowDoubleClicked: (params) => {\n if (seePreview) seePreview(params.data);\n },\n onSelectionChanged: () => {\n const selectedNodes = gridApi.getSelectedNodes();\n const selectedDataNodes = convertNodeData(selectedNodes);\n // const result = coverNewData(\n // selectedRows,\n // selectedDataNodes,\n // selectedItem\n // );\n setSelectedRows(selectedDataNodes);\n },\n onCellClicked: (params) => {\n if (params.colDef.field === '' && seePreview) seePreview(params.data);\n },\n onGridReady: onGridReady,\n };\n };\n\n const onGridReady = (params) => {\n setGridApi(params.api);\n };\n const gridColumn = [\n {\n key: '1',\n field: '',\n width: 70,\n cellRendererFramework: iconRenderer,\n menuTabs: [],\n },\n // {\n // key: '2',\n // field: 'drm',\n // cellRendererFramework: digitalRightIconRender,\n // width: 30,\n // menuTabs: [],\n // },\n {\n key: '2',\n field: 'description',\n width: 300,\n menuTabs: [],\n },\n {\n key: '3',\n field: 'dateAdded',\n cellRendererFramework: dateFormatter,\n width: 130,\n menuTabs: [],\n },\n ];\n const rowData =\n shortDetail && shortDetail.folderContents ? shortDetail.folderContents : [];\n\n const confirmDelete = () => {\n if (selectedRows.length > 0) {\n dialogFunction({\n type: 'warn',\n content: intl.formatMessage(Messages.areYouSureToDelete),\n onOk: callApiDelete,\n });\n } else {\n notification.warn({\n message: 'Must select at least one items to delete.',\n });\n }\n };\n\n const callApiDelete = async () => {\n const itemList = selectedRows.map((item) => {\n return { id: item.id, type: item.type };\n });\n\n try {\n const response =\n await folderService.deleteEntityAssocicationFromShortContent({\n folderId: shortDetail?.id,\n itemList,\n });\n const { isSuccess, message } = response;\n if (isSuccess) {\n if (currentPage !== 1) {\n setCurrentPage(1);\n }\n setSelectedRows([]);\n\n showSuccessMessageDialog();\n reloadPage();\n } else {\n callApiErrorHandler(message);\n }\n } catch (error) {\n callApiErrorHandler(error);\n }\n };\n\n const showSuccessMessageDialog = () => {\n notification.success({\n message: intl.formatMessage(Messages.deleteSuccess),\n });\n };\n\n const callApiErrorHandler = (error) => {\n notification.error({\n message: error,\n });\n };\n\n return (\n
\n \n \n {intl.formatMessage({\n id: 'Taco.folder.components.contentPane.content',\n })}\n \n {isEdit && (\n
\n \n \n \n
\n )}\n
\n\n \n \n {gridColumn?.map((column) => (\n \n ))}\n \n
\n
\n {\n setCurrentPage(page);\n setCurrentPageSize(size);\n }}\n pageSize={currentPageSize}\n defaultCurrent={currentPage}\n total={rowData && rowData.length}\n />\n
\n {rowData.filter((item) => item.drm).length > 0 && (\n \n \n \n \n \n {intl.formatMessage({\n id: 'Taco.common.components.folderDRM',\n })}\n \n \n )}\n {\n setSelectedRows([]);\n setCurrentPageSize(10);\n setCurrentPage(1);\n }}\n id='button-clear-table-item'\n >\n test\n \n \n );\n};\n\nexport default injectIntl(PanelContent);\n","import React, { useEffect, useState } from 'react';\nimport PropTypes, { bool } from 'prop-types';\nimport { useDispatch, useSelector, shallowEqual } from 'react-redux';\nimport { Form, message, notification } from 'antd';\n\nimport * as actionsGrid from 'common/components/grid-view/controllers/actions';\nimport PanelEditContent from './FolderPanelEditContent';\nimport PanelHeader from './FolderPanelEditHeader';\nimport moment from 'moment';\nimport * as actions from '../../controllers/actions';\nimport * as selectors from '../../controllers/selectors';\n\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\nimport FolderPanelContent from '../panel/FolderPanelContent.old';\n\nimport './FolderPanelEdit.less';\nimport { formatMDY } from 'utils/formatDate';\n\nconst FolderPanelEdit = (props) => {\n const { folderInfo, onCloseEdit, ownerFolder, loadingDetail } = props;\n const dispatch = useDispatch();\n const reloadPage = useDispatchReloadPage();\n\n const [disableSaveBtn, setDisableSaveBtn] = useState(true);\n\n const startEdit = useSelector(selectors.selectStartEdit());\n const editSuccess = useSelector(selectors.selectEditSuccess());\n\n let folderInfoOrgin = {\n folderName: folderInfo?.folderName,\n specialPurpose: folderInfo?.specialPurpose,\n };\n\n const [form] = Form.useForm();\n\n useEffect(() => {\n form.setFieldsValue({\n folderName: folderInfo?.folderName,\n specialPurpose: folderInfo?.specialPurpose,\n visibility: folderInfo?.visibility,\n });\n // eslint-disable-next-line\n }, [folderInfo?.folderName, folderInfo?.specialPurpose]);\n\n useEffect(() => {\n if (startEdit === 'finish') {\n if (editSuccess === 'success') {\n handleEditSuccess();\n } else if (editSuccess === 'error') {\n handleEditError();\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [startEdit, editSuccess]);\n\n const onFinishFailed = (errorInfo) => {\n console.log('onFinishFailed: ', errorInfo);\n };\n\n const isFormChanged = (fieldsValue) => {\n if (!shallowEqual(folderInfoOrgin, fieldsValue)) {\n return true;\n }\n return false;\n };\n\n const onFinish = (values) => {\n let id = folderInfo.id;\n if (isFormChanged(values)) {\n dispatch(\n actions.editShortContent({\n ...values,\n expirationDate: values?.expirationDate\n ? moment(values?.expirationDate)\n : formatMDY(folderInfo?.expirationDate),\n id,\n })\n );\n } else {\n notification.info({\n message: \"Folder information doesn't change!\",\n placement: 'topRight',\n duration: 1,\n });\n setTimeout(() => {\n onCloseEdit();\n }, 200);\n }\n };\n\n const onSaveClick = () => {\n form.submit();\n };\n\n const handleEditSuccess = () => {\n setTimeout(() => {\n dispatch(actions.editShortContentFinish());\n onCloseEdit();\n\n reloadPage();\n setTimeout(() => {\n dispatch(actionsGrid.updateItemsSelection([folderInfo.id]));\n dispatch(actions.getFolderShortDetail(folderInfo.id));\n }, 400);\n }, 500);\n };\n\n const handleEditError = () => {\n message.error('Edit error - Something went wrong!');\n };\n\n const onValuesChange = (value) => {\n if (isFormChanged(form.getFieldsValue())) {\n setDisableSaveBtn(false);\n } else {\n setDisableSaveBtn(true);\n }\n };\n\n const isLoading = loadingDetail || startEdit === 'starting';\n\n return (\n
\n \n \n \n
\n );\n};\n\nFolderPanelEdit.propTypes = {\n folderInfo: PropTypes.object,\n onCloseEdit: PropTypes.func,\n ownerFolder: bool,\n folderOption: PropTypes.string,\n loadingDetail: PropTypes.bool,\n};\n\nexport default FolderPanelEdit;\n","import { getNodeTreeData } from 'common/components/folder/utils';\n\nexport const transformSelectedItemToNodeTree = (node) => {\n return getNodeTreeData({\n node,\n });\n};\n\nexport const getCurrentFolderId = ({ treeData, selectedItem }) => {\n if (!selectedItem) return null;\n\n const node = transformSelectedItemToNodeTree(selectedItem);\n const ancestorNodes = findParentFolderOfNode(treeData, node); // list of ancestorNodes\n\n return ancestorNodes?.data?.id;\n};\n\nexport const findParentFolderOfNode = (treeData, childNode) => {\n let parentNode;\n\n for (let i = 0; i < treeData?.length; i++) {\n const node = treeData[i];\n if (node?.children) {\n if (\n node?.children?.some((item) => item?.data?.id === childNode?.data?.id)\n ) {\n parentNode = node;\n } else if (findParentFolderOfNode(node.children, childNode)) {\n parentNode = findParentFolderOfNode(node.children, childNode);\n }\n }\n }\n return parentNode;\n};\n","import React, { useMemo, useState } from 'react';\n\nimport { Row, Col } from 'antd';\nimport { DoubleRightOutlined } from '@ant-design/icons';\n\nimport { FormButton } from 'common/components';\nimport MoveFolderModal from 'pages/home/ribbon/components/controls/folders/MoveFolderModal';\n\nimport { useGridView } from 'hooks/useGridView';\n\nimport { getCurrentFolderId } from './utils';\n\nconst FolderPanelActions = (props) => {\n const { treeData, shortDetail, selectedItem, handleBuildHierarchyTree } =\n props;\n\n const [moveFolderModalVisible, setMoveFolderModalVisible] = useState(false);\n\n const { reloadPage } = useGridView();\n\n const onClickMove = () => {\n setMoveFolderModalVisible(true);\n };\n\n const closeMoveModal = () => {\n setMoveFolderModalVisible(false);\n };\n\n const moveSubFolderSuccessCallback = ({ destinationFolder }) => {\n handleBuildHierarchyTree(`/${shortDetail?.id}`);\n\n reloadPage(); //* 4555: check reload page condition may cause bug;\n };\n\n const checkDisabledMoveBtn = () => {\n const isSharedFolder = !selectedFolder?.isOwned;\n const isEditableFolder = selectedFolder?.editable;\n const isSelfSelected = selectedItem?.id === shortDetail?.id;\n\n if (!shortDetail?.isOwned && !shortDetail?.editable) return true;\n\n if (!selectedItem?.id) return true;\n\n //* preventing self-moving as it may cause issues\n if (isSelfSelected) return true;\n\n if (isSharedFolder && !isEditableFolder) return true;\n\n return false;\n };\n\n const currentFolderId = useMemo(\n () =>\n getCurrentFolderId({\n treeData,\n selectedItem,\n }),\n [selectedItem, treeData]\n );\n\n const selectedFolder =\n selectedItem?.type?.toLowerCase() === 'folder' && selectedItem;\n\n const disabled = checkDisabledMoveBtn();\n\n return (\n \n \n \n }\n disabled={disabled}\n onClick={onClickMove}\n />\n \n \n \n );\n};\n\nexport default FolderPanelActions;\n","import React from 'react';\n\nimport { Tooltip, Typography } from 'antd';\nimport { PlayCircleOutlined } from '@ant-design/icons';\n\nimport FolderPanelActions from './FolderPanelActions';\nimport { IconFolderAsset, NodeTree } from 'common/components/folder/FolderTree';\nimport { FolderTree } from 'common/components/folder';\n\nimport {\n getNodeTreeData,\n handleOpenDetailItem,\n} from 'common/components/folder/utils';\n\nimport { useGetFolderTreeData } from 'common/components/folder/hooks';\nimport { useChangeSize } from 'hooks/useResize';\n\nimport emptyFolderIcon from 'assets/folder/empty-folder.png';\nimport folderIcon from 'assets/folder/folder.png';\nimport classnames from 'classnames';\n\nconst FolderPanelContent = (props) => {\n const { shortDetail } = props;\n\n const parentNodeFolder = getNodeTreeData({\n node: { ...shortDetail, type: 'folder' }, // shortDetail doesn't have type value !!!\n folderParam: defaultFolderParam,\n fileParam: defaultFileParam,\n });\n\n const {\n treeData,\n selectedItem,\n expandedKeys,\n handleUpdateExpandedKeys,\n handleLoadMoreFolder,\n handleUpdateSelectedItem,\n handleBuildHierarchyTree,\n } = useGetFolderTreeData({\n defaultTreeProp: [parentNodeFolder],\n defaultExpandedKeys: [parentNodeFolder?.key],\n pageSize: 9999,\n filterType: 'all',\n folderParam: defaultFolderParam,\n fileParam: defaultFileParam,\n });\n\n const [treeWrapperWidth, treeWrapperHeight] =\n useChangeSize('#folder-panel-tree');\n const [treeWidth, treeHeight] = useChangeSize(\n '#folder-panel-tree > .folder-tree'\n );\n\n return (\n \n
\n \n \n Contents\n \n
\n treeHeight,\n })}\n id='folder-panel-tree'\n >\n \n \n \n );\n};\n\nconst checkEmptyContents = (node) => {\n const {\n items = 0,\n contentsCount = 0,\n assetCount = 0,\n memberCount = 0,\n productCount = 0,\n queryCount = 0,\n subFolderCount = 0,\n reportingCount = 0,\n } = node;\n\n return (\n items +\n contentsCount +\n assetCount +\n memberCount +\n productCount +\n queryCount +\n subFolderCount +\n reportingCount ===\n 0\n );\n};\n\nconst defaultFolderParam = {\n renderFolder: (node) => {\n const isEmptyContents = checkEmptyContents(node);\n\n if (isEmptyContents) {\n return {\n title: (\n \n \n handleOpenDetailItem(node?.type, node?.id)}\n />\n \n \n ),\n icon: ,\n isLeaf: true,\n };\n }\n return {\n title: (\n \n \n handleOpenDetailItem(node?.type, node?.id)}\n />\n \n \n ),\n icon: ,\n };\n },\n};\n\nconst defaultFileParam = {\n renderFile: (node) => {\n return {\n title: (\n \n \n handleOpenDetailItem(node?.type, node?.id)}\n />\n \n \n ),\n };\n },\n};\n\nexport default FolderPanelContent;\n","import React, { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Row, Col, Image, Typography, Tooltip, Space } from 'antd';\nimport { get } from 'lodash';\n\nimport { InfoWithLabel, FavoriteStarIconRender } from 'common/components';\nimport EmptyFolderImg from 'assets/folder/empty-folder.png';\nimport FolderImg from 'assets/folder/folder.png';\nimport ShareFolderImg from 'assets/folder/shared-folder.png';\nimport DownloadIcon from 'assets/DownloadIcon.png';\nimport { injectIntl } from 'react-intl';\n\nimport { formatMDY } from 'utils/formatDate';\nconst { Title } = Typography;\n\nconst PanelHeader = (props) => {\n const { shortDetail, ownerFolder, openDownloadPanel, intl } = props;\n\n const [thumbnailImg, setThumbnailImg] = useState('');\n\n const onClickDownloadBtn = () => {\n openDownloadPanel && openDownloadPanel();\n };\n\n useEffect(() => {\n const thumbnailSrc = !ownerFolder\n ? ShareFolderImg\n : get(shortDetail, 'items') > 0\n ? FolderImg\n : EmptyFolderImg;\n setThumbnailImg(thumbnailSrc);\n // eslint-disable-next-line\n }, [ownerFolder]);\n\n const metaData = [\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.owner',\n }),\n info:\n get(shortDetail, 'ownerName', '') && get(shortDetail, 'ownerName', ''),\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.dateCreated',\n }),\n info:\n formatMDY(get(shortDetail, 'dateCreated', '')) !== 'Invalid Date'\n ? formatMDY(get(shortDetail, 'dateCreated', ''))\n : '',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.dateShared',\n }),\n info:\n formatMDY(get(shortDetail, 'dateShared', '')) !== 'Invalid Date'\n ? formatMDY(get(shortDetail, 'dateShared', ''))\n : '',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.editable',\n }),\n info: get(shortDetail, 'editable', '') ? 'Yes' : 'No',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.shareable',\n }),\n info: get(shortDetail, 'shareable', '') ? 'Yes' : 'No',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.specialPurpose',\n }),\n info: get(shortDetail, 'specialPurpose', '') ? 'Yes' : 'No',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.visibility',\n }),\n info: get(shortDetail, 'visibility', ''),\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.items',\n }),\n info: get(shortDetail, 'items', '') && get(shortDetail, 'items', ''),\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.expirationDate',\n }),\n info:\n formatMDY(get(shortDetail, 'expirationDate', '')) !== 'Invalid Date'\n ? formatMDY(get(shortDetail, 'expirationDate', ''))\n : '',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.lastUpdated',\n }),\n info: (\n <>\n
\n {formatMDY(get(shortDetail, 'lastUpdated', '')) !== 'Invalid Date'\n ? formatMDY(get(shortDetail, 'lastUpdated', ''))\n : ''}\n
\n
\n {get(shortDetail, 'lastUpdatedBy', '') &&\n get(shortDetail, 'lastUpdatedBy', '')}\n
\n \n ),\n },\n\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.lastDownload',\n }),\n info:\n formatMDY(get(shortDetail, 'lastDownload', '')) !== 'Invalid Date'\n ? formatMDY(get(shortDetail, 'lastDownload', ''))\n : '',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.lastSchedule',\n }),\n info:\n formatMDY(get(shortDetail, 'lastSchedule', '')) !== 'Invalid Date'\n ? formatMDY(get(shortDetail, 'lastSchedule', ''))\n : '',\n },\n ];\n\n const infoColProps = {\n infoColProps: {\n flex: 'auto',\n },\n labelColProps: {\n flex: '130px',\n },\n boldInfo: true,\n labelAlign: 'right',\n };\n\n const dataLeft = metaData\n ? metaData.slice(0, Math.ceil(metaData.length / 2 + 1))\n : [];\n const dataRight = metaData\n ? metaData.slice(Math.ceil(metaData.length / 2 + 1))\n : [];\n\n const folderName = get(shortDetail, 'folderName', '');\n\n return (\n
\n \n \n \n \n \n \n \n {folderName}\n \n \n \n
\n \n \n {dataLeft &&\n dataLeft.length > 0 &&\n dataLeft.map((item, index) => {\n return (\n \n );\n })}\n \n \n {dataRight &&\n dataRight.length > 0 &&\n dataRight.map((item, index) => {\n return (\n \n );\n })}\n \n \n
\n
\n
\n );\n};\n\nPanelHeader.propTypes = {\n onTrigger: PropTypes.func,\n shortDetail: PropTypes.object,\n ownerFolder: PropTypes.bool,\n onEditClick: PropTypes.func,\n};\n\nexport default injectIntl(PanelHeader);\n","import React, { useState, useEffect } from 'react';\nimport PropTypes, { oneOfType } from 'prop-types';\nimport { Row, Col, Typography, Skeleton } from 'antd';\nimport { LabelValueWrapper } from 'common/components';\nimport { formatMDY } from 'utils/formatDate';\nimport { formatSizeUnits } from 'utils/formatSizeUnits';\nimport EmptyFolderImg from 'assets/folder/empty-folder.png';\nimport FolderImg from 'assets/folder/folder.png';\nimport ShareFolderImg from 'assets/folder/shared-folder.png';\nimport { get } from 'lodash';\nimport './DownloadInformation.less';\n\nconst { Text } = Typography;\n\nconst DownloadInformation = (props) => {\n const { downloadSetting, ownerFolder } = props;\n\n const [leftCol, setLeftCol] = useState([]);\n const [rightCol, setRightCol] = useState([]);\n const thumbnailImg = !ownerFolder\n ? ShareFolderImg\n : get(downloadSetting, 'items') > 0\n ? FolderImg\n : EmptyFolderImg;\n\n // Modify Data\n const modifyData = (key, value) => {\n if (typeof value === 'boolean') {\n switch (value) {\n case true:\n return 'Yes';\n case false:\n return 'No';\n default:\n return value;\n }\n } else {\n switch (key) {\n case 'dateCreated':\n case 'dateShared':\n case 'lastUpdated':\n case 'lastDownload':\n case 'lastSchedule':\n return formatMDY(value);\n case 'estSize':\n return formatSizeUnits(value);\n default:\n return value;\n }\n }\n };\n\n // Filter Object By Key\n const filterObjectByKey = (obj, filter) => {\n return Object.entries(obj).reduce((newObj, [key, value]) => {\n if (filter.includes(key)) {\n newObj[key] = modifyData(key, value);\n }\n return newObj;\n }, {});\n };\n\n useEffect(() => {\n if (downloadSetting) {\n setLeftCol(\n filterObjectByKey(downloadSetting, [\n 'ownerName',\n 'dateCreated',\n 'dateShared',\n 'editable',\n 'shareable',\n 'specialPurpose',\n ])\n );\n setRightCol(\n filterObjectByKey(downloadSetting, [\n 'items',\n 'estSize',\n 'lastUpdated',\n 'lastUpdatedBy',\n 'lastDownload',\n 'lastSchedule',\n ])\n );\n }\n }, [downloadSetting]);\n\n return (\n \n
\n \n \n \n \n \n \n {downloadSetting?.folderName}\n \n \n \n \n \n {leftCol && (\n \n )}\n \n \n {rightCol && (\n \n )}\n \n \n
\n
\n );\n};\n\nDownloadInformation.propTypes = {\n downloadSetting: oneOfType([PropTypes.array, PropTypes.object]),\n ownerFolder: PropTypes.bool,\n};\n\nexport default DownloadInformation;\n","import { useEffect } from 'react';\n\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { notification } from 'antd';\n\nimport * as folderActions from '../../controllers/actions';\nimport * as folderSelectors from '../../controllers/selectors';\nimport { getSubMappingSubscription } from 'services/mapping';\n\nimport { PRODUCT_CONFIG as productConfigs } from 'static/Constants';\n\nconst useSetIndeterminateCheckbox = (downloadSetting, setIndeterminate) => {\n useEffect(() => {\n if (downloadSetting) {\n const { hasTrueValue, name } = checkDefaultSetting(\n productConfigs,\n downloadSetting\n );\n if (hasTrueValue) {\n setIndeterminate({ [name]: true });\n }\n }\n }, [downloadSetting, setIndeterminate]);\n};\n\nconst useCheckSelectMapping = () => {\n const downloadSetting = useSelector(folderSelectors.selectDownloadSetting());\n const selectedMapping = useSelector(folderSelectors.selectSelectedMapping());\n const statusDownloadFolder = useSelector(\n folderSelectors.selectStatusDownloadFolder()\n );\n\n const dispatch = useDispatch();\n\n useEffect(() => {\n if (!downloadSetting?.productCount) return;\n\n if (selectedMapping === null && statusDownloadFolder === 'loading') {\n notification.error({\n message: 'Please select a mapping',\n });\n\n dispatch(folderActions.saveStatusDownloadFolder('idle'));\n }\n }, [\n dispatch,\n downloadSetting?.productCount,\n selectedMapping,\n statusDownloadFolder,\n ]);\n};\n\nconst checkContainsSomeTrueValue = (names, form) => {\n const mergedChildValues = getMergedChildValues(names, form);\n return mergedChildValues?.some((value) => value === true);\n};\n\nconst checkContainsAllTrueValue = (names, form) => {\n const mergedChildValues = getMergedChildValues(names, form);\n return mergedChildValues?.every((value) => value === true);\n};\n\nconst getMergedChildValues = (names, form) => {\n const mergedChildValues = names?.reduce((accumulator, currentValue) => {\n if (form.getFieldValue(`${currentValue}`)) {\n return accumulator.concat(\n Object.values(form.getFieldValue(`${currentValue}`))\n );\n }\n return [];\n }, []);\n\n return mergedChildValues;\n};\n\nconst checkAllTrue = (list) => list.every((value) => value === true);\n\nconst checkIfOneTrue = (list) => list.some((value) => value === true);\n\nconst checkOneOfThemHasTrueValue = (namesChild, form) => {\n for (const name of namesChild) {\n const valueChild = Object.values(form.getFieldValue()[`${name}`]);\n if (checkIfOneTrue(valueChild)) return true;\n }\n\n return false;\n};\n\nconst checkDefaultSetting = (productConfigs, folderDownload) => {\n if (folderDownload == null || !folderDownload) return {};\n\n for (const config of productConfigs) {\n const { name: nameParent, option: optionParent } = config;\n\n for (const childOption of optionParent) {\n const { name: nameChild, option: valueChild } = childOption;\n if (folderDownload[`${nameChild}`]?.length === valueChild.length) {\n return {\n hasTrueValue: true,\n name: nameParent,\n };\n }\n }\n }\n return {\n hasTrueValue: false,\n name: '',\n };\n};\n\nconst findMappingSubscription = async (mappingId) => {\n const params = {\n pageIndex: 1,\n pageSize: 9999,\n filters: [\n {\n fieldName: 'id',\n filterType: 'Equal',\n value: mappingId,\n },\n ],\n enableRivirDownload: true,\n };\n try {\n const response = await getSubMappingSubscription(params);\n if (response?.isSuccess) {\n return new Promise((resolve) => resolve(response.data?.gridData?.[0]));\n } else {\n return new Promise((resolve) => resolve(null));\n }\n } catch (error) {\n return new Promise((resolve) => resolve(null));\n }\n};\n\nexport {\n useSetIndeterminateCheckbox,\n useCheckSelectMapping,\n checkContainsSomeTrueValue,\n checkContainsAllTrueValue,\n checkOneOfThemHasTrueValue,\n checkAllTrue,\n checkDefaultSetting,\n findMappingSubscription,\n // dropdownConfigs,\n};\n\nexport const initProductConfigValue = (\n downloadSetting,\n form,\n onChangeBotCb\n) => {\n productConfigs.forEach((productItem) => {\n for (const [key, parent] of productItem.option?.entries()) {\n for (const [key, grandChild] of parent.option?.entries()) {\n form.setFieldsValue({\n [parent.name]: {\n [grandChild]: downloadSetting?.[parent.name]?.includes(grandChild),\n },\n });\n }\n }\n\n for (const [key, parent] of productItem.option?.entries()) {\n for (const [key, grandChild] of parent.option?.entries()) {\n onChangeBotCb(grandChild, parent, productItem);\n }\n }\n });\n};\n","import React, { useState, useRef, useEffect } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { Row, Col, Input, Form, Select, Checkbox } from 'antd';\n\nimport {\n StyledModal,\n AgGrid,\n FormAddButton,\n FormDeleteButton,\n dialogFunction,\n WrapperSelect,\n} from 'common/components';\nimport {\n InformationLabel,\n InformationData,\n Loading,\n} from 'pages/branded-products/components/content-pane/SharedComponents';\n\nimport * as folderActions from '../../controllers/actions';\n\nimport { findMappingSubscription } from './utils';\nimport { mappingColumns } from 'common/components/product-subscription/utils';\n\nimport * as endpoints from 'services/mapping/endpoints';\nimport { PRODUCTS_DATA_FORMAT } from 'static/Constants';\n\nimport { useIntl } from 'react-intl';\nimport messagesMapping from 'i18n/messages/mapping';\n\nconst formProductLayout = {\n labelCol: { span: 24 },\n wrapperCol: { span: 24 },\n};\n\nconst ConfigProductDownload = ({\n mappingId,\n selectedMapping,\n dropdownConfigs,\n formName = 'folder',\n}) => {\n const dispatch = useDispatch();\n\n const [visibleModal, setVisibleModal] = useState(false);\n const intl = useIntl();\n\n useEffect(() => {\n if (!mappingId) return;\n findMappingSubscription(mappingId)\n .then((data) => {\n dispatch(folderActions.saveSelectedMapping(data));\n })\n .catch((error) => {\n console.log(error);\n });\n }, [dispatch, mappingId]);\n\n const handleDeleteMapping = () => {\n dialogFunction({\n type: 'warn',\n content: 'Are you sure to delete the selected mapping?',\n okText: 'Delete',\n okButtonProps: {\n type: 'danger',\n },\n onOk: () => {\n dispatch(folderActions.saveSelectedMapping(null));\n },\n });\n };\n\n const dataFormat = selectedMapping?.formatTypes\n ? selectedMapping?.formatTypes?.slice().sort()\n : PRODUCTS_DATA_FORMAT.map((formatType) => formatType.toUpperCase());\n const renderProductCropSize = (options) => {\n return (\n <>\n {options?.map((option) => (\n \n {option === null ? 'No Crop' : `${option} Pixels`}\n \n ))}\n \n );\n };\n\n const renderProductImageFormat = (options) => {\n return (\n <>\n {options?.map((option) => (\n \n {option?.toUpperCase()}\n \n ))}\n \n );\n };\n\n const renderDefaultDropDownConfigs = (options) => {\n return (\n <>\n {options?.map((option) => (\n \n {option}\n \n ))}\n \n );\n };\n\n const renderResolution = (options) => {\n return (\n <>\n {options?.map((option) => (\n \n {option === null ? 'Original' : option}\n \n ))}\n \n );\n };\n\n const renderDropdownConfigs = (options, name) => {\n if (name === 'productCropSize') {\n return renderProductCropSize(options);\n }\n if (name === 'productImageFormat') {\n return renderProductImageFormat(options);\n }\n if (name === 'productResolution') {\n return renderResolution(options);\n }\n\n return renderDefaultDropDownConfigs(options);\n };\n\n return (\n <>\n \n \n \n {selectedMapping ? (\n <>\n \n \n \n \n \n ) : (\n \n setVisibleModal(true)}\n style={{ borderRadius: 0 }}\n />\n \n )}\n \n \n\n \n \n \n \n document.getElementById(formName)}\n allowClear={false}\n >\n {dataFormat.map((type) => (\n \n {type}\n \n ))}\n \n \n \n\n {dropdownConfigs.map(({ name, options, layout }) => (\n \n \n document.getElementById(formName)}\n >\n {renderDropdownConfigs(options, name)}\n \n \n \n ))}\n\n \n \n \n \n \n \n \n \n\n {visibleModal && (\n setVisibleModal(false)}\n />\n )}\n \n );\n};\n\nconst MappingSubscriptionGrid = (props) => {\n const gridApi = useRef(null);\n const dispatch = useDispatch();\n\n const { visibleModal, handleCancelModal } = props;\n\n const [searchText, setSearchText] = useState('');\n\n const handleAddMapping = () => {\n if (gridApi?.current?.getSelectedRows().length > 0) {\n const selectedRow = gridApi.current.getSelectedRows()[0];\n dispatch(folderActions.saveSelectedMapping(selectedRow));\n handleCancelModal();\n }\n };\n\n const modalProps = {\n visible: visibleModal,\n title: 'Select Mapping',\n onCancel: handleCancelModal,\n onOk: handleAddMapping,\n okText: 'Add',\n maskClosable: false,\n width: '600px',\n destroyOnClose: true,\n bodyStyle: { minHeight: '70vh' },\n };\n\n return (\n \n
\n {mappingColumns?.length === 0 ? (\n \n ) : (\n <>\n
\n setSearchText(value)}\n />\n
\n {\n gridApi.current = api;\n }}\n paramsGrid={{\n search: {\n searchText,\n },\n enableRivirDownload: true,\n }}\n />\n \n )}\n
\n
\n );\n};\n\nconst DisplayMapping = ({ selectedMapping }) => {\n const intl = useIntl();\n\n const { mappingName, mappingDescription, deliveryMethods, formatTypes } =\n selectedMapping;\n\n return (\n \n \n {intl.formatMessage(messagesMapping.mappingName)}\n \n \n\n \n {intl.formatMessage(messagesMapping.mappingDescription)}\n \n \n\n \n {intl.formatMessage(messagesMapping.deliveryMethods)}\n \n \n\n \n {intl.formatMessage(messagesMapping.formatTypes)}\n \n \n \n );\n};\n\nexport { ConfigProductDownload };\n","import React, { useEffect, useState, useReducer } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport PropTypes, { oneOfType } from 'prop-types';\nimport {\n Row,\n Col,\n Radio,\n Select,\n Typography,\n Divider,\n Collapse,\n Checkbox,\n Button,\n notification,\n Tooltip,\n InputNumber,\n} from 'antd';\n// import digitalAssetIcon from 'assets/asset-icons/DigitalAssets.png';\n// import memberIcon from 'assets/asset-icons/Member.png';\n// import productIcon from 'assets/asset-icons/Product.png';\n// import queryIcon from 'assets/asset-icons/Queries.png';\n// import reportIcon from 'assets/asset-icons/Queries.png';\nimport {\n // DashboardOutlined,\n ClearOutlined,\n PlusOutlined,\n} from '@ant-design/icons';\nimport { Form, TypePicker, EmailSelection } from 'common/components';\nimport {\n FOLDER_DOWNLOAD_TYPE,\n FOLDER_DELIVERY_METHOD,\n IMAGE_FORMAT_OPTIONS,\n IMAGE_SIZE_OPTIONS,\n IMAGE_SIZE_OPTIONS_SINGLE_DIGIT,\n CROP_SIZE_OPTIONS,\n RESOLUTION_OPTIONS,\n BACKGROUND_OPTIONS,\n QUERIES_DATA_FORMAT,\n REPORTS_DATA_FORMAT,\n PLANOGRAM_TYPE,\n PRODUCT_CONFIG,\n INFORMATION_SHEET_OPTIONS,\n} from 'static/Constants';\nimport { folderDownload } from 'services/folder';\nimport { FOLDER_DOWNLOAD } from 'services/folder/endpoints';\nimport userSelectors from '@redux/user/selectors';\nimport * as api from 'config/axios';\nimport { injectIntl } from 'react-intl';\nimport * as actionsMember from 'pages/branded-members/controllers/actions';\nimport * as memberSelectors from 'pages/branded-members/controllers/selectors';\nimport * as companySelectors from 'pages/company-profile/controllers/selectors';\nimport * as memberActions from 'pages/company-profile/controllers/actions';\n\nimport { WrapperSelect } from 'common/components';\n\nimport * as folderSelectors from '../../controllers/selectors';\nimport * as folderActions from '../../controllers/actions';\n\nimport { ConfigProductDownload } from './ConfigDownload';\n\nimport Messages from 'i18n/messages/folder';\n\nimport {\n useSetIndeterminateCheckbox,\n checkContainsSomeTrueValue,\n checkContainsAllTrueValue,\n checkOneOfThemHasTrueValue,\n initProductConfigValue,\n} from './utils';\n\nimport { deleteObjectField } from 'utils';\n\nimport * as _ from 'lodash';\n\nimport './DownloadConfiguration.less';\n\nconst { Option } = Select;\nconst { Panel } = Collapse;\nconst { Text } = Typography;\n\n// Form Layouts\nconst formFormatLayout = { labelCol: { span: 12 } };\nconst formLayout = { labelCol: { span: 5 }, wrapperCol: { span: 10 } };\nconst formCheckboxLayout = { labelCol: { span: 16 }, wrapperCol: { span: 8 } };\n\nconst addButtonStyle = {\n flex: 'none',\n padding: '8px',\n display: 'block',\n cursor: 'pointer',\n};\n\nconst customSetupStyle = {\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'nowrap',\n padding: 8,\n};\n\nconst defaultConfig = {\n productUnit: false,\n productUnitPlanogram: false,\n productUnitMarketing: false,\n productUnitAdditionInformation: false,\n productDisplayShipper: false,\n productDisplayShipperPlanogram: false,\n productDisplayShipperMarketing: false,\n productDisplayShipperAdditionInformation: false,\n productInnerPack: false,\n productInnerPackPlanogram: false,\n productInnerPackMarketing: false,\n productInnerPackAdditionInformation: false,\n productCase: false,\n productCasePlanogram: false,\n productCaseMarketing: false,\n productCaseAdditionInformation: false,\n productMasterCase: false,\n productMasterCasePlanogram: false,\n productMasterCaseMarketing: false,\n productMasterCaseAdditionInformation: false,\n productPallet: false,\n productPalletCasePlanogram: false,\n productPalletCaseMarketing: false,\n productPalletCaseAdditionInformation: false,\n};\n\nconst DownloadConfiguration = (props) => {\n const {\n downloadSetting,\n id,\n setLoading,\n onSetType,\n onSetMethod,\n intl,\n continueSchedule,\n downloadEntityAmount,\n memberOwnerId,\n formId,\n } = props;\n\n const formName = formId || 'folder';\n\n const [form] = Form.useForm();\n const [visibleEmailSelection, setVisibleEmailSelection] = useState(false);\n const [formFieldsValue, setFormFieldsValue] = useState({});\n const [resolutionOptions, setResolution] = useState(RESOLUTION_OPTIONS);\n const [imageSizeOptions, setImageSize] = useState(IMAGE_SIZE_OPTIONS);\n const [customResolution, setCustomResolution] = useState('');\n const [customImageSize, setCustomImageSize] = useState('');\n\n const [indeterminate, setIndeterminate] = useReducer(\n (state, action) => ({ ...state, ...action }),\n {}\n );\n\n const [assetResolutionOptions, setAssetResolution] =\n useState(RESOLUTION_OPTIONS);\n const [assetImageSizeOptions, setAssetImageSize] =\n useState(IMAGE_SIZE_OPTIONS);\n const [customAssetResolution, setCustomAssetResolution] = useState('');\n const [customAssetImageSize, setCustomAssetImageSize] = useState('');\n\n const dispatch = useDispatch();\n\n const alternativeEmail = useSelector(\n userSelectors.makeSelectUserAlternativeEmail()\n );\n const selectedMapping = useSelector(folderSelectors.selectSelectedMapping());\n\n const primaryEmail = useSelector(userSelectors.makeSelectUserEmail());\n const memberData = useSelector(memberSelectors.makeSelectMemberData());\n const memberInfo = useSelector(companySelectors.selectMemberProfile());\n const userInfo = useSelector(userSelectors.makeSelectUserInfo());\n\n useEffect(() => {\n if (_.isEmpty(memberInfo)) {\n dispatch(memberActions.getMemberProfileHeader(userInfo?.member?.id));\n }\n }, [dispatch, userInfo?.member?.id]);\n\n useSetIndeterminateCheckbox(downloadSetting, setIndeterminate);\n // useCheckSelectMapping();\n\n const dropdownConfigs = [\n {\n name: 'productImageNamingFormat',\n options: PLANOGRAM_TYPE,\n },\n {\n name: 'productImageFormat',\n options: IMAGE_FORMAT_OPTIONS,\n },\n {\n name: 'productImageSize',\n options: IMAGE_SIZE_OPTIONS,\n },\n {\n name: 'productCropSize',\n options: CROP_SIZE_OPTIONS,\n },\n {\n name: 'productResolution',\n options: RESOLUTION_OPTIONS,\n },\n {\n name: 'productBackground',\n options: BACKGROUND_OPTIONS,\n },\n ];\n\n // Configuration Data\n // const productData = [\n // {\n // name: 'productDataFormat',\n // option:\n // memberData?.gln?.toLowerCase() === 'gln'\n // ? PRODUCTS_DATA_FORMAT_WITH_GDSN\n // : PRODUCTS_DATA_FORMAT,\n // },\n // { name: '', option: [] },\n // { name: 'productPlanogramType', option: PLANOGRAM_TYPE },\n // { name: 'productImageFormat', option: IMAGE_FORMAT_OPTIONS },\n // { name: 'productImageSize', option: IMAGE_SIZE_OPTIONS },\n // { name: 'productCropSize', option: CROP_SIZE_OPTIONS },\n // { name: 'productResolution', option: RESOLUTION_OPTIONS },\n // { name: 'productBackground', option: BACKGROUND_OPTIONS },\n // ];\n const digitalAssetData = [\n {\n name: 'digitalAssetImageFormat',\n option: IMAGE_FORMAT_OPTIONS.map((item) => item?.toUpperCase()),\n },\n { name: 'digitalAssetImageSize', option: IMAGE_SIZE_OPTIONS },\n { name: 'digitalAssetResolution', option: RESOLUTION_OPTIONS },\n ];\n const resetData = () => {\n form.setFieldsValue({\n downloadType: downloadSetting?.downloadType,\n deliveryMethod: downloadSetting?.deliveryMethod,\n productDataFormat: downloadSetting?.productDataFormat,\n productImageNamingFormat: downloadSetting?.productImageNamingFormat,\n productImageFormat: downloadSetting?.productImageFormat?.toUpperCase(),\n productImageSize: downloadSetting?.productImageSize,\n productCropSize: downloadSetting?.productCropSize ?? null,\n productResolution: downloadSetting?.productResolution ?? null,\n productBackground: downloadSetting?.productBackground ?? 'Original',\n digitalAssetImageFormat:\n downloadSetting?.digitalAssetImageFormat === null\n ? 'ORIGINAL'\n : downloadSetting?.digitalAssetImageFormat?.toUpperCase(),\n digitalAssetImageSize: downloadSetting?.digitalAssetImageSize,\n digitalAssetResolution: downloadSetting?.digitalAssetResolution ?? null,\n queryDataFormat: downloadSetting?.queryDataFormat?.toUpperCase(),\n memberDefinedSheets:\n downloadSetting?.memberDefinedSheets || 'RIVIR Default',\n keepFolderStructure: true,\n includeSubfolders: true,\n });\n\n if (!downloadSetting) return;\n\n initProductConfigValue(downloadSetting, form, onChangeBotCb);\n\n onSetType && onSetType(form.getFieldValue('downloadType'));\n onSetMethod && onSetMethod(form.getFieldValue('deliveryMethod'));\n };\n\n const onOptionChange = (type, value) => {\n // eslint-disable-next-line default-case\n switch (type) {\n case 'resolution':\n setCustomResolution(value);\n break;\n case 'imageSize':\n setCustomImageSize(value);\n break;\n case 'assetResolution':\n setCustomAssetResolution(value);\n break;\n case 'assetImageSize':\n setCustomAssetImageSize(value);\n break;\n }\n };\n\n // Product Resolution\n const addResolutionItem = () => {\n if (!customResolution)\n openNotification(\n 'error',\n intl.formatMessage(Messages.resolutionCustomize),\n intl.formatMessage(Messages.resolutionMissing)\n );\n else if (resolutionOptions.includes(customResolution))\n openNotification(\n 'error',\n intl.formatMessage(Messages.resolutionCustomize),\n intl.formatMessage(Messages.resolutionDuplicated)\n );\n else setResolution([...resolutionOptions, customResolution]);\n };\n\n // Asset Resolution\n const addAssetResolutionItem = () => {\n if (!customAssetResolution)\n openNotification(\n 'error',\n intl.formatMessage(Messages.resolutionCustomize),\n intl.formatMessage(Messages.resolutionMissing)\n );\n else if (assetResolutionOptions.includes(customAssetResolution))\n openNotification(\n 'error',\n intl.formatMessage(Messages.resolutionCustomize),\n intl.formatMessage(Messages.resolutionDuplicated)\n );\n else setAssetResolution([...assetResolutionOptions, customAssetResolution]);\n };\n\n const imageSizeCustomRender = (value) => {\n if (IMAGE_SIZE_OPTIONS.includes(value)) return value;\n else return `${value}x${value}`;\n };\n\n // Product Image Size\n const addImageSizeItem = () => {\n if (!customImageSize)\n openNotification(\n 'error',\n intl.formatMessage(Messages.imageSizeCustomize),\n intl.formatMessage(Messages.imageSizeMissing)\n );\n else if (\n imageSizeOptions.includes(customImageSize) ||\n IMAGE_SIZE_OPTIONS_SINGLE_DIGIT.includes(customImageSize)\n )\n openNotification(\n 'error',\n intl.formatMessage(Messages.imageSizeCustomize),\n intl.formatMessage(Messages.imageSizeDuplicated)\n );\n else setImageSize([...imageSizeOptions, customImageSize]);\n };\n\n // Asset Image Size\n const addAssetImageSizeItem = () => {\n if (!customAssetImageSize)\n openNotification(\n 'error',\n intl.formatMessage(Messages.imageSizeCustomize),\n intl.formatMessage(Messages.imageSizeMissing)\n );\n else if (\n assetImageSizeOptions.includes(customAssetImageSize) ||\n IMAGE_SIZE_OPTIONS_SINGLE_DIGIT.includes(customAssetImageSize)\n )\n openNotification(\n 'error',\n intl.formatMessage(Messages.imageSizeCustomize),\n intl.formatMessage(Messages.imageSizeDuplicated)\n );\n else setAssetImageSize([...assetImageSizeOptions, customAssetImageSize]);\n };\n\n const openNotification = (result, message, description, key, close) => {\n let type;\n switch (result) {\n case true:\n type = 'success';\n break;\n case false:\n type = 'error';\n break;\n default:\n type = result;\n break;\n }\n notification[type]({\n message: message,\n description: description,\n duration: type === 'warning' ? 0 : 4.5,\n key: key,\n onClose: close,\n });\n };\n\n useEffect(() => {\n resetData();\n }, [downloadSetting]);\n\n useEffect(() => {\n memberOwnerId &&\n dispatch(actionsMember.getMemberShortDetail(memberOwnerId));\n }, [dispatch, memberOwnerId]);\n\n const openNotify = (result, description) => {\n notification[result ? 'success' : 'error']({\n message: 'Folder Download',\n description: description,\n });\n };\n\n async function onFolderDownload(values) {\n dispatch(folderActions.saveStatusDownloadFolder('loading'));\n\n const mappingId = selectedMapping?.id ? selectedMapping?.id : 0;\n const newFormValues = {\n ...values,\n };\n\n // if (downloadEntityAmount?.product && mappingId === null) return;\n\n if (downloadEntityAmount?.member && values.memberDefinedSheets === null) {\n values = { ...values, memberDefinedSheets: 'RIVIR Default' };\n }\n\n setLoading(true);\n if (values.deliveryMethod === 'direct') {\n await api\n .requestToDownload({\n method: 'POST',\n apiEndpoint: FOLDER_DOWNLOAD,\n payload: {\n folderId: id,\n mappingId,\n ...newFormValues,\n },\n options: { timeout: 1800000 },\n })\n .then((response) => {\n openNotify(response?.isSuccess, response?.message);\n })\n .finally(() => {\n setLoading(false);\n })\n .catch((e) => {\n console.log('e', e);\n });\n } else if (values.deliveryMethod === 'email') {\n setFormFieldsValue(newFormValues);\n openEmailSelection();\n } else {\n await folderDownload({\n folderId: id,\n ...newFormValues,\n }).then((response) => {\n openNotify(response.isSuccess, response.message);\n });\n }\n setLoading(false);\n dispatch(folderActions.saveStatusDownloadFolder('idle'));\n }\n\n const openEmailSelection = () => {\n setVisibleEmailSelection(true);\n };\n\n const onFolderDownloadByEmail = async (emails) => {\n // todo\n const mappingId = selectedMapping?.id ? selectedMapping?.id : null;\n\n const newFormValues = {\n ...formFieldsValue,\n };\n\n await folderDownload({\n folderId: id,\n mappingId,\n ...newFormValues,\n emails: emails,\n }).then((response) => {\n openNotify(response.isSuccess, response.message);\n });\n };\n\n const onSendMultiEmail = async (emails) => {\n setLoading(true);\n setVisibleEmailSelection(false);\n await onFolderDownloadByEmail(emails);\n setFormFieldsValue({});\n setLoading(false);\n };\n\n const onFinish = (values) => {\n PRODUCT_CONFIG.forEach((item) => {\n delete values[item.name];\n for (const [key, child] of item.option?.entries()) {\n if (!values[child.name]) {\n return;\n }\n delete values[child.name]['value'];\n values[child.name] = Object.keys(values[child.name]).filter((key) => {\n return values[child.name][key];\n });\n }\n });\n\n if (!values.downloadType && !values.deliveryMethod)\n openNotify(\n false,\n intl.formatMessage({\n id: 'Taco.folder.component.download.missing',\n })\n );\n else if (!values.downloadType)\n openNotify(\n false,\n intl.formatMessage({\n id: 'Taco.folder.component.download.downloadType.missing',\n })\n );\n else if (!values.deliveryMethod)\n openNotify(\n false,\n intl.formatMessage({\n id: 'Taco.folder.component.download.deliveryMethod.missing',\n })\n );\n else onFolderDownload(values);\n };\n\n const onChangeTopCb = (item) => {\n const data = form.getFieldValue(item.name);\n for (const [key, child] of item.option?.entries()) {\n form.setFieldsValue({ [child.name]: { value: data } });\n for (const [key, grandChild] of child.option?.entries()) {\n form.setFieldsValue({ [child.name]: { [grandChild]: data } });\n }\n }\n\n handleIndeterminationTopValue(item, data);\n };\n\n const onChangeMidCb = (item, parent) => {\n const data = form.getFieldValue([item.name, 'value']);\n let signal = data;\n for (const [key, child] of parent.option?.entries()) {\n signal = signal && form.getFieldValue([child.name, 'value']);\n form.setFieldsValue({ [parent.name]: signal });\n for (const [key, child] of item.option?.entries()) {\n form.setFieldsValue({ [item.name]: { [child]: data ? true : false } });\n }\n }\n\n handleIndeterminationMidValue(parent, form, item);\n };\n\n const onChangeBotCb = (item, parent, grandParent) => {\n handleIndeterminationBotValue(parent, form, grandParent);\n const data = form.getFieldValue([parent.name, item]);\n let signal = data;\n for (const [key, child] of parent.option?.entries()) {\n signal = signal && form.getFieldValue([parent.name, child]);\n form.setFieldsValue({ [parent.name]: { value: signal } });\n }\n for (const [key, child] of grandParent.option?.entries()) {\n signal = signal && form.getFieldValue([child.name, 'value']);\n form.setFieldsValue({ [grandParent.name]: signal });\n }\n };\n\n const handleIndeterminationTopValue = (item, data, form) => {\n const nameItem = item.name;\n const parentIndeterminateConfig = item?.option.reduce(\n (nextParentIndeterminateConfig, parent) => {\n nextParentIndeterminateConfig[parent?.name] = false;\n return nextParentIndeterminateConfig;\n },\n {}\n );\n\n setIndeterminate({ [nameItem]: false, ...parentIndeterminateConfig });\n };\n\n const handleIndeterminationMidValue = (parent, form, item) => {\n const parentName = parent.name;\n const itemName = item.name;\n const childNames = parent.option.map((option) => option.name);\n const haveCheckAllTrueValues = checkContainsAllTrueValue(childNames, form);\n const haveSomeTrueValues = checkContainsSomeTrueValue(childNames, form);\n\n if (haveCheckAllTrueValues) {\n setIndeterminate({ [parentName]: false, [itemName]: false });\n return;\n }\n\n if (haveSomeTrueValues) {\n setIndeterminate({ [parentName]: true, [itemName]: false });\n return;\n }\n\n setIndeterminate({ [parentName]: false });\n };\n\n const handleIndeterminationBotValue = (parent, form, grandParent) => {\n const nameParent = parent.name;\n const nameGrandParent = grandParent.name;\n let grandParentAllValues = grandParent.option.map(\n (grandParentOptionItem) => {\n let parentValues = form.getFieldValue(grandParentOptionItem?.name);\n return deleteObjectField(parentValues, ['value'], true);\n }\n );\n\n const isAllChildInGrandParentTrue = grandParentAllValues.reduce(\n (isAllChildTrue, parentValues) => {\n return (\n isAllChildTrue *\n Object.values(parentValues).every((value) => value === true)\n );\n },\n true\n );\n\n const isAllChildInGrandParentFalse = grandParentAllValues.reduce(\n (isAllChildFalse, parentValues) => {\n return (\n isAllChildFalse *\n Object.values(parentValues).every((value) => value === false)\n );\n },\n true\n );\n\n let valueParent = form.getFieldValue()[`${nameParent}`];\n const valueChild = Object.values(\n deleteObjectField(valueParent, ['value'], true)\n );\n const hasTrueValue = valueChild.includes(true);\n const haveAllTrueValue = valueChild.every((value) => value === true);\n\n if (haveAllTrueValue) {\n setIndeterminate({ [nameParent]: false, [nameGrandParent]: true });\n }\n\n if (isAllChildInGrandParentTrue) {\n setIndeterminate({ [nameGrandParent]: false });\n return;\n }\n\n if (isAllChildInGrandParentFalse) {\n setIndeterminate({ [nameGrandParent]: false });\n }\n\n if (hasTrueValue && !haveAllTrueValue) {\n const childNames = grandParent.option.map((child) => child.name);\n\n const isOneChildHaveTrueValue = checkOneOfThemHasTrueValue(\n childNames,\n form\n );\n\n if (isOneChildHaveTrueValue) {\n setIndeterminate({ [nameParent]: true, [nameGrandParent]: true });\n } else {\n setIndeterminate({ [nameParent]: true, [nameGrandParent]: false });\n }\n return;\n }\n\n setIndeterminate({ [nameParent]: false });\n };\n\n // Header Render\n const headerRender = (title) => {\n return (\n <>\n {title}\n \n );\n };\n\n // Checkbox Header Render\n const cbHeaderRender = (item, child, grandChild) => {\n if (grandChild) {\n return (\n \n onChangeBotCb(grandChild, child, item)}>\n {grandChild}\n \n \n );\n } else if (child) {\n return (\n event.stopPropagation()}\n >\n onChangeMidCb(child, item)}\n indeterminate={indeterminate[`${child.name}`]}\n >\n {intl.formatMessage({\n id: `Taco.folder.download.configuration.${child.name}`,\n })}\n
\n \n );\n } else {\n return (\n event.stopPropagation()}\n >\n onChangeTopCb(item)}\n indeterminate={indeterminate[`${item.name}`]}\n >\n {intl.formatMessage({\n id: `Taco.folder.download.configuration.${item.name}`,\n })}\n
\n \n );\n }\n };\n\n const selectOptionRender = (type, data) => {\n switch (type) {\n case 'productImageSize':\n return imageSizeOptions;\n case 'productResolution':\n return resolutionOptions;\n case 'digitalAssetImageSize':\n return assetImageSizeOptions;\n case 'digitalAssetResolution':\n return assetResolutionOptions;\n default:\n return data;\n }\n };\n\n const selectConfigRender = (item, data) => {\n switch (item) {\n case 'productImageSize':\n return (\n
\n {data}\n \n
\n
\n onOptionChange('imageSize', e)}\n />\n
\n \n \n \n
\n
\n );\n\n case 'productResolution':\n return (\n
\n {data}\n \n
\n onOptionChange('resolution', e, '')}\n />\n \n \n \n
\n
\n );\n\n case 'digitalAssetImageSize':\n return (\n
\n {data}\n \n
\n
\n onOptionChange('assetImageSize', e)}\n />\n
\n \n \n \n
\n
\n );\n\n case 'digitalAssetResolution':\n return (\n
\n {data}\n \n
\n onOptionChange('assetResolution', e, '')}\n />\n \n \n \n
\n
\n );\n\n default:\n return data;\n }\n };\n\n // Product Config Render\n // const productConfigRender = (data) => {\n // return (\n // \n // {data?.map((item) => {\n // return (\n // \n // {item.name && (\n // document.getElementById('folder')}\n // >\n // \n // \n // document.getElementById('folder')\n // }\n // dropdownRender={(data) =>\n // selectConfigRender(item.name, data)\n // }\n // listHeight={145}\n // >\n // {selectOptionRender(item.name, item.option).map(\n // (option, index) => {\n // return (\n // \n // );\n // }\n // )}\n // \n // \n // \n // )}\n // \n // );\n // })}\n // \n // );\n // };\n\n // Digital Asset Config Render\n const digitalAssetConfigRender = (item, index) => {\n if (item.name) {\n return (\n \n document.getElementById(formName)}\n dropdownRender={(data) => selectConfigRender(item.name, data)}\n listHeight={110}\n >\n {selectOptionRender(item.name, item.option).map((option, index) => {\n const isImageFormat =\n item.name === 'digitalAssetImageFormat' ||\n 'digitalAssetImageFormat';\n const isOrigin = option === 'ORIGINAL';\n const shouldNull = isImageFormat && isOrigin;\n const optionValue = shouldNull ? null : option;\n return (\n \n );\n })}\n \n \n );\n }\n };\n\n // Checkbox Group Render\n const checkboxGroupRender = (data) => {\n return (\n \n \n \n {data?.map((item) => {\n return (\n \n {item.option?.map((child) => {\n return (\n \n \n \n {child.option?.map((grandChild, index) => {\n return (\n \n {cbHeaderRender(item, child, grandChild)}\n \n );\n })}\n \n \n \n );\n })}\n \n );\n })}\n \n \n \n );\n };\n\n const clearIndeterminate = () => {\n setIndeterminate(defaultConfig);\n };\n\n const onClear = () => {\n PRODUCT_CONFIG.forEach((item) => {\n for (const [, child] of item.option?.entries()) {\n form.setFieldsValue({\n [child.name]: false,\n });\n for (const [, grandChild] of child.option?.entries()) {\n form.setFieldsValue({\n [child.name]: {\n [grandChild]: false,\n },\n });\n }\n }\n form.setFieldsValue({ [item.name]: false });\n });\n\n form.setFieldsValue({\n downloadType: null,\n deliveryMethod: null,\n productImageNamingFormat: null,\n productImageFormat: null,\n productImageSize: null,\n productCropSize: 0,\n productResolution: null,\n productBackground: null,\n });\n\n clearIndeterminate();\n onSetType && onSetType(form.getFieldValue('downloadType'));\n onSetMethod && onSetMethod(form.getFieldValue('deliveryMethod'));\n };\n\n const onReset = () => {\n resetData();\n };\n\n useEffect(() => {\n if (selectedMapping && selectedMapping?.formatTypes?.length) {\n form.setFieldsValue({\n productDataFormat: selectedMapping?.formatTypes?.[0],\n });\n } else {\n form.setFieldsValue({ productDataFormat: 'JSON' });\n }\n }, [selectedMapping, form]);\n\n return (\n <>\n \n \n {/* Clear will be kept -> click ->reset , Reset will be removed, task #3705 */}\n \n \n \n \n \n \n \n {intl.formatMessage({\n id: `Taco.folder.download.configuration.welcomeText`,\n })}\n \n \n \n \n \n onSetType && onSetType(form.getFieldValue('downloadType'))\n }\n >\n {FOLDER_DOWNLOAD_TYPE?.map((option, index) => {\n return (\n \n document.getElementById(formName)\n }\n title={`${option.toUpperCase()} File Extension Download`}\n key={`type-${index}`}\n >\n \n \n \n \n );\n })}\n \n \n \n \n \n \n onSetMethod?.(form.getFieldValue('deliveryMethod'))\n }\n >\n {FOLDER_DELIVERY_METHOD?.map((option, index) => {\n if (option === 'ftp' && !memberInfo?.ftpEnabled) return null;\n return (\n \n document.getElementById(formName)\n }\n title={intl.formatMessage({\n id: `Taco.folder.download.configuration.deliveryMethod.${option}`,\n })}\n key={`method-${index}`}\n >\n \n \n \n \n );\n })}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {downloadEntityAmount?.product && (\n \n \n {checkboxGroupRender(PRODUCT_CONFIG)}\n {/* {productConfigRender(productData)} */}\n \n )}\n {downloadEntityAmount?.digitalAsset && (\n \n {digitalAssetData.map((item, index) => {\n return digitalAssetConfigRender(item, index);\n })}\n \n )}\n {downloadEntityAmount?.member && (\n \n \n document.getElementById(formName)}\n >\n {INFORMATION_SHEET_OPTIONS.map((option, index) => {\n return (\n \n );\n })}\n \n \n \n )}\n {downloadEntityAmount?.query && (\n \n \n document.getElementById(formName)}\n >\n {QUERIES_DATA_FORMAT.map((option, index) => {\n return (\n \n );\n })}\n \n \n \n )}\n {downloadEntityAmount?.report && (\n \n \n document.getElementById(formName)}\n >\n {REPORTS_DATA_FORMAT.map((option, index) => {\n return (\n \n );\n })}\n \n \n \n )}\n \n \n {\n const params = form.getFieldsValue();\n PRODUCT_CONFIG.forEach((item) => {\n delete params[item.name];\n for (const [key, child] of item.option?.entries()) {\n if (!params[child.name]) {\n return;\n }\n delete params[child.name]['value'];\n params[child.name] = Object.keys(params[child.name]).filter(\n (key) => {\n return params[child.name][key];\n }\n );\n }\n });\n continueSchedule(\n downloadEntityAmount?.member && params.memberDefinedSheets === null\n ? { ...params, memberDefinedSheets: 'RIVIR Default' }\n : params\n );\n }}\n />\n setVisibleEmailSelection(false)}\n visible={visibleEmailSelection}\n onSendEmail={onSendMultiEmail}\n primaryEmail={primaryEmail}\n alternativeEmail={alternativeEmail}\n >\n \n );\n};\n\nDownloadConfiguration.propTypes = {\n downloadSetting: oneOfType([PropTypes.array, PropTypes.object]),\n id: PropTypes.number,\n setLoading: PropTypes.func,\n onSetType: PropTypes.func,\n onSetMethod: PropTypes.func,\n};\n\nexport default injectIntl(DownloadConfiguration);\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { useSelector } from 'react-redux';\nimport * as folderSelectors from '../../controllers/selectors';\nimport { Divider, Button, Alert } from 'antd';\nimport { ArrowLeftOutlined, ArrowRightOutlined } from '@ant-design/icons';\nimport DownloadInformation from './DownloadInformation';\nimport DownloadConfiguration from './DownloadConfiguration';\nimport { FOLDER_DOWNLOAD_TYPE } from 'static/Constants';\nimport { useIntl } from 'react-intl';\nimport './style.less';\nimport DigitalRight from 'assets/DRM.png';\nimport { dialogFunction } from 'common/components';\nimport Messages from 'i18n/messages/folder';\n\nconst DownloadPanel = (props) => {\n const intl = useIntl();\n const {\n ownerFolder,\n shortDetail,\n id,\n onClosePanel,\n continueSchedule,\n hiddenBackToBtn,\n hiddenExecuteNow,\n memberOwnerId,\n } = props;\n\n const [loading, setLoading] = useState(false);\n const [type, setType] = useState();\n const [method, setMethod] = useState();\n\n const downloadSetting = useSelector(folderSelectors.selectDownloadSetting());\n const isDRM =\n shortDetail?.folderContents.filter((item) => item.drm).length > 0;\n const isDisabledScheduleDownload =\n !downloadSetting ||\n !FOLDER_DOWNLOAD_TYPE.includes(type) ||\n !['email', 'ftp'].includes(method);\n const drmDialog = () => {\n dialogFunction({\n type: 'warn',\n content: (\n
\n \n {intl.formatMessage({\n id: 'Taco.folder.download.drm',\n })}\n
\n ),\n\n okText: 'Cancel',\n cancelButtonProps: { htmlType: 'submit', form: 'folder' },\n cancelText: 'OK',\n });\n };\n\n return (\n
\n
\n {hiddenBackToBtn ? null : (\n }\n onClick={onClosePanel}\n >\n {intl.formatMessage(Messages.upLevelText)}\n \n )}\n\n
\n {hiddenExecuteNow ? null : (\n {\n if (isDRM) {\n drmDialog();\n }\n }}\n type='link'\n loading={loading}\n disabled={!downloadSetting}\n >\n {intl.formatMessage({\n id: 'Taco.folder.download.execute',\n })}\n \n \n )}\n\n \n document\n .getElementById('download-configuration__schedule-button')\n .click()\n }\n >\n {intl.formatMessage({\n id: 'Taco.folder.download.scheduleSetup',\n })}\n \n \n
\n
\n \n \n \n {isDisabledScheduleDownload ? (\n \n ) : null}\n
\n );\n};\n\nDownloadPanel.propTypes = {\n ownerFolder: PropTypes.bool,\n id: PropTypes.number,\n onClosePanel: PropTypes.func,\n};\n\nexport default DownloadPanel;\n","import React from 'react';\nimport { Row, Col, Typography, Skeleton } from 'antd';\nimport { formatMDY } from 'utils/formatDate';\nimport { formatSizeUnits } from 'utils/formatSizeUnits';\nimport EmptyFolderImg from 'assets/folder/empty-folder.png';\nimport FolderImg from 'assets/folder/folder.png';\nimport ShareFolderImg from 'assets/folder/shared-folder.png';\nimport { get } from 'lodash';\nimport './ScheduleInformation.less';\nimport { injectIntl } from 'react-intl';\nimport { InfoWithLabel } from 'common/components';\n\nconst { Text } = Typography;\n\nconst ScheduleInfomation = (props) => {\n const { ownerFolder, intl, scheduleSetting } = props;\n\n const thumbnailImg = !ownerFolder\n ? ShareFolderImg\n : get(scheduleSetting, 'items') > 0\n ? FolderImg\n : EmptyFolderImg;\n\n const metaData = [\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.owner',\n }),\n info:\n get(scheduleSetting, 'ownerName', '') &&\n get(scheduleSetting, 'ownerName', ''),\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.dateCreated',\n }),\n info:\n formatMDY(get(scheduleSetting, 'dateCreated', '')) !== 'Invalid Date'\n ? formatMDY(get(scheduleSetting, 'dateCreated', ''))\n : '',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.dateShared',\n }),\n info:\n formatMDY(get(scheduleSetting, 'dateShared', '')) !== 'Invalid Date'\n ? formatMDY(get(scheduleSetting, 'dateShared', ''))\n : '',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.editable',\n }),\n info: get(scheduleSetting, 'editable', '') ? 'Yes' : 'No',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.shareable',\n }),\n info: get(scheduleSetting, 'shareable', '') ? 'Yes' : 'No',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.specialPurpose',\n }),\n info: get(scheduleSetting, 'specialPurpose', '') ? 'Yes' : 'No',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.items',\n }),\n info:\n get(scheduleSetting, 'items', '') && get(scheduleSetting, 'items', ''),\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.estSize',\n }),\n info:\n get(scheduleSetting, 'estSize', '') &&\n formatSizeUnits(get(scheduleSetting, 'estSize', '')),\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.lastUpdated',\n }),\n info: (\n <>\n
\n {formatMDY(get(scheduleSetting, 'lastUpdated', '')) !==\n 'Invalid Date'\n ? formatMDY(get(scheduleSetting, 'lastUpdated', ''))\n : ''}\n
\n
\n {get(scheduleSetting, 'lastUpdatedBy', '') &&\n get(scheduleSetting, 'lastUpdatedBy', '')}\n
\n \n ),\n },\n\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.lastDownload',\n }),\n info:\n formatMDY(get(scheduleSetting, 'lastDownload', '')) !== 'Invalid Date'\n ? formatMDY(get(scheduleSetting, 'lastDownload', ''))\n : '',\n },\n {\n label: intl.formatMessage({\n id: 'Taco.folder.components.contentPane.lastSchedule',\n }),\n info:\n formatMDY(get(scheduleSetting, 'lastSchedule', '')) !== 'Invalid Date'\n ? formatMDY(get(scheduleSetting, 'lastSchedule', ''))\n : '',\n },\n ];\n\n const infoColProps = {\n infoColProps: {\n flex: 'auto',\n },\n labelColProps: {\n flex: '135px',\n },\n boldInfo: true,\n labelAlign: 'right',\n };\n\n const dataLeft = metaData\n ? metaData.slice(0, Math.ceil(metaData.length / 2))\n : [];\n const dataRight = metaData\n ? metaData.slice(Math.ceil(metaData.length / 2), metaData.length)\n : [];\n return (\n \n
\n \n \n \n \n \n \n {scheduleSetting?.folderName}\n \n \n \n
\n \n \n {dataLeft &&\n dataLeft.length > 0 &&\n dataLeft.map((item, index) => {\n return (\n \n );\n })}\n \n \n {dataRight &&\n dataRight.length > 0 &&\n dataRight.map((item, index) => {\n return (\n \n );\n })}\n \n \n
\n
\n
\n );\n};\n\nexport default injectIntl(ScheduleInfomation);\n","import React, { useState, useEffect } from 'react';\nimport './ScheduleConfiguration.less';\nimport {\n Radio,\n Checkbox,\n Row,\n Col,\n TimePicker,\n InputNumber,\n Collapse,\n Divider,\n Button,\n notification,\n Select,\n} from 'antd';\nimport PropTypes, { oneOfType } from 'prop-types';\n\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { WEEK_DAY, MONTH_LIST, DAY_LIST, ORDER_LIST } from 'static/Constants';\nimport { TIME_ZONES } from 'static/TimeZones';\nimport moment from 'moment';\nimport { configScheduleDownload } from 'services/folder';\n\nimport * as folderSelectors from '../../controllers/selectors';\nimport * as folderActions from '../../controllers/actions';\n\nimport { Form, WrapperSelect } from 'common/components';\nimport { formatRangeDateTime } from 'utils/formatDate';\n\nconst { Panel } = Collapse;\nconst { Option } = Select;\n\nconst ScheduleConfiguration = (props) => {\n const { downloadConfig, folderId, onSetLoading } = props;\n const [type, setType] = useState(null);\n const [disableSpecific, setDisableSpecific] = useState(false);\n const [disableOrder, setDisableOrder] = useState(false);\n const [disableMonth, setDisableMonth] = useState(false);\n const [disableDays, setDisableDays] = useState(false);\n const [activeKey, setActiveKey] = useState(['month']);\n const [form] = Form.useForm();\n\n const dispatch = useDispatch();\n\n const selectedMapping = useSelector(folderSelectors.selectSelectedMapping());\n const downloadSetting = useSelector(folderSelectors.selectDownloadSetting());\n\n useEffect(() => {\n setActiveKey(['month']);\n setDisableDays(false);\n }, [type]);\n\n useEffect(() => {\n form.setFieldsValue({\n timezone: TIME_ZONES[16].utc[0],\n });\n }, [form]);\n\n const openNotify = (result, description) => {\n notification[result ? 'success' : 'error']({\n message: 'Config schedule download',\n description: description,\n });\n };\n\n function onFinish(params) {\n const test = new Date(formatRangeDateTime(params.runAt));\n const newDate = new Date(test.getTime() - test.getTimezoneOffset() * 60000);\n const submitForm = {\n ...downloadConfig,\n ...params,\n interval: !params.interval ? 'Daily' : params.interval,\n folderId: folderId,\n runEvery: params.runEvery > 0 ? params.runEvery : 0,\n runAt: newDate.toISOString(),\n specificScheduleOrdinalNumeral:\n params.specificScheduleOrdinalNumeral &&\n !Array.isArray(params.specificScheduleOrdinalNumeral)\n ? [params.specificScheduleOrdinalNumeral]\n : [],\n specificScheduleDaysOfWeek:\n params.specificScheduleDaysOfWeek &&\n !Array.isArray(params.specificScheduleDaysOfWeek)\n ? [params.specificScheduleDaysOfWeek]\n : params.specificScheduleDaysOfWeek\n ? params.specificScheduleDaysOfWeek\n : [],\n userTimeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n };\n\n onSetSchedule(submitForm);\n }\n\n async function onSetSchedule(values) {\n dispatch(folderActions.saveStatusDownloadFolder('loading'));\n const mappingId = selectedMapping?.id ? selectedMapping?.id : null;\n\n const newFormValues = {\n ...values,\n };\n\n onSetLoading(true);\n let result = await configScheduleDownload({ ...newFormValues, mappingId });\n if (result && result.isSuccess) {\n openNotify(true, result.message);\n setType('Daily');\n form.resetFields();\n } else {\n openNotify(false, result.message);\n }\n onSetLoading(false);\n }\n\n const monthDaysProps = {\n form,\n disableDays,\n setDisableSpecific,\n setActiveKey,\n };\n\n const specificScheduleProps = {\n form,\n disableSpecific,\n setDisableDays,\n };\n\n return (\n \n \n Use the information below to setup an automation schedule\n \n \n \n
Run at:
\n \n \n \n trigger.parentElement}\n />\n \n \n \n \n \n option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0\n }\n // defaultValue={TIME_ZONES[16].utc[0]}\n >\n {TIME_ZONES.map((zone) => (\n \n ))}\n \n \n \n
\n \n
Interval:
\n
\n \n \n \n {\n setType(params.target.value);\n setDisableOrder(false);\n form.setFieldsValue({\n ...form.getFieldValue(),\n runEvery: 0,\n onDate: [],\n specificScheduleOrdinalNumeral: [],\n atDays: [],\n atMonth: [],\n specificScheduleDaysOfWeek: [],\n });\n setDisableMonth(false);\n setDisableSpecific(false);\n }}\n >\n \n \n Daily\n \n \n Weekly\n \n \n Monthly\n \n \n \n \n \n \n\n {type === 'Weekly' ? (\n <>\n \n \n \n
Every:
\n \n \n \n \n \n \n
weeks
\n
\n \n \n \n
On:
\n \n \n \n \n \n {WEEK_DAY.map((option, index) => {\n return (\n \n \n {option}\n \n \n );\n })}\n \n \n \n \n
\n
\n \n ) : type === 'Monthly' ? (\n <>\n \n setActiveKey(key)}\n activeKey={activeKey}\n ghost\n >\n \n \n \n \n \n \n {\n setDisableMonth(true);\n setDisableOrder(true);\n setDisableSpecific(true);\n setType('Daily');\n form.resetFields();\n }}\n style={{ display: 'none' }}\n id='schedule-configuration__reset-button'\n >\n Reset\n \n \n \n ) : null}\n \n );\n};\n\nconst MonthDaysSection = (props) => {\n const { form, disableDays, setActiveKey, setDisableSpecific } = props;\n\n const handleChangeDays = () => {\n const { atDays } = form.getFieldValue();\n\n if (atDays?.length > 0) {\n setDisableSpecific(true);\n setActiveKey(['month']);\n } else {\n setDisableSpecific(false);\n }\n };\n\n return (\n <>\n \n \n \n \n \n {MONTH_LIST.map((option, index) => {\n return (\n \n \n {option}\n \n \n );\n })}\n \n \n \n \n \n \n \n
Days:
\n \n \n \n \n \n {DAY_LIST.map((option, index) => {\n return (\n \n \n {option}\n \n \n );\n })}\n \n \n \n \n
\n \n );\n};\n\nconst SpecificScheduleSection = (props) => {\n const { form, disableSpecific, setDisableDays } = props;\n const [checkAll, setCheckAll] = useState(false);\n const [disableCheckAll, setDisableCheckAll] = useState(false);\n\n const { specificScheduleOrdinalNumeral } = form.getFieldValue();\n\n const handleCheckAllDays = (e) => {\n if (e.target.checked) {\n form.setFieldsValue({\n ...form.getFieldValue(),\n specificScheduleDaysOfWeek: WEEK_DAY,\n });\n\n setCheckAll(true);\n } else {\n form.setFieldsValue({\n ...form.getFieldValue(),\n specificScheduleDaysOfWeek: [],\n });\n\n setCheckAll(false);\n }\n };\n\n const handleChangeOrder = () => {\n const { specificScheduleOrdinalNumeral } = form.getFieldValue();\n if (specificScheduleOrdinalNumeral.length > 0) {\n setDisableDays(true);\n setDisableCheckAll(true);\n }\n };\n\n const handleChangeWeekDay = () => {\n const { specificScheduleDaysOfWeek, specificScheduleOrdinalNumeral } =\n form.getFieldValue();\n\n if (specificScheduleDaysOfWeek.length > 0) {\n setDisableDays(true);\n }\n\n if (\n specificScheduleDaysOfWeek.length === 0 &&\n specificScheduleOrdinalNumeral.length === 0\n ) {\n setDisableDays(false);\n }\n };\n\n return (\n \n \n \n \n \n {ORDER_LIST.map((option, index) => {\n return (\n \n \n {option}\n \n \n );\n })}\n \n \n \n \n \n \n All\n
\n \n {specificScheduleOrdinalNumeral?.length > 0 ? (\n \n \n {WEEK_DAY.map((option, index) => {\n return (\n \n \n {option}\n \n \n );\n })}\n \n \n ) : (\n \n \n {WEEK_DAY.map((option, index) => {\n return (\n \n \n {option}\n \n \n );\n })}\n \n \n )}\n \n \n \n );\n};\n\nScheduleConfiguration.propTypes = {\n downloadConfig: oneOfType([PropTypes.array, PropTypes.object]),\n folderId: PropTypes.number,\n onSetLoading: PropTypes.func,\n};\n\nexport default ScheduleConfiguration;\n","import React, { useState } from 'react';\nimport './style.less';\nimport { ArrowLeftOutlined, ArrowRightOutlined } from '@ant-design/icons';\nimport { injectIntl } from 'react-intl';\nimport ScheduleInformation from './ScheduleInformation';\nimport ScheduleConfiguration from './ScheduleConfiguration';\nimport { Divider, Button } from 'antd';\nimport PropTypes from 'prop-types';\n\nconst SchedulePanel = (props) => {\n const {\n shortDetail,\n ownerFolder,\n onClosePanel,\n downloadConfig,\n onBackDownloadSetup,\n intl,\n } = props;\n const [loading, setLoading] = useState(false);\n\n return (\n
\n
\n }\n onClick={() => {\n onClosePanel && onClosePanel();\n document.getElementById('schedule-configuration__reset-button') &&\n document\n .getElementById('schedule-configuration__reset-button')\n .click();\n onBackDownloadSetup && onBackDownloadSetup();\n }}\n >\n {intl.formatMessage({\n id: 'Taco.folder.download.backDownload',\n })}\n \n {\n // document\n // .getElementById('schedule-configuration__submit-button')\n // .click();\n // }}>\n >\n {intl.formatMessage({\n id: 'Taco.folder.download.run',\n })}\n \n \n
\n \n \n \n
\n );\n};\n\nSchedulePanel.propTypes = {\n shortDetail: PropTypes.object,\n ownerFolder: PropTypes.bool,\n onClosePanel: PropTypes.func,\n downloadConfig: PropTypes.object,\n};\n\nexport default injectIntl(SchedulePanel);\n","import React, { useState, useImperativeHandle, forwardRef } from 'react';\n\nimport classnames from 'classnames';\n\nimport DownloadPanel from '../download-panel';\nimport SchedulePanel from '../schedule-panel';\n\nimport { sleep } from 'utils/delay';\n\nimport {\n WIDTH_CONTANT_PANE,\n DOWNLOAD_FOLDER_PANEL_STEP,\n} from 'static/Constants';\n\nimport 'styles/animation.less';\n\nconst FolderPanelDownload = forwardRef((props, ref) => {\n const { folder } = props;\n\n const [visibleStep, setVisibleStep] = useState(\n DOWNLOAD_FOLDER_PANEL_STEP.NONE\n );\n const [animationTrigger, setAnimationTrigger] = useState(\n DOWNLOAD_FOLDER_PANEL_STEP.NONE\n );\n\n const [downloadConfig, setDownloadConfig] = useState(null);\n\n useImperativeHandle(\n ref,\n () => {\n return {\n openDownloadPanel: () => {\n openPanel(DOWNLOAD_FOLDER_PANEL_STEP.DIRECT);\n },\n };\n },\n []\n );\n\n const openPanel = async (panel) => {\n setVisibleStep(panel);\n await sleep(100);\n setAnimationTrigger(panel);\n };\n\n const closePanel = async (panel) => {\n setAnimationTrigger(panel);\n\n await sleep(500);\n\n setVisibleStep(panel);\n };\n\n const closeDownloadPanel = () => {\n closePanel(DOWNLOAD_FOLDER_PANEL_STEP.NONE);\n };\n\n const openScheduledDownload = (params) => {\n openPanel(DOWNLOAD_FOLDER_PANEL_STEP.SCHEDULED);\n\n setDownloadConfig(params);\n };\n\n const closeScheduledDownload = async () => {\n closePanel(DOWNLOAD_FOLDER_PANEL_STEP.DIRECT);\n };\n\n return (\n <>\n {visibleStep !== DOWNLOAD_FOLDER_PANEL_STEP.NONE ? (\n \n \n {visibleStep === DOWNLOAD_FOLDER_PANEL_STEP.SCHEDULED ? (\n \n \n \n ) : null}\n \n ) : null}\n \n );\n});\n\nexport default FolderPanelDownload;\n","import React, { useRef } from 'react';\nimport PropTypes from 'prop-types';\n\nimport FolderPanelContent from './FolderPanelContent';\nimport FolderPanelHeader from './FolderPanelHeader';\nimport FolderPanelDownload from './FolderPanelDownload';\n\nimport './FolderPanel.less';\n\nconst FolderPanel = (props) => {\n const downloadPanelActions = useRef();\n\n const {\n onClosePanel,\n shortDetail,\n ownerFolder,\n seePreview,\n onEditClick,\n clickEditFolderHandler,\n } = props;\n\n const openDownloadPanel = () => {\n downloadPanelActions.current?.openDownloadPanel();\n };\n\n return (\n
\n {shortDetail && (\n <>\n
\n \n \n
\n \n \n )}\n
\n );\n};\n\nFolderPanel.propTypes = {\n onTrigger: PropTypes.func,\n onClosePanel: PropTypes.func,\n loadingDetail: PropTypes.bool,\n shortDetail: PropTypes.object,\n ownerFolder: PropTypes.bool,\n seePreview: PropTypes.func,\n onEditClick: PropTypes.func,\n};\n\nexport default FolderPanel;\n","import { useEffect } from 'react';\n\nimport * as servicesMember from 'services/members';\n\nimport { useFetch } from 'hooks/useAsync';\n\nexport const useMemberPublicContact = (props) => {\n const { isEnabled, memberId } = props;\n const { data, run } = useFetch();\n\n const fetchMemberPublicContact = (memberId) => {\n const params = {\n memberId: memberId,\n pageIndex: 1,\n pageSize: 100,\n };\n\n run(servicesMember.getPublicContact(params));\n };\n\n useEffect(() => {\n isEnabled && fetchMemberPublicContact(memberId);\n }, []);\n\n return {\n memberPublicContactList: data?.data?.gridData,\n fetchMemberPublicContact,\n };\n};\n","import React, { memo } from 'react';\n\nimport { Spin } from 'antd';\nimport { isEqual, capitalize } from 'lodash';\n\nimport { OpenItemContentPane } from 'common/components/openItem';\nimport FolderPanel from './panel/FolderPanel';\nimport { AssetPanel } from 'pages/branded-assets/components';\nimport MemberPanel from 'common/components/member-preview/MemberPanel';\nimport { QueryPanel } from 'pages/favorite-queries/components';\nimport { ReportingPanel } from 'pages/branded-reporting/components';\nimport {\n ProductContent,\n ProductActions,\n ProductInformation,\n ProductLogoThumbnail,\n} from 'pages/branded-products/components/content-pane';\n\nimport { useFolderContentPane } from 'pages/folders/hooks';\nimport { useMemberPublicContact } from 'hooks/useMemberPublicContact';\nimport { mapJSONToMarkdownObject } from 'utils/jsonChecker';\nimport * as getLink from 'utils/common/linkBuilder';\n\nimport * as constant from 'static/Constants';\n\nconst FolderContentPane = (props) => {\n const {\n setContentPreview,\n onCloseCallbackHandler,\n onOpenEdit,\n selectFolder,\n isOwner,\n setVisible,\n clickEditFolderHandler,\n addDrawerStack,\n } = props;\n\n const { shortDetail, isLoading, contentPaneType } = useFolderContentPane();\n\n const getOpenItemConfig = () => {\n const urlPath = getLink.getLinkPathByEntityType(contentPaneType);\n\n const configsCollection = {\n asset: {\n type: 'ASSET_CONTENT_PANE',\n name: shortDetail?.assetName,\n },\n member: {\n type: 'MEMBER_CONTENT_PANE',\n name: shortDetail?.memberName,\n },\n product: {\n type: 'PRODUCT_CONTENT_PANE',\n name: shortDetail?.productName,\n },\n reporting: {\n type: 'REPORTING_CONTENT_PANE',\n name: shortDetail?.name,\n },\n folder: {\n type: 'FOLDER_CONTENT_PANE',\n name: shortDetail?.folderName,\n },\n };\n\n const config = configsCollection[contentPaneType];\n\n return {\n type: constant.OPEN_ITEM.TYPE[config?.type],\n mode: constant.OPEN_ITEM.MODE.VIEW,\n url: `${urlPath}/${shortDetail?.id}`,\n name:\n config?.name ||\n `${capitalize(contentPaneType)} Full View (default view)`,\n };\n };\n\n const renderContentPane = () => {\n if (contentPaneType === 'folder') return renderFolderPanel();\n else return renderItemPanel();\n };\n\n const renderFolderPanel = () => {\n return (\n {\n setContentPreview(params);\n addDrawerStack('contentPreview');\n }}\n onClosePanel={() => {\n setVisible(false);\n }}\n onEditClick={onOpenEdit}\n />\n );\n };\n\n const renderItemPanel = () => {\n const panelCollection = {\n asset: AssetItemPanel,\n member: MemberItemPanel,\n product: ProductItemPanel,\n reporting: ReportingItemPanel,\n query: QueryItemPanel,\n };\n\n if (!contentPaneType) return null;\n\n const ItemPanel = panelCollection[contentPaneType];\n\n return ;\n };\n\n return (\n \n {isLoading || !shortDetail ? (\n
\n \n
\n ) : (\n renderContentPane()\n )}\n \n );\n};\n\nconst areEqual = (prevProps, nextProps) => {\n // just update when click to edit button to change view to edit mode, that button only clickable when selected folder is editable\n if (\n (prevProps?.shortDetail?.editable === nextProps?.shortDetail?.editable) ===\n true\n ) {\n return false;\n }\n\n if (!isEqual(prevProps.shortDetail, nextProps.shortDetail)) {\n return false;\n }\n\n return true;\n};\n\nconst AssetItemPanel = (props) => {\n const { shortDetail } = props;\n\n return ;\n};\n\nconst MemberItemPanel = (props) => {\n const { shortDetail } = props;\n\n const { memberPublicContactList } = useMemberPublicContact({\n isEnabled: true,\n memberId: shortDetail.id,\n });\n\n function convertTagLine(data) {\n const parsedTagline = mapJSONToMarkdownObject(data);\n return parsedTagline?.content;\n }\n\n return (\n \n );\n};\n\nconst ProductItemPanel = (props) => {\n const { shortDetail } = props;\n\n return (\n \n \n \n \n \n );\n};\n\nconst ReportingItemPanel = (props) => {\n const { shortDetail } = props;\n\n return ;\n};\n\nconst QueryItemPanel = (props) => {\n const { shortDetail } = props;\n\n return ;\n};\n\nexport default memo(FolderContentPane, areEqual);\n","import React, { useState } from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\nimport { Modal, Input, Spin, notification, Row } from 'antd';\nimport gridViewReducer from 'common/components/grid-view/controllers/reducer';\nimport gridViewSaga from 'common/components/grid-view/controllers/saga';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\nimport { Form } from 'common/components';\n\nimport * as selectorsGlobal from '@redux/global/selectors';\nimport * as actionGlobal from '@redux/global/actions';\nimport { useInjectReducer } from 'utils/common/injectedReducers';\nimport { useInjectSaga } from 'utils/common/injectSaga';\nimport * as services from 'services/apl/index.js';\nimport messagesProduct from 'i18n/messages/product';\nimport { useIntl } from 'react-intl';\nconst keyGridView = 'gridView';\n\nconst ModalAddFolderToAPL = (props) => {\n useInjectReducer({ key: keyGridView, reducer: gridViewReducer });\n useInjectSaga({ key: keyGridView, saga: gridViewSaga });\n const [loading, setLoading] = useState(false);\n const dispatch = useDispatch();\n const visibleModal = useSelector(selectorsGlobal.selectShowAddFolderToAPL());\n const folderList = useSelector(\n selectorsGridView.makeSelectDetailCurrentITemsSelection()\n );\n const folderListIds = folderList?.map((item) => item.id);\n const [form] = Form.useForm();\n const { TextArea } = Input;\n const onCloseModal = () => {\n form.resetFields();\n dispatch(actionGlobal.updateAddFolderToAPL(false));\n };\n const intl = useIntl();\n\n const handleAddToAPL = (value) => {\n setLoading(true);\n const params = {\n folderIds: folderListIds,\n aplName: value.aplName,\n aplDescription: value.aplDescription,\n };\n services\n .addFoldersIntoNewAPL(params)\n .then((response) => {\n if (response.isSuccess) {\n notification.success({\n message: (\n <>\n \n {response.data.productIdsAdded.length} product(s) adds\n successfully\n \n \n {response.data.productIdsIgnored.length} product(s) adds error\n \n \n ),\n });\n } else {\n notification.error({ message: response?.message });\n }\n })\n .catch((error) => {\n notification.error({ message: error });\n })\n .finally(() => {\n setLoading(false);\n onCloseModal();\n });\n };\n\n return (\n <>\n form.submit()}\n >\n \n handleAddToAPL(value)}\n >\n \n \n \n \n \n \n \n \n \n \n );\n};\n\nexport default ModalAddFolderToAPL;\n","import React, { useEffect, useCallback, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { Skeleton } from 'antd';\n\nimport { GridView } from 'common/components/';\nimport FolderContentPane from '../FolderContentPane';\n// import { MemberPanel } from 'pages/branded-members/components/index';\nimport ModalAddFolderToAPL from './ModalAddFolderToAPL';\n\nimport {\n FolderGridThumbnail,\n FolderGridTile,\n} from 'pages/folders/shared/components';\n\nimport useCheckIsFolderOwner from 'hooks/useCheckIsFolderOwner';\nimport { useAgGridFolder } from '../../hooks/useAgGridFolder';\n\nimport * as folderEndpoints from 'services/folder/endpoints';\n\nimport * as folderActions from '../../controllers/actions';\n// import * as folderSelectors from '../../controllers/selectors';\nimport * as globalActions from '@redux/global/actions';\nimport * as globalSelectors from '@redux/global/selectors';\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\n\nimport { injectIntl } from 'react-intl';\nimport { sortFolderToTop } from 'pages/folders/shared/utils';\n\nconst FolderGridView = (props) => {\n const {\n loading,\n dataList,\n totalPagination,\n pageSizePagination,\n pageNumberPagination,\n loadingDetail,\n selectFolder,\n enableDownload,\n disableItemEvent,\n typeView,\n isInModal,\n visibleContentPane,\n hidePagination,\n folderOption,\n isFavoriteRoute,\n queryConditions,\n requestParams,\n shouldReloadDetailGrid,\n enableDragToFolder,\n shouldShowAdvanceFilterTags,\n searchText,\n } = props;\n const dispatch = useDispatch();\n const isShowDetail = useSelector(globalSelectors.selectShowDetail());\n const itemsSelection = useSelector(\n selectorsGridView.makeSelectItemsSelection()\n );\n const isOwner = useCheckIsFolderOwner();\n const isEditable = selectFolder?.editable;\n const [visible, setVisible] = useState(false);\n const [contentPreview, setContentPreview] = useState(null);\n\n // const queryPreview = useSelector(folderSelectors.selectQueryPreview());\n const {\n gridConfigProps,\n columnDefs,\n shouldReloadAgGrid,\n requestParamsFolder,\n // requestParams: requestParamsFolders,\n } = useAgGridFolder({\n folderOption,\n searchText,\n typeView,\n requestParams,\n });\n\n useEffect(() => {\n if (!visibleContentPane) {\n document.getElementById('button-clear-table-item') &&\n document.getElementById('button-clear-table-item').click();\n }\n }, [visibleContentPane]);\n\n useEffect(() => {\n return () => {\n // turn edit mode off when close ed panel\n dispatch(folderActions.turnEditShortContentOn(false));\n };\n }, []);\n\n const onClose = () => {\n dispatch(globalActions.removeCurrentFolder());\n setVisible(false);\n };\n\n const clickEditFolderHandler = () => {\n dispatch(folderActions.turnEditShortContentOn(true));\n dispatch(actionsGridView.updateVisible(true));\n };\n\n useEffect(() => {\n if (contentPreview && contentPreview?.type?.toLowerCase() === 'asset') {\n dispatch(folderActions.getDigitalAssetPreview(contentPreview.id));\n } else if (\n contentPreview &&\n contentPreview?.type?.toLowerCase() === 'member'\n ) {\n dispatch(folderActions.getMemberPreview(contentPreview.id));\n dispatch(folderActions.getPublicContact(contentPreview.id));\n } else if (\n contentPreview &&\n contentPreview?.type?.toLowerCase() === 'query'\n ) {\n dispatch(folderActions.getQueryPreview(contentPreview.id));\n } else if (\n contentPreview &&\n contentPreview?.type?.toLowerCase() === 'reporting'\n ) {\n dispatch(folderActions.getReportingPreview(contentPreview.id));\n } else if (\n contentPreview &&\n contentPreview?.type?.toLowerCase() === 'product'\n ) {\n dispatch(folderActions.getProductPreview(contentPreview.id));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [contentPreview]);\n\n useEffect(() => {\n if (visibleContentPane && selectFolder && visible) {\n dispatch(folderActions.getDownloadSetting(selectFolder.id));\n }\n }, [visibleContentPane, selectFolder, visible]);\n\n useEffect(() => {\n // close download content pane when click edit button\n onClose();\n // eslint-disable-next-line\n }, [visibleContentPane]);\n\n const closeDetailContentPane = useCallback(() => {\n const shouldHideContentPane =\n (!isShowDetail && visibleContentPane && !isEditable) ||\n itemsSelection?.length !== 1;\n\n shouldHideContentPane && dispatch(actionsGridView.updateVisible(false));\n\n // eslint-disable-next-line\n }, [itemsSelection, isEditable]);\n\n const switchToDetailView = useCallback(() => {\n const shouldSwitchToDetailView =\n !isEditable && itemsSelection?.length === 1;\n\n shouldSwitchToDetailView &&\n dispatch(folderActions.turnEditShortContentOn(false));\n // eslint-disable-next-line\n }, [itemsSelection, isEditable]);\n\n useEffect(() => {\n // close detail content pane if needed\n closeDetailContentPane();\n // switch to detail content view if needed\n switchToDetailView();\n }, [closeDetailContentPane, switchToDetailView]);\n\n const onOpenEdit = () => {\n dispatch(folderActions.turnEditShortContentOn(true));\n };\n\n const onCloseEdit = () => {\n dispatch(folderActions.turnEditShortContentOn(false));\n // close detail content pane if show detail mode is off\n !isShowDetail && dispatch(actionsGridView.updateVisible(false));\n };\n\n const onCloseCallbackHandler = () => {\n onCloseEdit();\n };\n\n const folderContentPaneProps = {\n setContentPreview,\n onCloseCallbackHandler,\n onCloseEdit,\n onOpenEdit,\n loadingDetail,\n selectFolder,\n folderOption,\n isOwner,\n setVisible,\n clickEditFolderHandler,\n };\n\n const urlGrid = isFavoriteRoute\n ? folderEndpoints.FAVORITE_FOLDER_DETAIL_GRID\n : folderEndpoints.FOLDER_DETAIL_GRID;\n const urlGridDistinct = isFavoriteRoute\n ? folderEndpoints.FAVORITE_FOLDER_DETAIL_GRID_DISTINCT\n : folderEndpoints.FOLDER_DETAIL_GRID_DISTINCT;\n\n const isApplyDefaultSort = searchText ? false : true;\n\n return (\n <>\n \n
\n {\n const newConfigProps = {\n ...configProps,\n folderOption,\n disableEvent: true,\n };\n return ;\n }}\n tileGridBody={(configProps) => {\n const { clickEvents } = configProps;\n const newConfigProps = {\n ...clickEvents,\n ...configProps,\n folderOption,\n disableEvent: true,\n };\n return ;\n }}\n columnDefs={columnDefs}\n urlGrid={urlGrid}\n urlGridDistinct={urlGridDistinct}\n responseParams='data'\n requestParams={{\n folderOption,\n ...requestParamsFolder,\n }}\n shouldReloadDetailGrid={shouldReloadAgGrid}\n queryConditions={queryConditions}\n hidePagination={hidePagination}\n panelDetail={}\n typeView={typeView}\n type={'Folder'}\n disableItemEvent={disableItemEvent}\n enableDragToFolder={enableDragToFolder}\n notShowHeaderCheckbox={true}\n gridConfigProps={gridConfigProps}\n shouldShowAdvanceFilterTags={shouldShowAdvanceFilterTags}\n applyDefaultSort={isApplyDefaultSort}\n sortDataHandler={sortFolderToTop}\n />\n
\n
\n \n \n );\n};\n\nFolderGridView.propTypes = {\n loading: PropTypes.bool,\n dataList: PropTypes.array,\n totalPagination: PropTypes.number,\n pageSizePagination: PropTypes.number,\n pageNumberPagination: PropTypes.number,\n columns: PropTypes.array,\n enableDownload: PropTypes.bool,\n disableItemEvent: PropTypes.bool,\n typeView: PropTypes.string,\n isInModal: PropTypes.bool,\n visibleContentPane: PropTypes.bool,\n hidePagination: PropTypes.bool,\n folderOption: PropTypes.string,\n isFavoriteRoute: PropTypes.bool,\n};\n\nFolderGridView.defaultProps = {\n enableDownload: true,\n propTypeView: false,\n};\n\nexport default injectIntl(FolderGridView);\n","import React, { useEffect } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Input, Checkbox, Col, Row, Spin, DatePicker, Select } from 'antd';\n\nimport { formatMDY } from 'utils/formatDate';\nimport Message from 'i18n/messages/folder';\nimport memberReducer from 'pages/company-profile/controllers/reducer';\nimport { useInjectReducer } from 'utils/common/injectedReducers';\nimport { useInjectSaga } from 'utils/common/injectSaga';\nimport saga from 'pages/company-profile/controllers/saga';\nimport userSelectors from '@redux/user/selectors';\nimport moment from 'moment';\nimport * as memberActions from 'pages/company-profile/controllers/actions';\nimport { FormattedMessage } from 'react-intl';\nimport { Form, WrapperSelect } from 'common/components';\nimport { getDateFormat } from 'utils/formatDate';\n\nimport {\n PRIVATE_FOLDER_VISIBILITY,\n FOLDER_VISIBILITY,\n DATE_FORMAT,\n} from 'static/Constants';\n\nimport { useGetMemberHeaderFromMemberId } from 'common/queries/member-module';\n\nconst formItemLayout = {\n labelCol: { span: 10 },\n wrapperCol: { span: 14 },\n};\n\nconst FolderEditDetailContent = (props) => {\n useInjectReducer({ key: 'member', reducer: memberReducer });\n useInjectSaga({ key: 'member', saga });\n\n const dispatch = useDispatch();\n\n const { folderInfo } = props;\n\n const userInfo = useSelector(userSelectors.makeSelectUserInfo());\n\n useEffect(() => {\n dispatch(memberActions.getMemberProfileHeader(userInfo?.member?.id));\n }, [dispatch, userInfo?.member?.id]);\n\n const { data: memberHeaderOfFolderOwner } = useGetMemberHeaderFromMemberId({\n memberId: folderInfo?.ownerId,\n enabled: Boolean(folderInfo && folderInfo?.ownerId),\n });\n\n const isPrivateVisibilityFolder =\n memberHeaderOfFolderOwner?.folders?.toLowerCase() === 'private';\n\n const isRootFolder = folderInfo?.level === 1;\n\n function disabledDate(current) {\n // Can not select days before today and today\n return current && current < moment().endOf('day');\n }\n\n const FieldItemInputDisabled = ({ data }) => {\n return (\n }\n >\n \n \n );\n };\n\n const FieldItemCheckboxDisabled = ({ data }) => {\n return (\n }\n valuePropName='checked'\n >\n \n \n );\n };\n\n const FieldItemCheckbox = ({ data }) => {\n return (\n }\n valuePropName='checked'\n >\n \n \n );\n };\n\n const FieldItemRangePicker = ({ data }) => {\n return (\n }\n >\n \n \n );\n };\n const FieldItemRangePickerDisabled = ({ data }) => {\n return (\n }\n >\n \n \n );\n };\n return (\n <>\n \n \n \n }\n rules={[\n {\n required: true,\n message: (\n \n ),\n },\n {\n whitespace: true,\n message: (\n \n ),\n },\n ]}\n className='folder-panel-edit-content__folder-name'\n >\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n {isPrivateVisibilityFolder\n ? PRIVATE_FOLDER_VISIBILITY?.slice()\n .sort()\n .map((visibility) => (\n \n {visibility}\n \n ))\n : FOLDER_VISIBILITY?.slice()\n .sort()\n .map((visibility) => (\n \n {visibility}\n \n ))}\n \n \n \n \n \n \n );\n};\n\nexport default FolderEditDetailContent;\n","import React, { useEffect, useState } from 'react';\nimport { Form, Button, Col, Row } from 'antd';\nimport { StyledModal } from 'common/components';\nimport FolderEditDetailContent from 'pages/folders/folder-details/FolderEditDetailContent';\nimport _ from 'lodash';\nimport { editFolderShortContent } from 'services/folder';\nimport { apiHandler } from 'utils/api';\nimport moment from 'moment';\nimport { sleep } from 'utils/delay';\n\nexport const WIDTH_CONTANT_PANE = 500;\n\nconst FolderEditModal = ({\n visible,\n onCancel,\n folderInfo,\n idSelected,\n onSaveSuccess,\n}) => {\n const [form] = Form.useForm();\n const [loading, setLoading] = useState(false);\n\n const folderName = Form.useWatch('folderName', form);\n\n const isFolderNameEmpty = folderName?.trim() === '';\n\n const submitUpdateSuccessCallback = () => {\n onSaveSuccess && onSaveSuccess();\n setLoading(false);\n };\n\n const saveFolder = async () => {\n setLoading(true);\n const formValue = form.getFieldsValue();\n const params = _.pick(formValue, [\n 'id',\n 'folderName',\n 'specialPurpose',\n 'expirationDate',\n 'visibility',\n ]);\n await sleep(1000);\n apiHandler({\n service: editFolderShortContent,\n params: { ...params, id: idSelected },\n successMessage: 'Edit Folder Successfully !',\n errorMessage: 'Edit Folder Failed !',\n successCallback: submitUpdateSuccessCallback,\n onFinally: () => {\n setLoading(false);\n },\n });\n };\n\n const renderModalFooter = () => {\n const CancelBtn = Button;\n const SaveBtn = Button;\n\n return (\n \n \n \n \n Cancel\n \n \n Save\n \n \n \n );\n };\n\n const modalProps = {\n title: 'Edit Folder',\n visible,\n onCancel,\n\n width: 700,\n bodyStyle: {\n minHeight: '40vh',\n },\n maskClosable: false,\n okText: 'Save',\n onOk: saveFolder,\n footer: renderModalFooter(),\n };\n\n useEffect(() => {\n if (folderInfo) {\n const {\n dateCreated,\n dateShared,\n lastUpdated,\n lastDownload,\n lastSchedule,\n expirationDate,\n ...rest\n } = folderInfo;\n const paramsForm = {\n ...rest,\n dateCreated: dateCreated ? moment(dateCreated) : null,\n lastUpdated: lastUpdated ? moment(lastUpdated) : null,\n dateShared: dateShared ? moment(dateShared) : null,\n lastDownload: lastDownload ? moment(lastDownload) : null,\n lastSchedule: lastSchedule ? moment(lastSchedule) : null,\n expirationDate: expirationDate ? moment(expirationDate) : null,\n };\n\n form.setFieldsValue(paramsForm);\n }\n }, [folderInfo]);\n\n return (\n <>\n \n \n \n \n \n \n );\n};\n\nexport default FolderEditModal;\n","import { Images } from 'config/assets';\n\nimport Reporting from 'assets/reporting/Reporting.png';\nimport AssetReport from 'assets/reporting/AssetReport.png';\nimport ProductReport from 'assets/reporting/ProductReport.png';\nimport MemberReport from 'assets/reporting/MemberReport.png';\n\nexport const getThumbnailImage = (dataDetail, type) => {\n const totalCount =\n dataDetail?.subFolderCount +\n dataDetail?.contentsCount +\n dataDetail?.productCount +\n dataDetail?.assetCount +\n dataDetail?.reportingCount +\n dataDetail?.queryCount +\n dataDetail?.memberCount;\n\n const reportingImage =\n (dataDetail?.advType === 'DigitalMedia' && AssetReport) ||\n (dataDetail?.advType === 'Member' && MemberReport) ||\n (dataDetail?.advType === 'ProductItem' && ProductReport);\n\n const imageCollection = {\n folder: totalCount > 0 ? Images.folder : Images.emptyFolder,\n reporting: reportingImage,\n query: Reporting,\n };\n\n const image = imageCollection[type] || dataDetail?.thumbnail;\n\n return image;\n};\n","import * as types from './constants';\n\nexport const getFolderGridColumns = (gridName) => ({\n type: types.GET_FOLDER_GRID_COLUMN,\n gridName,\n});\n\nexport const getFolderGridColumnsSuccess = (columns) => {\n return {\n type: types.GET_FOLDER_GRID_COLUMN_SUCCESS,\n columns,\n };\n};\n\nexport const getFolderGridColumnsError = (error) => ({\n type: types.GET_FOLDER_GRID_COLUMN_ERROR,\n error,\n});\n\nexport function getFolderList(\n folderOption,\n pageNumber,\n pageSize,\n search,\n isFavoriteRoute,\n advancedSearchContainer\n) {\n return {\n type: types.GET_FOLDER_GRID,\n folderOption,\n pageIndex: pageNumber,\n pageSize,\n search,\n isFavoriteRoute,\n advancedSearchContainer,\n };\n}\n\nexport const getFolderListByLevel = (params) => {\n return {\n type: types.GET_FOLDER_GRID_BY_LEVEL,\n ...params,\n };\n};\n\nexport const getFolderListByLevelSuccess = ({\n data,\n folderOption,\n ...rest\n}) => {\n return {\n type: types.GET_FOLDER_GRID_BY_LEVEL_SUCCESS,\n data,\n folderOption,\n ...rest,\n };\n};\n\nexport const updateFolderBreadcrumb = (breadcrumb) => {\n return {\n type: types.UPDATE_FOLDER_BREADCRUMB,\n breadcrumb,\n };\n};\n\nexport const keepBreadcrumb = (payload) => {\n return {\n type: types.KEEP_BREADCRUMB,\n payload,\n };\n};\n\nexport const updateShouldKeepBreadcrumb = (payload) => {\n return {\n type: types.UPDATE_SHOULD_KEEP_BREADCRUMB,\n payload,\n };\n};\n\nexport const getFolderListByLevelError = (error) => {\n return {\n type: types.GET_FOLDER_GRID_BY_LEVEL_ERROR,\n error,\n };\n};\n\nexport function getFolderListSuccess(folders, total) {\n return {\n type: types.GET_FOLDER_GRID_SUCCESS,\n folders,\n total,\n };\n}\n\nexport function getFolderListError(error) {\n return {\n type: types.GET_FOLDER_GRID_ERROR,\n error,\n };\n}\n\nexport const turnOnModalCreate = () => {\n return { type: types.TURN_ON_MODAL_CREATE };\n};\n\nexport const turnOffModalCreate = () => {\n return { type: types.TURN_OFF_MODAL_CREATE };\n};\n\nexport const turnOnModalCopy = () => {\n return { type: types.TURN_ON_MODAL_COPY };\n};\n\nexport const turnOffModalCopy = () => {\n return { type: types.TURN_OFF_MODAL_COPY };\n};\n\nexport const deleteFolders = (ids) => {\n return { type: types.DELETE_FOLDERS, payload: ids };\n};\n\nexport const deleteFoldersSuccess = () => {\n return { type: types.DELETE_FOLDERS_SUCCESS };\n};\n\nexport const deleteFoldersFail = (error) => {\n return { type: types.DELETE_FOLDERS_FAIL, error };\n};\n\nexport const copyFolder = (params) => {\n return { type: types.COPY_FOLDER, payload: params };\n};\n\nexport const copyFolderSuccess = () => {\n return { type: types.COPY_FOLDER_SUCCESS };\n};\n\nexport const copyFolderFail = (error) => {\n return { type: types.COPY_FOLDER_FAIL, error };\n};\n\nexport function getFolderShortDetail(id) {\n return {\n type: types.GET_FOLDER_SHORT_DETAIL,\n id,\n };\n}\n\nexport function getFolderShortDetailSuccess(data) {\n return {\n type: types.GET_FOLDER_SHORT_DETAIL_SUCCESS,\n data,\n };\n}\n\nexport function getFolderShortDetailError(error) {\n return {\n type: types.GET_FOLDER_SHORT_DETAIL_ERROR,\n error,\n };\n}\n\nexport function getDigitalAssetPreview(id) {\n return {\n type: types.GET_DIGITAL_ASSET_PREVIEW,\n id,\n };\n}\n\nexport function getDigitalAssetPreviewSuccess(data) {\n return {\n type: types.GET_DIGITAL_ASSET_PREVIEW_SUCCESS,\n data,\n };\n}\n\nexport function getDigitalAssetPreviewError(error) {\n return {\n type: types.GET_DIGITAL_ASSET_PREVIEW_ERROR,\n error,\n };\n}\n\nexport function getMemberPreview(id) {\n return {\n type: types.GET_MEMBER_PREVIEW,\n id,\n };\n}\n\nexport function getMemberPreviewSuccess(data) {\n return {\n type: types.GET_MEMBER_PREVIEW_SUCCESS,\n data,\n };\n}\n\nexport function getMemberPreviewError(error) {\n return {\n type: types.GET_MEMBER_PREVIEW_ERROR,\n error,\n };\n}\n\n// GET DOWNLOAD SETTING\nexport function getDownloadSetting(id) {\n return {\n type: types.GET_DOWNLOAD_SETTING,\n id,\n };\n}\n\nexport function getDownloadSettingSuccess(data) {\n return {\n type: types.GET_DOWNLOAD_SETTING_SUCCESS,\n data,\n };\n}\n\nexport function getDownloadSettingError(error) {\n return {\n type: types.GET_DOWNLOAD_SETTING_ERROR,\n error,\n };\n}\n\n// edit folder short content\nexport const turnEditShortContentOn = (value) => {\n return {\n type: types.TURN_EDIT_SHORT_CONTENT_ON,\n value,\n };\n};\n\nexport const editShortContent = (params) => {\n return {\n type: types.EDIT_FOLDER_SHORT_CONTENT,\n params,\n };\n};\n\nexport const editShortContentSuccess = () => ({\n type: types.EDIT_FOLDER_SHORT_CONTENT_SUCCESS,\n});\n\nexport const editShortContentError = (error) => ({\n type: types.EDIT_FOLDER_SHORT_CONTENT_ERROR,\n error,\n});\n\nexport const setReloadContentPane = (value) => ({\n type: types.SET_RELOAD_FOLDER_CONTENT_PANE,\n value,\n});\n\nexport const editShortContentFinish = () => ({\n type: types.EDIT_FOLDER_SHORT_CONTENT_FINISH,\n});\n\nexport const setReloadFolderPage = () => ({\n type: types.SET_RELOAD_FOLDER_PAGE,\n});\n\nexport const configDownloadSchedule = (params) => {\n return {\n type: types.CONFIG_SCHEDULE_DOWNLOAD,\n params,\n };\n};\n\nexport const configDownloadScheduleSuccess = () => ({\n type: types.CONFIG_SCHEDULE_DOWNLOAD_SUCCESS,\n});\n\nexport const configDownloadScheduleError = (error) => ({\n type: types.CONFIG_SCHEDULE_DOWNLOAD_ERROR,\n error,\n});\n\n// Reset Folders Paging\nexport const resetFolderPaging = () => ({\n type: types.RESET_FOLDER_PAGING,\n});\n// Reset MyFolders Paging\nexport const resetOwnedFolderPaging = () => ({\n type: types.RESET_OWNED_FOLDER_PAGING,\n});\n// Reset FoldersSharedToMe Paging\nexport const resetSharedFolderPaging = () => ({\n type: types.RESET_SHARED_FOLDER_PAGING,\n});\n\n// Get MyFolders\nexport function getOwnedFolderList(\n folderOption,\n pageNumber,\n pageSize,\n search,\n advancedSearchContainer\n) {\n return {\n type: types.GET_OWNED_FOLDER_GRID,\n folderOption,\n pageIndex: pageNumber,\n pageSize,\n search,\n advancedSearchContainer,\n };\n}\nexport function getOwnedFolderListSuccess(folders, total) {\n return {\n type: types.GET_OWNED_FOLDER_GRID_SUCCESS,\n folders,\n total,\n };\n}\nexport function getOwnedFolderListError(error) {\n return {\n type: types.GET_OWNED_FOLDER_GRID_ERROR,\n error,\n };\n}\n\n// Get FoldersSharedToMe\nexport function getSharedFolderList(\n folderOption,\n pageNumber,\n pageSize,\n search,\n advancedSearchContainer\n) {\n return {\n type: types.GET_SHARED_FOLDER_GRID,\n folderOption,\n pageIndex: pageNumber,\n pageSize,\n search,\n advancedSearchContainer,\n };\n}\nexport function getSharedFolderListSuccess(folders, total) {\n return {\n type: types.GET_SHARED_FOLDER_GRID_SUCCESS,\n folders,\n total,\n };\n}\nexport function getSharedFolderListError(error) {\n return {\n type: types.GET_SHARED_FOLDER_GRID_ERROR,\n error,\n };\n}\n\nexport function getPublicContact(memberId) {\n return {\n type: types.GET_PUBLIC_CONTACT_FOLDER,\n memberId,\n };\n}\n\nexport function getPublicContactSuccess(data) {\n return {\n type: types.GET_PUBLIC_CONTACT_FOLDER_SUCCESS,\n data,\n };\n}\n\nexport function getPublicContactError(error) {\n return {\n type: types.GET_PUBLIC_CONTACT_FOLDER_ERROR,\n error,\n };\n}\n\n// Folder details\nexport function getColumnsFolderDetails(gridName) {\n return {\n type: types.GET_COLUMNS_FOLDER_DETAILS,\n gridName,\n };\n}\n\nexport function getColumnsFolderDetailsSuccess(columns) {\n return {\n type: types.GET_COLUMNS_FOLDER_DETAILS_SUCCESS,\n columns,\n };\n}\n\nexport function getColumnsFolderDetailsError(error) {\n return {\n type: types.GET_COLUMNS_FOLDER_DETAILS_ERROR,\n error,\n };\n}\n\nexport function getFolderDetailsGridThumb(params) {\n return {\n type: types.GET_FOLDER_DETAILS_GRID_THUMB,\n params,\n };\n}\n\nexport function getFolderDetailsGridThumbSuccess(data) {\n return {\n type: types.GET_FOLDER_DETAILS_GRID_THUMB_SUCCESS,\n data,\n };\n}\n\nexport function getQueryPreview(id) {\n return {\n type: types.GET_QUERY_PREVIEW,\n id,\n };\n}\n\nexport function getQueryPreviewSuccess(data) {\n return {\n type: types.GET_QUERY_PREVIEW_SUCCESS,\n data,\n };\n}\n\nexport function getFolderDetailsGridThumbError(error) {\n return {\n type: types.GET_COLUMNS_FOLDER_DETAILS_ERROR,\n };\n}\n\nexport function getQueryPreviewError(error) {\n return {\n type: types.GET_QUERY_PREVIEW_ERROR,\n error,\n };\n}\n\nexport function getReportingPreview(id) {\n return {\n type: types.GET_REPORTING_PREVIEW,\n id,\n };\n}\n\nexport function getReportingPreviewSuccess(data) {\n return {\n type: types.GET_REPORTING_PREVIEW_SUCCESS,\n data,\n };\n}\n\nexport function getReportingPreviewError(error) {\n return {\n type: types.GET_REPORTING_PREVIEW_ERROR,\n error,\n };\n}\n\nexport function getProductPreview(id) {\n return {\n type: types.GET_PRODUCT_PREVIEW,\n id,\n };\n}\n\nexport function getProductPreviewSuccess(data) {\n return {\n type: types.GET_PRODUCT_PREVIEW_SUCCESS,\n data,\n };\n}\n\nexport function getProductPreviewError(error) {\n return {\n type: types.GET_PRODUCT_PREVIEW_ERROR,\n error,\n };\n}\n\nexport function saveSelectedMapping(data) {\n return {\n type: types.SAVE_SELECTED_MAPPING,\n data,\n };\n}\n\nexport function saveStatusDownloadFolder(data) {\n return {\n type: types.SAVE_STATUS_DOWNLOAD_FOLDER,\n data,\n };\n}\n\nexport function updateFolderDetailData(data) {\n return {\n type: types.UPDATE_FOLDER_DETAIL_DATA,\n data,\n };\n}\n","// GET FOLDER grid columns\nexport const GET_FOLDER_GRID_COLUMN = 'GET_FOLDER_GRID_COLUMN';\nexport const GET_FOLDER_GRID_COLUMN_SUCCESS = 'GET_FOLDER_GRID_COLUMN_SUCCESS';\nexport const GET_FOLDER_GRID_COLUMN_ERROR = 'GET_FOLDER_GRID_COLUMN_ERROR';\nexport const GET_FOLDER_LIST = 'GET_FOLDER_LIST';\nexport const GET_FOLDER_LIST_SUCCESS = 'GET_FOLDER_LIST_SUCCESS';\nexport const GET_FOLDER_LIST_ERROR = 'GET_FOLDER_LIST_ERROR';\n\nexport const TURN_ON_MODAL_CREATE = 'TURN_ON_MODAL_CREATE';\nexport const TURN_OFF_MODAL_CREATE = 'TURN_OFF_MODAL_CREATE';\n\nexport const TURN_ON_MODAL_COPY = 'TURN_ON_MODAL_COPY';\nexport const TURN_OFF_MODAL_COPY = 'TURN_OFF_MODAL_COPY';\n\nexport const CREATE_FOLDER = 'CREATE_FOLDER';\nexport const CREATE_FOLDER_SUCCESS = 'CREATE_FOLDER_SUCCESS';\nexport const CREATE_FOLDER_FAIL = 'CREATE_FOLDER_FAIL';\n\nexport const DELETE_FOLDERS = 'DELETE_FOLDERS';\nexport const DELETE_FOLDERS_SUCCESS = 'DELETE_FOLDERS_SUCCESS';\nexport const DELETE_FOLDERS_FAIL = 'DELETE_FOLDERS_FAIL';\n\nexport const COPY_FOLDER = 'COPY_FOLDER';\nexport const COPY_FOLDER_SUCCESS = 'COPY_FOLDER_SUCCESS';\nexport const COPY_FOLDER_FAIL = 'COPY_FOLDER_FAIL';\n\nexport const GET_FOLDER_GRID_BY_LEVEL = 'GET_FOLDER_GRID_BY_LEVEL';\nexport const GET_FOLDER_GRID_BY_LEVEL_SUCCESS =\n 'GET_FOLDER_GRID_BY_LEVEL_SUCCESS';\nexport const GET_FOLDER_GRID_BY_LEVEL_ERROR = 'GET_FOLDER_GRID_BY_LEVEL_ERROR';\n\nexport const UPDATE_FOLDER_BREADCRUMB = 'UPDATE_FOLDER_BREADCRUMB';\nexport const KEEP_BREADCRUMB = 'KEEP_BREADCRUMB';\n\nexport const GET_FOLDER_GRID = 'GET_FOLDER_GRID';\nexport const GET_FOLDER_GRID_SUCCESS = 'GET_FOLDER_GRID_SUCCESS';\nexport const GET_FOLDER_GRID_ERROR = 'GET_FOLDER_GRID_ERROR';\n\nexport const GET_FOLDER_SHORT_DETAIL = 'GET_FOLDER_SHORT_DETAIL';\nexport const GET_FOLDER_SHORT_DETAIL_SUCCESS =\n 'GET_FOLDER_SHORT_DETAIL_SUCCESS';\nexport const GET_FOLDER_SHORT_DETAIL_ERROR = 'GET_FOLDER_SHORT_DETAIL_ERROR';\n\nexport const GET_MEMBER_PREVIEW = 'GET_MEMBER_PREVIEW';\nexport const GET_MEMBER_PREVIEW_SUCCESS = 'GET_MEMBER_PREVIEW_SUCCESS';\nexport const GET_MEMBER_PREVIEW_ERROR = 'GET_MEMBER_PREVIEW_ERROR';\nexport const GET_DIGITAL_ASSET_PREVIEW = 'GET_DIGITAL_ASSET_PREVIEW';\nexport const GET_DIGITAL_ASSET_PREVIEW_SUCCESS =\n 'GET_DIGITAL_ASSET_PREVIEW_SUCCESS';\nexport const GET_DIGITAL_ASSET_PREVIEW_ERROR =\n 'GET_DIGITAL_ASSET_SHORT_DETAIL_ERROR';\n\n// GET DOWNLOAD SETTING\nexport const GET_DOWNLOAD_SETTING = 'GET_DOWNLOAD_SETTING';\nexport const GET_DOWNLOAD_SETTING_SUCCESS = 'GET_DOWNLOAD_SETTING_SUCCESS';\nexport const GET_DOWNLOAD_SETTING_ERROR = 'GET_DOWNLOAD_SETTING_ERROR';\n\n// EDIT FOLDER SHORT CONTENT\nexport const EDIT_FOLDER_SHORT_CONTENT = 'EDIT_FOLDER_SHORT_CONTENT';\nexport const TURN_EDIT_SHORT_CONTENT_ON = 'TURN_EDIT_SHORT_CONTENT_ON';\nexport const EDIT_FOLDER_SHORT_CONTENT_SUCCESS =\n 'EDIT_FOLDER_SHORT_CONTENT_SUCCESS';\nexport const EDIT_FOLDER_SHORT_CONTENT_ERROR =\n 'EDIT_FOLDER_SHORT_CONTENT_ERROR';\nexport const SET_RELOAD_FOLDER_CONTENT_PANE = 'SET_RELOAD_FOLDER_CONTENT_PANE';\nexport const EDIT_FOLDER_SHORT_CONTENT_FINISH =\n 'EDIT_FOLDER_SHORT_CONTENT_FINISH';\nexport const SET_RELOAD_FOLDER_PAGE = 'SET_RELOAD_FOLDER_PAGE';\n\nexport const CONFIG_SCHEDULE_DOWNLOAD = 'CONFIG_SCHEDULE_DOWNLOAD';\nexport const CONFIG_SCHEDULE_DOWNLOAD_SUCCESS =\n 'CONFIG_SCHEDULE_DOWNLOAD_SUCCESS';\nexport const CONFIG_SCHEDULE_DOWNLOAD_ERROR = 'CONFIG_SCHEDULE_DOWNLOAD_ERROR';\n\n// Leave page\nexport const RESET_FOLDER_PAGING = 'RESET_FOLDER_PAGING';\nexport const RESET_OWNED_FOLDER_PAGING = 'RESET_OWNED_FOLDER_PAGING';\nexport const RESET_SHARED_FOLDER_PAGING = 'RESET_SHARED_FOLDER_PAGING';\n// MyFolders grid\nexport const GET_OWNED_FOLDER_GRID = 'GET_OWNED_FOLDER_GRID';\nexport const GET_OWNED_FOLDER_GRID_SUCCESS = 'GET_OWNED_FOLDER_GRID_SUCCESS';\nexport const GET_OWNED_FOLDER_GRID_ERROR = 'GET_OWNED_FOLDER_GRID_ERROR';\n// FoldersSharedToMe grid\nexport const GET_SHARED_FOLDER_GRID = 'GET_SHARED_FOLDER_GRID';\nexport const GET_SHARED_FOLDER_GRID_SUCCESS = 'GET_SHARED_FOLDER_GRID_SUCCESS';\nexport const GET_SHARED_FOLDER_GRID_ERROR = 'GET_SHARED_FOLDER_GRID_ERROR';\nexport const GET_PUBLIC_CONTACT_FOLDER = 'GET_PUBLIC_CONTACT_FOLDER';\nexport const GET_PUBLIC_CONTACT_FOLDER_SUCCESS =\n 'GET_PUBLIC_CONTACT_FOLDER_SUCCESS';\nexport const GET_PUBLIC_CONTACT_FOLDER_ERROR =\n 'GET_PUBLIC_CONTACT_FOLDER_ERROR';\n\n// Folder details\nexport const GET_COLUMNS_FOLDER_DETAILS = 'GET_COLUMNS_FOLDER_DETAILS';\nexport const GET_COLUMNS_FOLDER_DETAILS_SUCCESS =\n 'GET_COLUMNS_FOLDER_DETAILS_SUCCESS';\nexport const GET_COLUMNS_FOLDER_DETAILS_ERROR =\n 'GET_COLUMNS_FOLDER_DETAILS_ERROR';\n\nexport const GET_FOLDER_DETAILS_GRID_THUMB = 'GET_FOLDER_DETAILS_GRID_THUMB';\nexport const GET_FOLDER_DETAILS_GRID_THUMB_SUCCESS =\n 'GET_FOLDER_DETAILS_GRID_THUMB_SUCCESS';\nexport const GET_FOLDER_DETAILS_GRID_THUMB_ERROR =\n 'GET_FOLDER_DETAILS_GRID_THUMB_ERROR';\nexport const GET_QUERY_PREVIEW = 'GET_QUERY_PREVIEW';\nexport const GET_QUERY_PREVIEW_SUCCESS = 'GET_QUERY_PREVIEW_SUCCESS';\nexport const GET_QUERY_PREVIEW_ERROR = 'GET_QUERY_PREVIEW_ERROR';\nexport const GET_REPORTING_PREVIEW = 'GET_REPORTING_PREVIEW';\nexport const GET_REPORTING_PREVIEW_SUCCESS = 'GET_REPORTING_PREVIEW_SUCCESS';\nexport const GET_REPORTING_PREVIEW_ERROR = 'GET_REPORTING_PREVIEW_ERROR';\n\nexport const GET_PRODUCT_PREVIEW = 'GET_PRODUCT_PREVIEW';\nexport const GET_PRODUCT_PREVIEW_SUCCESS = 'GET_PRODUCT_PREVIEW_SUCCESS';\nexport const GET_PRODUCT_PREVIEW_ERROR = 'GET_PRODUCT_PREVIEW_ERROR';\n\nexport const SAVE_SELECTED_MAPPING = 'SAVE_SELECTED_MAPPING';\nexport const SAVE_STATUS_DOWNLOAD_FOLDER = 'SAVE_STATUS_DOWNLOAD_FOLDER';\n\nexport const UPDATE_FOLDER_DETAIL_DATA = 'UPDATE_FOLDER_DETAIL_DATA';\n\nexport const UPDATE_SHOULD_KEEP_BREADCRUMB = 'UPDATE_SHOULD_KEEP_BREADCRUMB';\n\nexport const ROOT_FOLDER = 'home';\n","/* eslint-disable default-case */\nimport produce from 'immer';\nimport * as types from './constants';\n\n// initial state\nexport const initialState = {\n loading: false,\n error: false,\n folderOption: null,\n folders: [],\n total: 0,\n pageSize: 20,\n pageNumber: 1,\n search: '',\n ownedFolderPageSize: 20,\n ownedFolderPageNumber: 1,\n ownFolderSearch: '',\n sharedFolderPageSize: 20,\n sharedFolderPageNumber: 1,\n sharedFolderSearch: '',\n columns: [],\n gridName: '',\n deleteFolders: {\n statusDelete: 'idle',\n errorDelete: null,\n },\n\n copyFolder: {\n statusCopy: 'idle',\n errorCopy: null,\n visibleModal: false,\n },\n\n folderShortDetail: null,\n loadingDetail: false,\n reloadContentPane: false,\n memberPreview: null,\n memberLoading: false,\n assetLoading: false,\n assetPreview: null,\n downloadSetting: null,\n isEdit: false,\n startEdit: 'idle',\n editSuccess: 'idle',\n editError: null,\n configLoading: false,\n configError: null,\n publicContactList: null,\n\n folderDetails: {\n columnsGrid: [],\n pageSize: 20,\n pageNumber: 1,\n total: 0,\n loading: false,\n data: [],\n },\n queryLoading: false,\n queryPreview: false,\n reportingLoading: false,\n reportingPreview: false,\n\n productLoading: false,\n productPreview: false,\n\n selectedMapping: null,\n statusDownloadFolder: 'idle',\n\n folderDetailData: null,\n\n //\n folderByLevel: {\n loading: false,\n error: null,\n folders: [],\n myFolders: [],\n sharedFolders: [],\n folderBreadcrumb: [\n {\n id: types.ROOT_FOLDER,\n folderName: 'Home',\n },\n ],\n keepBreadcrumb: false,\n shouldKeepFolderBreadcrumb: false,\n }, // maybe cache in here\n};\n\nconst folderReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.GET_FOLDER_GRID_COLUMN:\n draft.loading = true;\n draft.columns = [];\n break;\n case types.GET_FOLDER_GRID_COLUMN_SUCCESS:\n draft.loading = false;\n draft.columns = action.columns;\n break;\n case types.GET_FOLDER_GRID_COLUMN_ERROR:\n draft.loading = false;\n draft.columns = [];\n draft.error = action.error;\n break;\n case types.GET_FOLDER_GRID:\n draft.loading = true;\n draft.error = false;\n draft.folderOption = action.folderOption;\n draft.pageSize = action.pageSize;\n draft.pageNumber = action.pageIndex;\n draft.search = action['Search.SearchText'];\n\n draft['deleteFolders'] = {\n statusDelete: 'idle',\n errorDelete: null,\n };\n draft['copyFolder'] = {\n name: '',\n statusCopy: 'idle',\n errorCopy: null,\n visibleModal: false,\n };\n break;\n case types.GET_FOLDER_GRID_SUCCESS:\n draft.loading = false;\n draft.folders = action.folders;\n draft.total = action.total;\n break;\n case types.GET_FOLDER_GRID_ERROR:\n draft.loading = false;\n draft.total = 0;\n draft.folders = [];\n draft.error = action.error;\n break;\n\n case types.DELETE_FOLDERS:\n draft.loading = true;\n // draft['deleteFolders'].statusDelete = 'loading';\n break;\n case types.DELETE_FOLDERS_SUCCESS:\n draft['deleteFolders'].statusDelete = 'success';\n draft.folderShortDetail = null;\n break;\n case types.DELETE_FOLDERS_FAIL:\n draft['deleteFolders'].statusDelete = 'fail';\n draft['deleteFolders'].errorDelete = action.error;\n draft.loading = false;\n break;\n\n case types.TURN_ON_MODAL_COPY:\n draft['copyFolder'].statusCopy = 'idle';\n draft['copyFolder'].visibleModal = true;\n break;\n case types.TURN_OFF_MODAL_COPY:\n draft['copyFolder'].statusCopy = 'idle';\n draft['copyFolder'].visibleModal = false;\n break;\n\n case types.COPY_FOLDER:\n draft['copyFolder'].statusCopy = 'loading';\n break;\n case types.COPY_FOLDER_SUCCESS:\n draft['copyFolder'].statusCopy = 'success';\n break;\n case types.COPY_FOLDER_FAIL:\n draft['copyFolder'].statusCopy = 'fail';\n draft['copyFolder'].errorCopy = action.error;\n break;\n\n case types.GET_FOLDER_SHORT_DETAIL:\n draft.loadingDetail = true;\n draft.error = false;\n break;\n case types.GET_FOLDER_SHORT_DETAIL_SUCCESS:\n draft.loadingDetail = false;\n draft.folderShortDetail = action.data;\n break;\n case types.GET_FOLDER_SHORT_DETAIL_ERROR:\n draft.loadingDetail = false;\n draft.error = action.error;\n break;\n case types.GET_MEMBER_PREVIEW:\n draft.memberLoading = true;\n draft.error = false;\n break;\n case types.GET_MEMBER_PREVIEW_SUCCESS:\n draft.memberLoading = false;\n draft.memberPreview = action.data;\n break;\n case types.GET_MEMBER_PREVIEW_ERROR:\n draft.memberLoading = false;\n draft.error = action.error;\n break;\n case types.GET_DIGITAL_ASSET_PREVIEW:\n draft.assetLoading = true;\n draft.error = false;\n break;\n case types.GET_DIGITAL_ASSET_PREVIEW_SUCCESS:\n draft.assetLoading = false;\n draft.assetPreview = action.data;\n break;\n case types.GET_DIGITAL_ASSET_PREVIEW_ERROR:\n draft.assetLoading = false;\n draft.error = action.error;\n break;\n // Download Setting\n case types.GET_DOWNLOAD_SETTING:\n draft.loadingDownloadSetting = true;\n draft.error = false;\n draft.downloadSetting = null;\n break;\n case types.GET_DOWNLOAD_SETTING_SUCCESS:\n draft.loadingDownloadSetting = false;\n draft.error = false;\n draft.downloadSetting = action.data;\n break;\n case types.GET_DOWNLOAD_SETTING_ERROR:\n draft.loadingDownloadSetting = false;\n draft.error = action.error;\n draft.downloadSetting = null;\n break;\n case types.TURN_EDIT_SHORT_CONTENT_ON:\n draft.isEdit = action.value;\n break;\n case types.EDIT_FOLDER_SHORT_CONTENT:\n draft.startEdit = 'starting';\n draft.editSuccess = 'idle';\n draft.editError = null;\n break;\n case types.EDIT_FOLDER_SHORT_CONTENT_SUCCESS:\n draft.startEdit = 'finish';\n draft.editSuccess = 'success';\n draft.reloadContentPane = true;\n break;\n case types.EDIT_FOLDER_SHORT_CONTENT_ERROR:\n draft.startEdit = 'finish';\n draft.editSuccess = 'error';\n draft.editError = action.error;\n break;\n case types.SET_RELOAD_FOLDER_CONTENT_PANE:\n draft.reloadContentPane = action.value;\n break;\n case types.EDIT_FOLDER_SHORT_CONTENT_FINISH:\n draft.startEdit = 'idle';\n draft.editSuccess = 'idle';\n draft.editError = null;\n break;\n case types.CONFIG_SCHEDULE_DOWNLOAD:\n draft.configLoading = true;\n break;\n case types.CONFIG_SCHEDULE_DOWNLOAD_SUCCESS:\n draft.configLoading = false;\n break;\n case types.CONFIG_SCHEDULE_DOWNLOAD_ERROR:\n draft.configLoading = false;\n draft.editError = action.error;\n break;\n case types.RESET_FOLDER_PAGING:\n draft.pageSize = 20;\n draft.pageNumber = 1;\n draft.search = '';\n break;\n case types.RESET_OWNED_FOLDER_PAGING:\n draft.ownedFolderPageSize = 20;\n draft.ownedFolderPageNumber = 1;\n draft.ownedFolderSearch = '';\n break;\n case types.RESET_SHARED_FOLDER_PAGING:\n draft.sharedFolderPageSize = 20;\n draft.sharedFolderPageNumber = 1;\n draft.sharedFolderSearch = '';\n break;\n case types.GET_OWNED_FOLDER_GRID:\n draft.loading = true;\n draft.error = false;\n draft.folderOption = action.folderOption;\n draft.ownedFolderPageSize = action.pageSize;\n draft.ownedFolderPageNumber = action.pageIndex;\n draft.ownedFolderSearch = action.search;\n\n draft['deleteFolders'] = {\n statusDelete: 'idle',\n errorDelete: null,\n };\n draft['copyFolder'] = {\n name: '',\n statusCopy: 'idle',\n errorCopy: null,\n visibleModal: false,\n };\n break;\n case types.GET_OWNED_FOLDER_GRID_SUCCESS:\n draft.loading = false;\n draft.folders = action.folders;\n draft.total = action.total;\n break;\n case types.GET_OWNED_FOLDER_GRID_ERROR:\n draft.loading = false;\n draft.total = 0;\n draft.folders = [];\n draft.error = action.error;\n break;\n case types.GET_SHARED_FOLDER_GRID:\n draft.loading = true;\n draft.error = false;\n draft.folderOption = action.folderOption;\n draft.sharedFolderPageSize = action.pageSize;\n draft.sharedFolderPageNumber = action.pageIndex;\n draft.sharedFolderSearch = action.search;\n\n // reset object\n draft['deleteFolders'] = {\n statusDelete: 'idle',\n errorDelete: null,\n };\n draft['copyFolder'] = {\n name: '',\n statusCopy: 'idle',\n errorCopy: null,\n visibleModal: false,\n };\n break;\n case types.GET_SHARED_FOLDER_GRID_SUCCESS:\n draft.loading = false;\n draft.folders = action.folders;\n draft.total = action.total;\n break;\n case types.GET_SHARED_FOLDER_GRID_ERROR:\n draft.loading = false;\n draft.total = 0;\n draft.folders = [];\n draft.error = action.error;\n break;\n case types.GET_PUBLIC_CONTACT_FOLDER:\n draft.loadingDetail = true;\n draft.error = null;\n break;\n case types.GET_PUBLIC_CONTACT_FOLDER_SUCCESS:\n draft.loadingDetail = false;\n draft.publicContactList = action.data;\n draft.error = null;\n break;\n case types.GET_PUBLIC_CONTACT_FOLDER_ERROR:\n draft.loadingDetail = false;\n draft.publicContactList = null;\n draft.error = action.error;\n break;\n\n case types.GET_COLUMNS_FOLDER_DETAILS_SUCCESS:\n draft['folderDetails'].columnsGrid = action.columns;\n break;\n\n case types.GET_FOLDER_DETAILS_GRID_THUMB:\n draft['folderDetails'].loading = true;\n break;\n\n case types.GET_FOLDER_DETAILS_GRID_THUMB_SUCCESS:\n draft['folderDetails'].loading = false;\n draft['folderDetails'].data = action.data.gridData;\n draft['folderDetails'].pageNumber = action.data.paging.currentPageIndex;\n draft['folderDetails'].pageSize = action.data.paging.currentPageSize;\n draft['folderDetails'].total = action.data.paging.totalRecord;\n break;\n\n case types.GET_QUERY_PREVIEW:\n draft.queryLoading = true;\n draft.error = false;\n break;\n case types.GET_QUERY_PREVIEW_SUCCESS:\n draft.queryLoading = false;\n draft.queryPreview = action.data;\n break;\n case types.GET_QUERY_PREVIEW_ERROR:\n draft.queryLoading = false;\n draft.error = action.error;\n break;\n case types.GET_REPORTING_PREVIEW:\n draft.reportingLoading = true;\n draft.error = false;\n break;\n case types.GET_REPORTING_PREVIEW_SUCCESS:\n draft.reportingLoading = false;\n draft.reportingPreview = action.data;\n break;\n case types.GET_REPORTING_PREVIEW_ERROR:\n draft.reportingLoading = false;\n draft.error = action.error;\n break;\n\n case types.GET_PRODUCT_PREVIEW:\n draft.productLoading = true;\n draft.error = false;\n break;\n case types.GET_PRODUCT_PREVIEW_SUCCESS:\n draft.productLoading = false;\n draft.productPreview = action.data;\n break;\n case types.GET_PRODUCT_PREVIEW_ERROR:\n draft.productLoading = false;\n draft.error = action.error;\n break;\n\n case types.SAVE_SELECTED_MAPPING:\n draft.selectedMapping = action.data;\n break;\n\n case types.SAVE_STATUS_DOWNLOAD_FOLDER:\n draft.statusDownloadFolder = action.data;\n break;\n\n case types.UPDATE_FOLDER_DETAIL_DATA:\n draft.folderDetailData = action.data;\n break;\n\n //\n case types.GET_FOLDER_GRID_BY_LEVEL:\n draft.folderByLevel.loading = true;\n draft.folderByLevel.error = null;\n // draft.folderByLevel.folderBreadcrumb = [\n // {\n // id: 'home',\n // folderName: 'Home',\n // },\n // ];\n break;\n\n case types.GET_FOLDER_GRID_BY_LEVEL_SUCCESS:\n const { folderOption, data, loading } = action;\n\n draft.folderByLevel.loading = loading ?? false;\n draft.folderByLevel.error = null;\n\n if (folderOption?.toLowerCase() === 'folders') {\n draft.folderByLevel.folders = data;\n } else if (folderOption?.toLowerCase() === 'myfolders') {\n draft.folderByLevel.myFolders = data;\n } else if (folderOption?.toLowerCase() === 'folderssharedtome') {\n draft.folderByLevel.sharedFolders = data;\n }\n break;\n\n case types.UPDATE_FOLDER_BREADCRUMB:\n const { breadcrumb } = action;\n draft.folderByLevel.folderBreadcrumb = breadcrumb;\n break;\n\n case types.KEEP_BREADCRUMB:\n draft.folderByLevel.keepBreadcrumb = action.payload;\n break;\n\n case types.UPDATE_SHOULD_KEEP_BREADCRUMB:\n draft.folderByLevel.shouldKeepFolderBreadcrumb = action.payload;\n break;\n\n default:\n break;\n }\n });\n\nexport default folderReducer;\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\nconst selectFolderList = (state) => state.folderList || initialState;\nconst makeSelectLoading = () =>\n createSelector(selectFolderList, (folderState) => folderState.loading);\nconst makeSelectFolderList = () =>\n createSelector(selectFolderList, (folderState) => folderState.folders);\nconst makeSelectTotal = () =>\n createSelector(selectFolderList, (folderState) => folderState.total);\nconst makeSelectPageSize = () =>\n createSelector(selectFolderList, (folderState) => folderState.pageSize);\nconst makeSelectPageNumber = () =>\n createSelector(selectFolderList, (folderState) => folderState.pageNumber);\nconst makeSelectSearch = () =>\n createSelector(selectFolderList, (folderState) => folderState.search);\nconst makeSelectOwnedFolderPageSize = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.ownedFolderPageSize\n );\nconst makeSelectOwnedFolderPageNumber = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.ownedFolderPageNumber\n );\nconst makeSelectOwnedFolderSearch = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.ownedFolderSearch\n );\nconst makeSelectSharedFolderPageSize = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.sharedFolderPageSize\n );\nconst makeSelectSharedFolderPageNumber = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.sharedFolderPageNumber\n );\nconst makeSelectSharedFolderSearch = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.sharedFolderSearch\n );\nconst selectColumns = () =>\n createSelector(selectFolderList, (folderState) => folderState.columns);\nconst selectError = () =>\n createSelector(selectFolderList, (folderState) => folderState.error);\n\nconst selectDeleteFolders = () =>\n createSelector(selectFolderList, (folderState) => folderState.deleteFolders);\n\nconst selectCopyFolder = () =>\n createSelector(selectFolderList, (folderState) => folderState.copyFolder);\n\nconst selectPublicContact = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.publicContactList\n );\n\nconst selectFolderShortDetail = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.folderShortDetail\n );\n\nconst selectReloadContentPane = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.reloadContentPane\n );\nconst selectLoadingDetail = () =>\n createSelector(selectFolderList, (folderState) => folderState.loadingDetail);\n\nconst selectMemberLoading = () =>\n createSelector(selectFolderList, (folderState) => folderState.memberLoading);\nconst selectMemberPreview = () =>\n createSelector(selectFolderList, (folderState) => folderState.memberPreview);\nconst selectAssetLoading = () =>\n createSelector(selectFolderList, (folderState) => folderState.assetLoading);\nconst selectAssetPreview = () =>\n createSelector(selectFolderList, (folderState) => folderState.assetPreview);\n\nconst selectDownloadSetting = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.downloadSetting\n );\n\nconst selectIsEdit = () =>\n createSelector(selectFolderList, (folderState) => folderState.isEdit);\nconst selectStartEdit = () =>\n createSelector(selectFolderList, (folderState) => folderState.startEdit);\nconst selectEditSuccess = () =>\n createSelector(selectFolderList, (folderState) => folderState.editSuccess);\nconst selectEditError = () =>\n createSelector(selectFolderList, (folderState) => folderState.editError);\nconst selectConfigLoading = () =>\n createSelector(selectFolderList, (folderState) => folderState.configLoading);\nconst selectConfigError = () =>\n createSelector(selectFolderList, (folderState) => folderState.configError);\n\nconst selectFolderDetails = () =>\n createSelector(selectFolderList, (folderState) => folderState.folderDetails);\nconst selectQueryLoading = () =>\n createSelector(selectFolderList, (folderState) => folderState.queryLoading);\nconst selectQueryPreview = () =>\n createSelector(selectFolderList, (folderState) => folderState.queryPreview);\nconst selectReportingLoading = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.reportingLoading\n );\nconst selectReportingPreview = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.reportingPreview\n );\n\nconst selectProductPreview = () =>\n createSelector(selectFolderList, (folderState) => folderState.productPreview);\nconst selectProductLoading = () =>\n createSelector(selectFolderList, (folderState) => folderState.productLoading);\n\nconst selectSelectedMapping = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.selectedMapping\n );\n\nconst selectStatusDownloadFolder = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.statusDownloadFolder\n );\n\nconst selectFolderDetailData = () =>\n createSelector(\n selectFolderList,\n (folderState) => folderState.folderDetailData\n );\n\n//\nconst selectFolderListByLevel = () =>\n createSelector(selectFolderList, (folderState) => folderState.folderByLevel);\n\nexport {\n selectFolderList,\n makeSelectLoading,\n makeSelectFolderList,\n makeSelectTotal,\n makeSelectPageSize,\n makeSelectPageNumber,\n makeSelectSearch,\n makeSelectOwnedFolderPageSize,\n makeSelectOwnedFolderPageNumber,\n makeSelectOwnedFolderSearch,\n makeSelectSharedFolderPageSize,\n makeSelectSharedFolderPageNumber,\n makeSelectSharedFolderSearch,\n selectColumns,\n selectError,\n selectDeleteFolders,\n selectFolderShortDetail,\n selectReloadContentPane,\n selectLoadingDetail,\n selectCopyFolder,\n selectMemberLoading,\n selectMemberPreview,\n selectAssetLoading,\n selectAssetPreview,\n selectIsEdit,\n selectStartEdit,\n selectEditSuccess,\n selectEditError,\n selectDownloadSetting,\n selectConfigLoading,\n selectConfigError,\n selectPublicContact,\n selectFolderDetails,\n selectQueryLoading,\n selectQueryPreview,\n selectReportingLoading,\n selectReportingPreview,\n selectProductPreview,\n selectProductLoading,\n selectSelectedMapping,\n selectStatusDownloadFolder,\n selectFolderDetailData,\n selectFolderListByLevel,\n};\n","import { useDispatch, useSelector } from 'react-redux';\n\nimport * as folderSelectors from 'pages/folders/controllers/selectors';\nimport * as folderActions from 'pages/folders/controllers/actions';\n\nexport const useDownloadFolderSetting = (props) => {\n const dispatch = useDispatch();\n\n const downloadSetting = useSelector(folderSelectors.selectDownloadSetting());\n\n const getDownloadSetting = (id) => {\n dispatch(folderActions.getDownloadSetting(id));\n };\n\n return {\n downloadSetting,\n getDownloadSetting,\n };\n};\n","import React from 'react';\nimport { useIntl } from 'react-intl';\nimport { useDispatch } from 'react-redux';\n\nimport { Tooltip } from 'antd';\n\nimport _ from 'lodash';\n\nimport { Space, notification } from 'antd';\nimport SharedIcon from 'common/components/thumb/share/SharedIcon';\nimport DigitalRightIcon from 'common/components/digital-right-icon/DigitalRightIcon';\n\nimport { Images } from 'config/assets';\n\nimport { IconFolderAsset } from 'common/components/folder';\nimport customCellComponents from 'pages/folders/components/custom-cell-components';\n\nimport { getFolderShortDetail } from 'services/folder';\nimport * as actionsGlobal from '@redux/global/actions';\n\nimport { formatSizeUnits } from 'utils/formatSizeUnits';\nimport { formatSizeUnitByParam } from 'utils/formatSizeUnits';\nimport { entityTypeIcon } from 'utils/entityTypeIcon';\nimport { formatMDY } from 'utils/formatDate';\nimport { formatMDYWithParam } from 'utils/formatDate';\n\nimport { getNodeTreeData } from 'common/components/folder/utils';\n\nimport emptyFolderIcon from 'assets/folder/empty-folder.png';\nimport folderIcon from 'assets/folder/folder.png';\nimport { CustomNotification } from 'common/components';\nimport { sleep } from 'utils/delay';\nimport { forwardTo } from 'utils/common/route';\nimport { useGridView } from 'hooks/useGridView';\nimport { useDownloadFolderSetting } from 'hooks/useDownloadFolderSetting';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\n\nimport folderMessages from 'i18n/messages/folder';\n\n// Hooks\n\nconst useFetchFolder = (id) => {\n const [state, setState] = React.useReducer((_, action) => action, {\n isLoading: true,\n isReloading: false,\n });\n\n const { getDownloadSetting } = useDownloadFolderSetting();\n\n const fetchFolder = () => {\n if (!id) return;\n setState({ ...state, isReloading: true });\n getFolderShortDetail({ id, IsLoadContent: true })\n .then((res) => {\n if (res.isSuccess) {\n setState({\n isLoading: false,\n isReloading: false,\n isSuccess: true,\n data: res.data,\n });\n } else {\n notification.error({ message: res?.message || 'Folder not found' });\n forwardTo('/folders');\n }\n })\n .catch((error) => {\n notification.error({\n message: error?.message || 'Folder not found',\n });\n forwardTo('/folders');\n });\n };\n\n const reFetchingFolderShortDetail = () => {\n fetchFolder();\n };\n\n const handleLoading = () => {\n setState({ ...state, isReloading: true });\n };\n\n const updateFolderData = (data) => {\n setState({\n isLoading: false,\n isReloading: false,\n isSuccess: true,\n data: data,\n });\n };\n\n React.useEffect(() => {\n fetchFolder();\n }, [+id]);\n\n return {\n ...state,\n reFetchingFolderShortDetail,\n updateFolderData,\n handleLoading,\n setState,\n state,\n };\n};\n\n// const option = RIBBON_OPTIONS.BLANK;\nconst NAME_GRID = 'folder-detail-grid';\n\nconst useInitialComponent = () => {\n const dispatch = useDispatch();\n\n React.useEffect(() => {\n // dispatch(actionsGlobal.changeRibbonActions(option));\n // dispatch(folderActions.getColumnsFolderDetails(NAME_GRID));\n dispatch(actionsGlobal.updateIsOnlyDetailGird(true));\n dispatch(actionsGlobal.hideSearchBar());\n return () => {\n dispatch(actionsGlobal.updateIsOnlyDetailGird(false));\n };\n }, [dispatch]);\n};\n\n//\nconst folderInfoFields = [\n { label: 'Owner', value: 'ownerName' },\n { label: '# Items', value: 'items' },\n { label: 'Date Created', value: 'dateCreated', type: 'Date' },\n { label: 'Last Updated', value: 'lastUpdated', type: 'Date' },\n { type: 'icon' },\n];\n\nconst renderValueFolderInfo = (field, folder) => {\n if (!folder) return null;\n\n if (field.type === 'Date') {\n return formatMDY(folder[`${field.value}`]);\n }\n\n if (field.value === 'estSize') {\n return formatSizeUnits(folder[field.value]);\n }\n\n if (field.type === 'icon') return renderFolderIcon(folder);\n\n return folder[`${field.value}`];\n};\n\nconst renderFolderIcon = (folder) => {\n return (\n \n {!folder?.isOwner ? : null}\n {folder?.drm ? : null}\n \n );\n};\n\nconst getImageFolder = (folder) => {\n if (!folder) return;\n const { items, isOwner } = folder;\n\n // if (!isOwner) {\n // return Images.sharedFolder;\n // }\n\n if (items > 0) {\n return Images.folder;\n }\n\n return Images.emptyFolder;\n};\n\nconst checkOwnerFolder = (folder) => {\n return folder?.isOwner;\n};\n\nconst renderPathname = (type) => {\n switch (type?.toLowerCase()) {\n case 'asset':\n case 'document':\n return 'asset';\n\n case 'member':\n return 'company';\n\n case 'reporting':\n return 'reporting';\n\n case 'product':\n return 'product';\n\n case 'folder':\n return 'folder';\n case 'query':\n return 'execute-query';\n\n default:\n return '';\n }\n};\n\nconst updateNode = (treeData, node, folderId) => {\n return treeData?.map((nodeItem) => {\n if (nodeItem.data.id === folderId) {\n const imageFolder =\n node.data.subFolderCount > 0 ? folderIcon : emptyFolderIcon;\n return {\n ...node,\n data: { ...node.data },\n key: nodeItem.key,\n isLeaf: node.data.subFolderCount === 0 ? true : false,\n children: nodeItem.children,\n icon: ,\n };\n } else if (nodeItem?.children && nodeItem?.children.length > 0) {\n return {\n ...nodeItem,\n children: updateNode(nodeItem.children, node, folderId),\n };\n }\n return nodeItem;\n });\n};\n\nconst addNodeToTree = (tree, node, idParent, subFolderCount) => {\n return tree.map((parentNode) => {\n if (parentNode.data.id === idParent) {\n const childOfNodeParent = parentNode?.children ?? [];\n return {\n ...parentNode,\n data: { ...parentNode.data, subFolderCount },\n children: childOfNodeParent.concat(node),\n isLeaf: false,\n icon: ,\n };\n } else if (parentNode?.children && parentNode?.children.length > 0) {\n return {\n ...parentNode,\n children: addNodeToTree(\n parentNode.children,\n node,\n idParent,\n subFolderCount\n ),\n };\n }\n return parentNode;\n });\n};\n\nconst deleteSubNodesToTree = (tree, ids) => {\n return tree\n .map((item) => {\n if (ids.includes(item.data.id)) {\n return null;\n } else if (item?.children && item?.children.length > 0) {\n return {\n ...item,\n children: deleteSubNodesToTree(item?.children, ids),\n };\n }\n return item;\n })\n .filter((item) => item)\n .map((item) => {\n if (item?.children && item?.children.length === 0) {\n delete item.children;\n return {\n ...item,\n icon: ,\n isLeaf: true,\n };\n }\n return item;\n });\n};\n\nexport const getParentFolder = (id, tree) => {\n let parentNode;\n for (let i = 0; i < tree?.length; i++) {\n const node = tree[i];\n if (node?.children) {\n if (node?.children?.some((item) => item.id === id)) {\n parentNode = node;\n } else if (getParentFolder(id, node.children)) {\n parentNode = getParentFolder(id, node.children);\n }\n }\n }\n return parentNode;\n};\n\nconst defaultFolderParam = {\n renderFolder: (node) => {\n const isEmptyContents = node && node.subFolderCount === 0;\n\n if (isEmptyContents) {\n return {\n icon: ,\n isLeaf: true,\n };\n }\n\n return {};\n },\n};\n\nconst useReloadFolderActionWhenSuccess = ({\n treeData,\n currentFolder,\n handleUpdateTreeData,\n handleSelectNodeById,\n handleSetStatusTree,\n viewFolderContents,\n handleGetDataList,\n}) => {\n const reloadPage = useDispatchReloadPage();\n const { clearGridSelection } = useGridView();\n const intl = useIntl();\n\n const reloadFolderWhenCreateSuccess = async (idFolder) => {\n try {\n handleSetStatusTree('loading');\n const data = await getFolderShortDetail({\n id: idFolder,\n IsLoadContent: false,\n });\n const dataParent = await getFolderShortDetail({\n id: currentFolder.id,\n IsLoadContent: false,\n });\n\n const subFolderCountParent = dataParent.data.subFolderCount;\n\n const node = getNodeTreeData({\n node: { ...data.data, type: 'folder' },\n folderParam: defaultFolderParam,\n });\n\n const newTree = addNodeToTree(\n treeData,\n node,\n currentFolder.id,\n subFolderCountParent\n );\n\n handleUpdateTreeData(newTree);\n\n await sleep(100);\n handleSelectNodeById(idFolder.toString());\n handleSetStatusTree('success');\n\n CustomNotification.success(\n intl.formatMessage(folderMessages.createFolderSuccessMessage)\n );\n } catch (error) {\n CustomNotification.success(\n intl.formatMessage(folderMessages.createFolderFailedMessage)\n );\n handleSetStatusTree('success');\n }\n };\n\n const reloadFolderWhenEditSuccess = async (idFolder, updateFolderData) => {\n handleSetStatusTree('loading');\n await sleep(500);\n const folderDetail = await getFolderShortDetail({\n id: idFolder,\n IsLoadContent: false,\n });\n const newNode = getNodeTreeData({\n node: { ...folderDetail.data, type: 'folder' },\n folderParam: false,\n fileParam: false,\n });\n\n const newTree = updateNode(treeData, newNode, idFolder);\n handleSelectNodeById(currentFolder?.id);\n handleUpdateTreeData(newTree);\n\n updateFolderData(folderDetail.data);\n\n handleSetStatusTree('success');\n\n viewFolderContents === 'grid' ? reloadPage() : handleGetDataList(20, 1, '');\n };\n\n const reloadFolderWhenDeleteSuccess = async (\n idFolders,\n reFetchingFolderShortDetail,\n idSelected,\n level\n ) => {\n let successMessage = folderMessages.deleteItemsSuccessMessage;\n\n handleSetStatusTree('loading');\n await sleep(500);\n if (\n idFolders.length === 1 &&\n idFolders?.[0].toString() === idSelected.toString() &&\n level === 1\n ) {\n CustomNotification.success(intl.formatMessage(successMessage));\n handleSetStatusTree('success');\n forwardTo('/folders/owned');\n return;\n }\n\n if (idFolders.length === 1 && idFolders?.[0] === currentFolder.id) {\n const hierarchyList = currentFolder.hierarchy?.split('/');\n\n const newTree = deleteSubNodesToTree(treeData, idFolders);\n handleUpdateTreeData(newTree);\n\n const prevFolderId = hierarchyList[hierarchyList.length - 2];\n handleSelectNodeById(prevFolderId);\n\n CustomNotification.success(intl.formatMessage(successMessage));\n\n handleSetStatusTree('success');\n clearGridSelection();\n return;\n }\n\n await sleep(500);\n const newTree = deleteSubNodesToTree(treeData, idFolders);\n handleUpdateTreeData(newTree);\n reFetchingFolderShortDetail();\n CustomNotification.success(intl.formatMessage(successMessage));\n\n if (viewFolderContents === 'thumbnails') handleGetDataList(20, 1, '');\n handleSetStatusTree('success');\n clearGridSelection();\n reloadPage();\n };\n\n return {\n reloadFolderWhenCreateSuccess,\n reloadFolderWhenEditSuccess,\n reloadFolderWhenDeleteSuccess,\n };\n};\n\nconst defaultColProperties = {\n resizable: true,\n};\n\nconst formatColumns = (columns) => {\n if (!columns?.length) return null;\n\n const checkboxColumn = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n sortable: false,\n },\n ];\n\n const excludeColumns = ['id', 'thumbnail'];\n\n const columnsFilter = columns.filter(\n (column) => excludeColumns.indexOf(column?.fieldNameCamelCase) === -1\n );\n\n const fieldNameCamelCaseMapping = columnsFilter?.map(\n (item) => item.fieldNameCamelCase\n );\n\n const renderEntityTypeIcon = (item) => {\n return (\n \n {entityTypeIcon(item?.data?.type)}\n \n );\n };\n\n const formattedColumns = fieldNameCamelCaseMapping.map((showCol) => {\n const colData = columns.find(\n (dataCol) => dataCol?.fieldNameCamelCase === showCol\n );\n\n switch (showCol) {\n case 'type':\n return {\n ...colData,\n ...defaultColProperties,\n cellRenderer: renderEntityTypeIcon,\n filter: false,\n suppressMenu: true,\n width: 80,\n };\n case 'description':\n return {\n ...colData,\n ...defaultColProperties,\n minWidth: 150,\n resizable: true,\n flex: 1,\n cellRenderer: customCellComponents.renderLink,\n };\n\n case 'size':\n return {\n ...colData,\n ...defaultColProperties,\n width: 140,\n resizable: true,\n fieldName: 'Size',\n allowFilter: false,\n cellRenderer: formatSizeUnitByParam,\n };\n\n case 'lastUpdated':\n return {\n ...colData,\n ...defaultColProperties,\n flex: 1,\n minWidth: 150,\n valueFormatter: formatMDYWithParam,\n resizable: true,\n };\n\n case 'dateCreated':\n return {\n ...colData,\n ...defaultColProperties,\n flex: 1,\n minWidth: 150,\n valueFormatter: formatMDYWithParam,\n resizable: true,\n };\n\n case 'entityVisibilityType':\n return {\n ...colData,\n displayName: 'Visibility',\n };\n\n default:\n return {\n ...colData,\n ...defaultColProperties,\n };\n }\n });\n\n return checkboxColumn.concat(formattedColumns);\n};\n\nexport {\n folderInfoFields,\n renderValueFolderInfo,\n getImageFolder,\n checkOwnerFolder,\n renderPathname,\n useFetchFolder,\n useInitialComponent,\n updateNode,\n addNodeToTree,\n deleteSubNodesToTree,\n defaultFolderParam,\n useReloadFolderActionWhenSuccess,\n formatColumns,\n};\n","import { useState, useEffect } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport * as folderSelectors from 'pages/folders/controllers/selectors';\nimport * as folderActions from 'pages/folders/controllers/actions';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\n\nimport { useFetch } from 'hooks/useAsync';\n\nimport * as folderServices from 'services/folder';\n\nconst shortDetailServiceCollection = {\n folder: folderServices.getFolderShortDetail,\n asset: folderServices.getDigitalAssetPreview,\n member: folderServices.getMemberPreview,\n product: folderServices.getProductPreview,\n reporting: folderServices.getReportingPreview,\n query: folderServices.getQueryPreview,\n};\n\nconst useFolderContentPane = () => {\n const dispatch = useDispatch();\n\n const { run, data, status, resetData } = useFetch();\n\n const shortDetail = data?.data;\n\n const [contentPaneType, setContentPaneType] = useState(null);\n\n const visibleContentPane = useSelector(selectorsGridView.makeSelectVisible());\n\n const selectedItems = useSelector(\n selectorsGridView.makeSelectDetailCurrentITemsSelection()\n );\n\n const { folderBreadcrumb } = useSelector(\n folderSelectors.selectFolderListByLevel()\n );\n const currentFolder = folderBreadcrumb[folderBreadcrumb?.length - 1];\n\n const selectedItem = selectedItems?.[0];\n\n const currentShortItem = selectedItem\n ? selectedItem\n : currentFolder?.id === 'home'\n ? {}\n : currentFolder;\n\n const fetchShortDetail = ({ id, type }) => {\n if (!id) return;\n\n const service = shortDetailServiceCollection[type?.toLowerCase()];\n\n if (!service) return;\n\n const params = {\n id,\n ...(type?.toLowerCase() === 'folder' && { IsLoadContent: true }),\n };\n\n run(service(params), () => {\n setContentPaneType(type?.toLowerCase());\n });\n };\n\n const clearContentPane = () => {\n resetData();\n };\n\n const fetchData = async () => {\n if (!currentShortItem) return;\n\n const { id, type } = currentShortItem;\n\n await fetchShortDetail(currentShortItem);\n\n if (type?.toLowerCase() === 'folder')\n dispatch(folderActions.getDownloadSetting(id));\n };\n\n useEffect(() => {\n if (visibleContentPane && currentShortItem?.id) {\n fetchData();\n return;\n }\n\n //* clear data when close panel, it will prevent show old data when selecting other item\n clearContentPane();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n //* separate into 2 useEffect to prevent duplicated api call\n useEffect(() => {\n //* re-fetch short content data when selecting another item while content panel is opening\n if (status !== 'resolved') return;\n\n if (visibleContentPane && currentShortItem?.id) {\n fetchData();\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [currentShortItem?.id]);\n\n return {\n shortDetail,\n isLoading: status === 'pending',\n contentPaneType,\n };\n};\n\nexport { useFolderContentPane };\n","import { useEffect, useMemo, useState } from 'react';\nimport { useSelector } from 'react-redux';\n\nimport { Typography } from 'antd';\n\nimport customCellComponents, {\n QueryLink,\n} from 'pages/folders/components/custom-cell-components';\n\nimport { CustomNotification } from 'common/components';\n\nimport {\n FolderGridItemContainer,\n useFolderGridDetailView,\n} from '../shared/grid-detail';\n\nimport { useCallbackRef } from 'hooks';\nimport { useGetColumnsGrid } from 'hooks/useGetColumns';\nimport useCheckFavoriteRoute from 'hooks/useCheckFavoriteRoute';\n\nimport * as folderSelectors from '../controllers/selectors';\n\nimport { formatMDYWithParam } from 'utils/formatDate';\nimport { formatSizeUnitByParam } from 'utils/formatSizeUnits';\nimport { sortFolderToTop } from '../shared/utils';\n\nimport { getFolderDetailGrid, getFavoriteFolderList } from 'services/folder';\n\nimport { entityTypeIcon } from 'utils/entityTypeIcon';\nimport { sleep } from 'utils/delay';\n\nexport const createServerSideDatasource = (blockSizeData) => {\n return {\n getRows: (params) => {\n const response = blockSizeData.getData(params.request);\n\n if (response.success) {\n params.success({\n rowData: response.rows,\n rowCount: response.lastRow,\n });\n } else {\n params.fail();\n }\n },\n };\n};\n\nexport const createDataByBlockSize = (allData) => {\n return {\n getData: (request) => {\n const requestedRows = allData.slice(request.startRow, request.endRow);\n return {\n success: true,\n rows: requestedRows,\n lastRow: allData.length,\n };\n },\n };\n};\n\nconst pathUrl = {\n folder: 'folder',\n product: 'product',\n asset: 'asset',\n member: 'company',\n reporting: 'reporting',\n query: 'query',\n};\n\nconst mappingColumns = (columns = []) => {\n let result = [\n {\n field: '',\n checkboxSelection: true,\n filter: false,\n suppressMenu: true,\n resizable: false,\n allowFilter: false,\n allowSort: false,\n },\n {\n field: '',\n width: 85,\n cellRenderer: customCellComponents.renderFavSharePackIcons,\n filter: false,\n suppressMenu: true,\n resizable: false,\n allowFilter: false,\n allowSort: false,\n },\n {\n field: 'type',\n cellRenderer: (params) => {\n const { type } = params?.data ?? {};\n const isFolderType = type.toLowerCase() === 'folder';\n\n if (isFolderType) {\n return (\n \n {customCellComponents.renderFolderOptionIcon(params)}\n \n );\n }\n\n return (\n
{entityTypeIcon(type)}
\n );\n },\n filter: false,\n suppressMenu: true,\n width: 70,\n resizable: false,\n allowFilter: false,\n allowSort: false,\n },\n {\n field: 'description',\n headerName: 'Description',\n resizable: true,\n cellRenderer: (params) => {\n const name = params?.data?.folderName ?? params?.data?.description;\n if (params?.data?.type?.toLowerCase() === 'query') {\n return ;\n }\n\n const to = `${pathUrl[params?.data?.type?.toLowerCase()]}/${\n params?.data?.id\n }`;\n return (\n \n {params?.data?.folderName ?? params?.data?.description}\n \n );\n },\n minWidth: 300,\n flex: 1,\n allowFilter: true,\n allowSort: true,\n },\n ];\n\n const ShowColumns = [\n // 'description',\n 'folderSize',\n 'productCount',\n 'assetCount',\n 'creatorFullName',\n 'memberName',\n 'dateCreated',\n 'lastUpdated',\n 'drm',\n ];\n\n if (columns?.length > 0) {\n columns.forEach((col) => {\n if (ShowColumns.indexOf(col?.fieldNameCamelCase) > -1) {\n if (\n col.fieldNameCamelCase === 'creatorFullName' ||\n col.fieldNameCamelCase === 'memberName' ||\n col.fieldNameCamelCase === 'description'\n ) {\n col = { ...col, width: 150 };\n } else if (col.fieldNameCamelCase === 'folderSize') {\n col = {\n ...col,\n cellRenderer: formatSizeUnitByParam,\n width: 150,\n };\n } else if (\n col.fieldNameCamelCase === 'productCount' ||\n col.fieldNameCamelCase === 'assetCount'\n ) {\n col = { ...col, width: 150 };\n } else if (col.fieldNameCamelCase === 'drm') {\n col = { ...col, headerName: 'DRM', width: 150 };\n } else if (\n col.fieldNameCamelCase === 'dateCreated' ||\n col.fieldNameCamelCase === 'lastUpdated'\n ) {\n col = {\n ...col,\n cellRenderer: formatMDYWithParam,\n width: 150,\n };\n }\n\n // if (col.fieldNameCamelCase === 'description')\n // col = { ...col, linkTo: '/folder/{id}', minWidth: 300, flex: 1 };\n result.push({ ...col, resizable: true });\n }\n });\n }\n\n return result;\n};\n\nconst defaultFolderParams = {\n pageSize: 9999,\n pageIndex: 1,\n folderId: null,\n sort: [\n [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ],\n ],\n filters: [],\n search: {\n searchText: '',\n },\n};\n\nconst moveFolderToTop = (data) => {\n return data.slice().sort(sortFolderToTop);\n};\n\nexport const useAgGridFolder = ({\n folderOption,\n searchText,\n typeView,\n requestParams: propsRequestParams,\n}) => {\n const isDetailGridView = typeView === 'detailsview';\n\n const columns = useGetColumnsGrid(\n isDetailGridView ? 'folder-detail-grid' : ''\n );\n\n const gridApi = useFolderGridDetailView();\n const isFavoriteRoute = useCheckFavoriteRoute();\n\n const { folderBreadcrumb } = useSelector(\n folderSelectors.selectFolderListByLevel()\n );\n\n const isRoot = folderBreadcrumb?.length === 1;\n\n const columnDefs = useMemo(() => mappingColumns(columns), [columns]);\n\n const [shouldReloadAgGrid, setShouldReloadAgGrid] = useState(false);\n const [requestParamsFolder, setRequestParamsFolder] = useState({\n folderId: null,\n });\n\n const getFolderDetailService =\n isFavoriteRoute && isRoot ? getFavoriteFolderList : getFolderDetailGrid;\n\n const fetchRootFolders = async (agGridParams) => {\n const folderParams = {\n ...defaultFolderParams,\n ...propsRequestParams,\n sort: searchText\n ? []\n : [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ],\n folderOption,\n search: {\n searchText,\n },\n };\n\n const responseData = await getFolderDetailService(folderParams);\n\n if (responseData?.isSuccess) {\n const folderData = responseData?.data?.gridData ?? [];\n\n const blockSizeData = createDataByBlockSize(folderData);\n const datasource = createServerSideDatasource(blockSizeData);\n\n agGridParams.api.setServerSideDatasource(datasource);\n } else {\n agGridParams.api.setServerSideDatasource([]);\n CustomNotification.error(responseData?.message ?? 'Something went wrong');\n }\n };\n\n const getSubFolderContent = async (agGridParams) => {\n //* get subfolder content\n const currentBreadcrumb = folderBreadcrumb[folderBreadcrumb.length - 1];\n const folderId = currentBreadcrumb?.id;\n\n const folderParams = {\n ...defaultFolderParams,\n ...propsRequestParams,\n sort: searchText\n ? []\n : [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ],\n search: {\n searchText,\n },\n folderOption,\n folderId,\n };\n\n const responseData = await getFolderDetailService(folderParams);\n\n if (responseData?.isSuccess) {\n const folderList = responseData?.data?.gridData ?? [];\n const sortedFolderList = moveFolderToTop(folderList);\n\n const blockSizeData = createDataByBlockSize(sortedFolderList);\n const datasource = createServerSideDatasource(blockSizeData);\n\n agGridParams.api.setServerSideDatasource(datasource);\n } else {\n agGridParams.api.setServerSideDatasource([]);\n CustomNotification.error(responseData?.message ?? 'Something went wrong');\n }\n };\n\n /* \n I don't want use this useEffect, because AgGrid force me\n */\n useEffect(() => {\n if (!isDetailGridView) return;\n\n if (folderBreadcrumb?.length > 1) {\n const currentBreadcrumb = folderBreadcrumb[folderBreadcrumb.length - 1];\n const folderId = currentBreadcrumb?.id;\n\n setRequestParamsFolder((prevVal) => ({\n ...prevVal,\n folderId,\n }));\n } else {\n setRequestParamsFolder((prevVal) => ({\n ...prevVal,\n ...propsRequestParams,\n folderId: null,\n }));\n }\n }, [folderBreadcrumb?.length, JSON.stringify(propsRequestParams)]);\n\n const onGridReady = useCallbackRef(async (params) => {\n if (params?.api) {\n gridApi.current = params?.api;\n }\n\n if (isRoot) {\n fetchRootFolders(params);\n } else {\n getSubFolderContent(params);\n }\n });\n\n const handleToggleReloadAgGrid = async () => {\n setShouldReloadAgGrid(true);\n await sleep(200);\n setShouldReloadAgGrid(false);\n };\n\n const onSortChanged = useCallbackRef(async () => {\n if (isRoot) {\n setRequestParamsFolder((prevVal) => ({\n ...prevVal,\n folderId: null,\n }));\n } else {\n const currentBreadcrumb = folderBreadcrumb[folderBreadcrumb.length - 1];\n const folderId = currentBreadcrumb?.id;\n setRequestParamsFolder((prevVal) => ({\n ...prevVal,\n folderId,\n }));\n }\n handleToggleReloadAgGrid();\n });\n\n const onFilterChanged = useCallbackRef(async () => {\n if (isRoot) {\n setRequestParamsFolder((prevVal) => ({\n ...prevVal,\n folderId: null,\n }));\n } else {\n const currentBreadcrumb = folderBreadcrumb[folderBreadcrumb.length - 1];\n const folderId = currentBreadcrumb?.id;\n setRequestParamsFolder((prevVal) => ({\n ...prevVal,\n folderId,\n }));\n }\n handleToggleReloadAgGrid();\n });\n\n return {\n gridConfigProps: {\n onGridReady,\n serverSideStoreType: 'partial',\n cacheBlockSize: 50,\n blockLoadDebounceMillis: 500,\n notCheckTotalRecordAgGrid: true,\n onSortChanged,\n onFilterChanged,\n // maxBlocksInCache: 5,\n },\n requestParamsFolder,\n columnDefs,\n shouldReloadAgGrid,\n };\n};\n","import { useDispatch } from 'react-redux';\n\nimport { defaultSearchText } from '@redux/global/reducer';\nimport * as globalActions from '@redux/global/actions';\nimport * as gridViewActions from 'common/components/grid-view/controllers/actions';\nimport * as folderActions from '../controllers/actions';\n\nimport { useGridView } from 'hooks/useGridView';\n\nimport { getLinkPathByEntityType } from 'utils/common/linkBuilder';\nimport { buildHierarchyBreadcrumb } from './utils';\nimport { useFolderByLevel } from 'hooks/useFolderByLevel';\n\nexport const useFolderGridItem = (props) => {\n const dispatch = useDispatch();\n\n const { dataDetail, folderOption } = props;\n\n const { clearGridSelection } = useGridView();\n const { handleFetchFolderByLevel } = useFolderByLevel();\n\n const openEntity = () => {\n const { id, type } = dataDetail;\n\n if (!id) return;\n if (!type) return;\n\n if (type === 'query') return openQueryItem(dataDetail);\n\n const path = getLinkPathByEntityType(type);\n window.open(`${window.location.origin}${path}/${id}`).focus();\n };\n\n const openNestedFolderGrid = async () => {\n const { id } = dataDetail;\n\n const breadcrumbs = await buildHierarchyBreadcrumb(dataDetail);\n\n dispatch(gridViewActions.togglePreventCallApiGridView(true));\n dispatch(globalActions.resetSearchText(defaultSearchText));\n\n handleFetchFolderByLevel({\n folderId: id,\n folderOption,\n successCallback: () => {\n // Need to review\n dispatch(folderActions.updateFolderBreadcrumb(breadcrumbs));\n // await sleep(400);\n clearGridSelection();\n },\n });\n };\n\n const openQueryItem = (dataDetail) => {\n if (!dataDetail) return;\n\n const { id } = dataDetail;\n\n const url = `${window.location.origin}/execute-query/${id}`;\n\n window.open(url).focus();\n //* query execution are handled in execute-query/index\n };\n\n return {\n openEntity,\n openNestedFolderGrid,\n };\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport {\n FolderBreadcrumb,\n FolderItemContainer,\n} from 'common/components/folder';\nimport { FolderThumbnailCard, FolderTile } from '../components';\n\nimport * as globalActions from '@redux/global/actions';\n\nimport { useGridView } from 'hooks/useGridView';\nimport { useFolderByLevel } from 'hooks/useFolderByLevel';\nimport useCheckFavoriteRoute from 'hooks/useCheckFavoriteRoute';\nimport { useFolderGridItem } from './hooks';\nimport useDocumentAttachEvent from 'hooks/documentAttachEventHook';\nimport { forwardTo } from 'utils/common/route';\n\nimport { EVENT } from 'static/Constants';\n\nexport const FolderGridViewSection = ({\n folderOption,\n // isHideBreadcrumb,\n searchText,\n requestParams,\n children,\n ...rest\n}) => {\n const dispatch = useDispatch();\n\n const isFavoriteRoute = useCheckFavoriteRoute();\n\n const { clearGridSelection } = useGridView();\n const {\n folderBreadcrumb,\n handleFetchFolderByLevel,\n updateFolderBreadcrumb,\n resetFolderBreadcrumb,\n } = useFolderByLevel();\n\n const handleGetFolderByBreadcrumb = async (idBreadcrumb) => {\n const currentBreadcrumb = folderBreadcrumb[folderBreadcrumb.length - 1];\n\n if (currentBreadcrumb?.id === idBreadcrumb) return;\n\n const { id } =\n folderBreadcrumb.find((item) => item?.id === idBreadcrumb) ?? {};\n\n const isRoot = id === 'home';\n\n const advFilterParams = isRoot ? requestParams : {};\n\n handleFetchFolderByLevel({\n folderId: isRoot ? null : id,\n folderOption,\n params: { ...advFilterParams, folderOption, isFavoriteRoute },\n });\n\n clearGridSelection();\n dispatch(globalActions.updateToggleDetail(false));\n\n //* update breadcrumb\n if (isRoot) {\n resetFolderBreadcrumb();\n } else {\n const foundIdxBreadcrumb = folderBreadcrumb.findIndex(\n (item) => parseInt(item.id) === parseInt(id)\n );\n\n const newBreadcrumbs = folderBreadcrumb.slice(0, foundIdxBreadcrumb + 1);\n updateFolderBreadcrumb(newBreadcrumbs);\n }\n };\n\n const backToHome = () => {\n handleGetFolderByBreadcrumb('home');\n };\n\n useDocumentAttachEvent({\n name: EVENT.BACK_FOLDER_GRID_TO_HOME,\n handler: backToHome,\n });\n\n return (\n
\n {/* {isHideBreadcrumb ? null : (\n )} */}\n handleGetFolderByBreadcrumb(breadcrumb)}\n />\n {children}\n
\n );\n};\n\nexport const FolderViewContainer = ({ children, configProps }) => {\n const dispatch = useDispatch();\n\n const { clearGridSelection } = useGridView();\n\n const { onClickItemGrid, dataDetail, folderOption } = configProps || {};\n\n const { openEntity, openNestedFolderGrid } = useFolderGridItem({\n dataDetail,\n folderOption,\n });\n const { updateShouldKeepBreadcrumb } = useFolderByLevel();\n\n const onDoubleClick = () => {\n if (!dataDetail) return;\n forwardTo(`/folder/${dataDetail?.id}`);\n };\n\n const onClickLink = () => {\n //* clicking on link will redirect to item detail page\n //* when closing detail, breadcrumb will reset\n\n //* So prevent resetting breadcrumb\n dataDetail?.type.toLowerCase() !== 'query' &&\n updateShouldKeepBreadcrumb(true);\n };\n\n /*\n Checkbox is wrong, because onClick is overlapping onCheckGrid\n */\n\n return (\n {\n const target = event.srcElement.tagName;\n if (target === 'A') {\n onClickLink();\n\n //* prevent selecting\n return;\n }\n\n onClickItemGrid && onClickItemGrid(dataDetail, event);\n }}\n >\n {children}\n \n );\n};\n\nexport const FolderGridThumbnail = (configProps) => {\n return (\n \n \n \n );\n};\n\nexport const FolderGridTile = (configProps) => {\n return (\n \n \n \n );\n};\n","import React, { createContext, useRef } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { Tooltip } from 'antd';\n\nimport { CustomNotification } from 'common/components';\nimport {\n FolderBreadcrumb,\n FolderItemContainer,\n} from 'common/components/folder';\n\nimport * as folderSelectors from '../../controllers/selectors';\nimport * as folderActions from '../../controllers/actions';\n\nimport { getFolderDetailGrid } from 'services/folder';\n\nimport {\n createDataByBlockSize,\n createServerSideDatasource,\n} from '../../hooks/useAgGridFolder';\n\nimport { useCallbackRef } from 'hooks';\nimport 'pages/folders/style.less';\nimport { forwardTo } from 'utils/common/route';\n\nconst FolderGridDetailViewContext = createContext({});\n\nexport const FolderGridDetailViewProvider = ({ children }) => {\n const gridApi = useRef();\n\n return (\n \n {children}\n \n );\n};\n\nexport const useFolderGridDetailView = () => {\n const context = React.useContext(FolderGridDetailViewContext);\n\n if (context === undefined) {\n throw new Error(\n 'useFolderGridDetailView must be used within a FormContextProvider'\n );\n }\n return context;\n};\n\nexport const FolderGridDetailViewSection = ({\n folderOption,\n children,\n ...rest\n}) => {\n const { folderBreadcrumb } = useSelector(\n folderSelectors.selectFolderListByLevel()\n );\n\n const dispatch = useDispatch();\n\n const gridApi = useFolderGridDetailView();\n\n const handleGetItemByBreadcrumb = useCallbackRef(async (idBreadcrumb) => {\n const currentBreadcrumb = folderBreadcrumb[folderBreadcrumb.length - 1];\n if (currentBreadcrumb?.id === idBreadcrumb) return;\n\n const { id } =\n folderBreadcrumb.find((item) => item?.id === idBreadcrumb) ?? {};\n\n const isRoot = id === 'home';\n\n if (isRoot) {\n const folderParams = {\n pageSize: 9999,\n pageIndex: 1,\n sort: [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ],\n filters: [\n {\n fieldName: 'level',\n filterType: 'Equal',\n value: '1', //\n },\n ],\n folderOption,\n isAdvanceSearch: false,\n advCriteria: [],\n search: {\n searchText: '',\n },\n };\n getFolderDetailGrid(folderParams).then((resp) => {\n if (resp?.data?.gridData) {\n const data = resp.data.gridData;\n\n const blockSizeData = createDataByBlockSize(data);\n const datasource = createServerSideDatasource(blockSizeData);\n\n if (gridApi?.current) {\n gridApi.current.setServerSideDatasource(datasource);\n }\n dispatch(\n folderActions.updateFolderBreadcrumb([\n {\n id: 'home',\n folderName: 'Home',\n },\n ])\n );\n }\n });\n } else {\n const params = {\n folderId: id,\n pageIndex: 1,\n pageSize: 9999,\n filters: [],\n sort: [\n {\n fieldName: 'id',\n isAscending: false,\n },\n ],\n isFavoriteRoute: false,\n };\n const foundIdxBreadcrumb = folderBreadcrumb.findIndex(\n (item) => parseInt(item.id) === parseInt(id)\n );\n const newBreadcrumbs = folderBreadcrumb.slice(0, foundIdxBreadcrumb + 1);\n const response = await getFolderDetailGrid(params);\n try {\n if (response?.isSuccess) {\n const gridData = response?.data?.gridData ?? [];\n const item = gridData.map((folder) => ({\n ...folder,\n folderName: folder?.description,\n }));\n\n const blockSizeData = createDataByBlockSize(item);\n const datasource = createServerSideDatasource(blockSizeData);\n\n if (gridApi?.current) {\n gridApi.current.setServerSideDatasource(datasource);\n }\n\n dispatch(folderActions.updateFolderBreadcrumb(newBreadcrumbs));\n } else {\n CustomNotification.error('Something went wrong');\n }\n } catch (error) {}\n }\n });\n\n return (\n
\n handleGetItemByBreadcrumb(breadcrumb)}\n />\n {children}\n
\n );\n};\n\nexport const FolderGridItemContainer = ({ params, children }) => {\n const handleOpenDetail = async () => {\n const { data } = params;\n forwardTo(`/folder/${data?.id}`);\n };\n\n return (\n \n {\n // dispatch(globalActions.updateToggleDetail(false));\n // }}\n >\n {children}\n \n \n );\n};\n","import { getFolderShortDetail } from 'services/folder';\n\nconst homeBreadcrumb = [\n {\n id: 'home',\n folderName: 'Home',\n },\n];\n\nexport const generateChildBreadcrumbs = async (fullPathIds) => {\n let result = [];\n\n const promises = fullPathIds.map((id) =>\n getFolderShortDetail({\n id,\n IsLoadContent: false,\n })\n );\n\n const detailFolderResponses = await Promise.all(promises);\n\n detailFolderResponses.forEach((resp) => {\n const breadcrumb = {\n id: resp?.data?.id,\n folderName: resp?.data?.folderName ?? resp?.data?.description,\n };\n result.push(breadcrumb);\n });\n\n return result;\n};\n\nexport const buildHierarchyBreadcrumb = async (selectedFolder) => {\n if (selectedFolder) {\n const {\n level,\n hierarchy,\n id: selectedId,\n folderName,\n description,\n editable,\n } = selectedFolder;\n const isRootFolder = level === 1;\n\n if (isRootFolder) {\n const breadcrumb = {\n id: selectedId,\n folderName: folderName ?? description,\n editable,\n };\n return homeBreadcrumb.concat(breadcrumb);\n }\n\n const parentIds = hierarchy\n ? hierarchy\n .split('/')\n .filter(Boolean)\n .map((id) => parseInt(id))\n : [];\n const fullPathIds = parentIds.concat(selectedId);\n\n const childBreadcrumbs = await generateChildBreadcrumbs(fullPathIds);\n\n return homeBreadcrumb.concat(childBreadcrumbs);\n }\n\n return [];\n};\n\nexport const sortFolderToTop = (a, b) => {\n if (a.type.toLowerCase() === 'folder') {\n if (b.type.toLowerCase() === 'folder') return 0;\n return -1; //* sort folder to the top\n } else if (a.type.toLowerCase() !== 'folder') {\n //* this is not convenient but write details like this just to support Firefox\n if (b.type.toLowerCase() === 'folder') return 1;\n return 0;\n }\n\n return 0;\n};\n","import React from 'react';\n\nimport { Badge, Image } from 'antd';\n\nimport classnames from 'classnames';\n\nimport SandClockImage from 'assets/navigation/sand-clock.png';\n\nexport const FilterIndicator = ({\n onClickAction,\n isGdsnReceivedProducts,\n absoluteRight,\n absoluteTop,\n actionData,\n children,\n}) => {\n return (\n \n {/* */}\n \n \n {isGdsnReceivedProducts ? (\n \n ) : (\n <>{children}\n )}\n \n \n \n );\n};\n","import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Image } from 'antd';\nimport PropTypes from 'prop-types';\nimport classnames from 'classnames';\nimport { forwardTo } from 'utils/common/route';\n\nimport * as globalActions from '@redux/global/actions';\nimport * as globalSelectors from '@redux/global/selectors';\n\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\n\nimport { clearQueryCondition } from 'utils/queryCondition';\n\nimport NewImage from 'assets/navigation/new.png';\nimport { PRODUCT_NAV } from 'static/Constants';\nimport { SSO_APPROVAL_NAV } from 'static/Constants';\n\nimport { FilterIndicator } from './FilterIndicator';\n\n//* STYLING\nimport './HomeNavActionGroup.less';\n\nfunction HomeNavActionGroup(props) {\n const dispatch = useDispatch();\n\n const { actionData, absoluteRight, absoluteTop, link, type } = props;\n\n const isMemberNew = useSelector(globalSelectors.selectDisplayMemberNew());\n const isAssetNew = useSelector(globalSelectors.selectDisplayAssetNew());\n const isProductNew = useSelector(globalSelectors.selectDisplayProductNew());\n\n const isAssetUnmatch = useSelector(\n globalSelectors.selectDisplayAssetUnmatch()\n );\n const isProductUnmatch = useSelector(\n globalSelectors.selectDisplayProductUnmatch()\n );\n const isMemberUnmatch = useSelector(\n globalSelectors.selectDisplayMemberUnmatch()\n );\n\n const filterSsoUserPending = useSelector(\n globalSelectors.selectToggleSsoUserPending()\n );\n const filterSsoMemberPending = useSelector(\n globalSelectors.selectToggleSsoMemberPending()\n );\n const filterProducts = useSelector(globalSelectors.selectFilterProducts());\n const filterAssets = useSelector(globalSelectors.selectFilterAssets());\n const filterMembers = useSelector(globalSelectors.selectFilterMembers());\n\n const prevPathnameQuery = useSelector(\n selectorsGridView.makeSelectPrevPathnameQuery()\n );\n\n const isGdsnReceivedProducts = link === PRODUCT_NAV.subItems[2].link;\n const isSsoMemberApproval = link === SSO_APPROVAL_NAV.subItems[0].link;\n const isSsoUserApproval = link === SSO_APPROVAL_NAV.subItems[1].link;\n\n const actionCollection = {\n '/members': {\n target: 'new',\n isFiltering: isMemberNew,\n isUnmatched: isMemberUnmatch,\n toggleNew: 'toggleMemberNew',\n toggleUnmatched: 'toggleMemberUnmatch',\n resetPage: 'resetPageCurrentMember',\n filter: filterMembers,\n updateFilter: 'updateFilterMembers',\n },\n '/digital-media': {\n target: 'new',\n isFiltering: isAssetNew,\n isUnmatched: isAssetUnmatch,\n toggleNew: 'toggleAssetNew',\n toggleUnmatched: 'toggleAssetUnmatch',\n resetPage: 'resetPageCurrentMedia',\n filter: filterAssets,\n updateFilter: 'updateFilterAssets',\n },\n '/products': {\n target: 'new',\n isFiltering: isProductNew,\n isUnmatched: isProductUnmatch,\n toggleNew: 'toggleProductNew',\n toggleUnmatched: 'toggleProductUnmatch',\n resetPage: 'resetPageCurrentProduct',\n filter: filterProducts,\n updateFilter: 'updateFilterProducts',\n },\n '/products/syndication-history': {\n target: 'new',\n toggleNew: 'toggleNewSyndicationHistory',\n },\n '/products/gdsn-received-products': {\n target: 'new',\n toggleNew: 'toggleFilterPendingPublication',\n },\n '/security-matrix/permission-request': {\n target: 'new',\n toggleNew: 'toggleRequestNew',\n },\n '/sso-approval/member': {\n target: 'pending',\n toggleNew: 'toggleFilterPendingSsoMember',\n filter: filterSsoMemberPending,\n },\n '/sso-approval/user': {\n target: 'pending',\n toggleNew: 'toggleFilterPendingSsoUser',\n filter: filterSsoUserPending,\n },\n // '/ticketing-system': {\n // target: 'new',\n // toggleNew: 'toggleNewTicketingSystem',\n // },\n };\n\n const toggleNew = () => {\n const actions = actionCollection[link];\n if (actions.target !== 'new') return;\n if (!actions.toggleNew) return;\n\n // turnUnmatchedOff();\n\n if (actions.isFiltering) {\n dispatch(globalActions[actions.toggleNew](false));\n setTimeout(() => {\n dispatch(globalActions[actions.toggleNew](true));\n }, 100);\n } else {\n dispatch(globalActions[actions.toggleNew](true));\n }\n\n actions.resetPage && dispatch(actionsGridView[actions.resetPage]());\n };\n\n const toggleUnmatched = () => {\n const actions = actionCollection[link];\n\n if (!actions.toggleUnmatched) return;\n\n // turnNewOff();\n\n if (!actions.isUnmatched) {\n dispatch(globalActions[actions.toggleUnmatched](true));\n }\n\n const filterValue = actions.filters?.includes('unmatched')\n ? []\n : ['unmatched'];\n actions.updateFilter &&\n dispatch(globalActions[actions.updateFilter](filterValue));\n\n actions.resetPage && dispatch(actionsGridView[actions.resetPage]());\n };\n\n const filterPendingSso = () => {\n const actions = actionCollection[link];\n if (actions.target !== 'pending') return;\n if (actions.filter.length > 0) return;\n dispatch(\n globalActions[actions.toggleNew]([\n {\n fieldName: 'poolStatus',\n values: ['Pending'],\n filterType: 'In',\n },\n ])\n );\n actions.resetPage && dispatch(actionsGridView[actions.resetPage]());\n };\n\n const turnUnmatchedOff = () => {\n isAssetUnmatch && dispatch(globalActions.toggleAssetUnmatch(false));\n isProductUnmatch && dispatch(globalActions.toggleProductUnmatch(false));\n isMemberUnmatch && dispatch(globalActions.toggleMemberUnmatch(false));\n };\n\n const turnNewOff = () => {\n isAssetNew && dispatch(globalActions.toggleAssetNew(false));\n isProductNew && dispatch(globalActions.toggleProductNew(false));\n isMemberNew && dispatch(globalActions.toggleMemberNew(false));\n };\n\n const onIndicatorClick = (target) => () => {\n const actions = actionCollection[link];\n if (!actions) return;\n\n if (target === actions.target) {\n toggleNew();\n filterPendingSso();\n }\n\n target === 'unmatched' && toggleUnmatched();\n\n clearQueryCondition(dispatch, '', prevPathnameQuery);\n forwardTo(link);\n };\n\n const targetToggleFilter =\n isSsoMemberApproval || isSsoUserApproval ? 'pending' : 'new';\n\n return (\n \n {!!actionData &&\n actionData > 0 &&\n type === 'new' &&\n !isGdsnReceivedProducts && (\n \n \n \n )}\n\n {!!actionData && actionData > 0 && type === 'unmatched' && (\n \n \n \n )}\n {!!actionData && isGdsnReceivedProducts && actionData > 0 && (\n \n )}\n \n );\n}\n\nHomeNavActionGroup.propTypes = {\n //? link - path name\n link: PropTypes.string,\n //? actionData - action status of activity and new\n actionData: PropTypes.number,\n //? absoluteRight - position absolute right position\n absoluteRight: PropTypes.number,\n};\n\nexport default HomeNavActionGroup;\n","import React from 'react';\nimport PropTypes, { oneOfType } from 'prop-types';\nimport { useSelector } from 'react-redux';\nimport * as selectors from '@redux/branding/selectors';\nimport { Link } from 'react-router-dom';\nimport { Typography } from 'antd';\nimport classnames from 'classnames';\nimport HomeNavActionGroup from './HomeNavActionGroup';\nimport './HomeNavSubMenuTitle.less';\nimport { OFFSET_X_UNMATCHED } from 'static/Constants';\n\nimport { MAIN_PAGE_LINK } from 'static/Constants';\nimport { forwardTo } from 'utils/common/route';\n\nconst { Text } = Typography;\n\nfunction HomeNavSubMenuTitle(props) {\n const {\n titleName,\n keyName,\n link,\n selectedKeys,\n actionDataNew,\n actionDataUnmatched,\n actionLink,\n } = props;\n const pathName = window.location.pathname;\n const branding = useSelector(selectors.getBranding());\n\n const getPositionUnmatchedByTotalNew = (totalNew) => {\n if (totalNew && totalNew > 0) {\n return OFFSET_X_UNMATCHED.offsetXHight;\n }\n\n return OFFSET_X_UNMATCHED.offsetXLow;\n };\n\n const calcPositionActionInNavMenu = () => {\n switch (actionLink) {\n case '/products': {\n return getPositionUnmatchedByTotalNew(branding.totalNewProducts);\n }\n case '/digital-media': {\n return getPositionUnmatchedByTotalNew(branding.totalNewDams);\n }\n default:\n break;\n }\n };\n\n const positionUnmatched = calcPositionActionInNavMenu();\n\n const handleClickMenuTitle = (link) => {\n if (MAIN_PAGE_LINK.includes(link)) {\n forwardTo(`/blank?returnUrl=${link}`);\n }\n };\n\n return (\n
\n {!MAIN_PAGE_LINK.includes(link) && link ? (\n \n \n {titleName || 'NO NAME'}\n \n \n ) : (\n {\n e.preventDefault();\n handleClickMenuTitle(link);\n }}\n >\n \n {titleName || 'NO NAME'}\n \n \n )}\n \n \n
\n );\n}\n\nHomeNavSubMenuTitle.propTypes = {\n //? titleName - name of submenu\n titleName: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),\n //? keyName - keyname when it is selected - required\n keyName: PropTypes.string.isRequired,\n // ? link - path name\n link: oneOfType([\n PropTypes.string.isRequired,\n PropTypes.oneOf([undefined]).isRequired,\n ]),\n // ? selectedKey - selected key of menu Navigation\n selectedKey: PropTypes.string,\n // ? actionData - action data of sub menu item only\n actionData: PropTypes.number,\n};\n\nexport default React.memo(HomeNavSubMenuTitle);\n","import React from 'react';\n\nimport { FormOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nimport Messages from 'i18n/messages/home';\nimport { useGlobalModal } from 'hooks';\n\nexport const WIDTH_CONTANT_PANE = 500;\n\nconst EditFolderDetail = (props) => {\n const { disabled } = props;\n\n const { MODAL_NAMES, openModal } = useGlobalModal();\n\n const clickEditFolderHandler = () => {\n openModal(MODAL_NAMES.EDIT_FOLDER);\n };\n\n return (\n <>\n }\n label={Messages.editFoldersRibbon}\n onClick={clickEditFolderHandler}\n disabled={disabled}\n />\n \n );\n};\n\nexport default EditFolderDetail;\n","import React from 'react';\nimport { useIntl } from 'react-intl';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport { ReactComponent as IconDeleteFolders } from 'common/components/button/svg-icons/delete-folder.svg';\n\nimport Messages from 'i18n/messages/home';\nimport { dialogFunction, CustomNotification } from 'common/components';\nimport { apiHandler } from 'utils/api';\nimport { deleteFolders } from 'services/folder';\nimport folderMessages from 'i18n/messages/folder';\n\nconst DeleteFolderDetail = ({\n selectedFolders,\n onReloadWhenSaveSuccess,\n disabled,\n}) => {\n const intl = useIntl();\n\n const handleDeleteFolder = () => {\n const params = {\n deleteFolderIds: [selectedFolders.id],\n };\n\n apiHandler({\n service: deleteFolders,\n params,\n skipNotification: true,\n failCallback: (message) => {\n CustomNotification.error(message);\n },\n successCallback: () => {\n onReloadWhenSaveSuccess &&\n onReloadWhenSaveSuccess(params.deleteFolderIds, 'delete');\n },\n });\n };\n\n const showModalConfirm = () => {\n dialogFunction({\n type: 'warn',\n content: intl.formatMessage(folderMessages.confirmDeleteFolderMessage),\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: () => handleDeleteFolder(),\n });\n };\n return (\n <>\n }\n label={Messages.deleteFolderDetailRibbon}\n onClick={showModalConfirm}\n disabled={disabled}\n />\n \n );\n};\n\nexport default DeleteFolderDetail;\n","import React from 'react';\n\nimport { ReactComponent as IconAddFolder } from 'common/components/button/svg-icons/add-folder.svg';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nimport Messages from 'i18n/messages/home';\n\nconst CreateFolderDetail = (props) => {\n const { setVisibleModal, disabled } = props;\n\n const openNewFolderModal = () => {\n setVisibleModal(true);\n };\n\n return (\n <>\n }\n label={Messages.newFolder}\n onClick={openNewFolderModal}\n disabled={disabled}\n />\n \n );\n};\n\nexport default CreateFolderDetail;\n","import React, { useState } from 'react';\nimport { useSelector } from 'react-redux';\n\nimport { Dropdown, Menu } from 'antd';\nimport { FolderOutlined, DownloadOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport CopyFolder from '../../controls/folders/CopyFolder';\nimport MoveFolder from '../../controls/folders/MoveFolder';\nimport BulkEditProduct from '../../controls/product/BulkEditProduct';\nimport CopyFolderModal from '../../controls/folders/CopyFolderModal';\nimport MoveFolderModal from '../../controls/folders/MoveFolderModal';\n\n// redux\nimport gridSelector from 'common/components/grid-view/controllers/selectors';\nimport { useInjectReducer } from 'utils/common/injectedReducers';\nimport { useInjectSaga } from 'utils/common/injectSaga';\nimport reducer from 'common/components/grid-view/controllers/reducer';\nimport saga from 'common/components/grid-view/controllers/saga';\n\nimport { useCheckPermissions } from 'hooks/useCheckPermissions';\nimport {\n usePermissionEditSharedProduct,\n useCheckIsSuperAdmin,\n useGlobalModal,\n} from 'hooks';\n\nimport Messages from 'i18n/messages/home';\nimport messagesProduct from 'i18n/messages/product';\n\nimport './FolderSection.less';\nimport { Can } from 'context/Can';\nimport {\n ABILITY_ACTION,\n ABILITY_SUBJECT,\n PERMISSION_EDIT_PRODUCTS,\n} from 'static/Permission';\nimport EditFolderDetail from '../../controls/folders/EditFolderDetail';\nimport DeleteFolderDetail from '../../controls/folders/DeleteFolderDetail';\nimport CreateFolderDetail from '../../controls/folders/CreateFolderDetail';\nimport ExportProductPropertiesModal from '../../modal/bulk-edit-product/ExportProductPropertiesModal';\nimport ImportProductBulkEditModal from '../../modal/bulk-edit-product/ImportProductBulkEditModal';\nimport CreateFolderModal from '../../controls/folders/CreateFolderModal';\nimport FolderEditModal from 'pages/folders/components/modal/FolderEditModal';\n\nconst key = 'gridView';\nconst { SubMenu } = Menu;\n\nconst FolderDetailSection = (props) => {\n useInjectReducer({ key, reducer });\n useInjectSaga({ key, saga });\n\n const {\n folderDetail,\n handleLoading,\n onReloadWhenSaveSuccess,\n onMoveFolder,\n onCopyFolder,\n } = props;\n\n const [copyFolderModalVisible, setCopyFolderVisible] = useState(false);\n const [moveFolderModalVisible, setMoveFolderVisible] = useState(false);\n\n const createFolderModalVisibleHook = useState(false);\n const [, setVisibleModal] = createFolderModalVisibleHook;\n\n let detailItems = useSelector(\n gridSelector.makeSelectDetailCurrentITemsSelection()\n );\n\n const checkItemsProduct = () => {\n return detailItems\n .filter((item) => item?.type?.toLowerCase() === 'product')\n .map((item) => item?.id);\n };\n\n const { MODAL_NAMES, checkModalVisible, closeModal } = useGlobalModal();\n\n const isExportProductModalOpen = checkModalVisible(\n MODAL_NAMES.EXPORT_PROPERTY_MODAL\n );\n const isImportProductModalOpen = checkModalVisible(\n MODAL_NAMES.IMPORT_PROPERTY_MODAL\n );\n\n const isEditFolderModalOpen = checkModalVisible(MODAL_NAMES.EDIT_FOLDER);\n\n const detailItemsProduct = checkItemsProduct();\n\n const hasPermissionEditProducts = useCheckPermissions(\n PERMISSION_EDIT_PRODUCTS\n );\n\n const hasPermissionEditSharedProduct = usePermissionEditSharedProduct();\n const isSuperAdmin = useCheckIsSuperAdmin();\n\n const isAllowActionsPim =\n isSuperAdmin || hasPermissionEditProducts || hasPermissionEditSharedProduct;\n\n const closeCopyModal = () => {\n setCopyFolderVisible(false);\n };\n\n const closeMoveModal = () => {\n setMoveFolderVisible(false);\n };\n\n const cancelEditFolder = () => {\n closeModal(MODAL_NAMES.EDIT_FOLDER);\n };\n\n const saveEditFolderSuccess = () => {\n cancelEditFolder();\n onReloadWhenSaveSuccess && onReloadWhenSaveSuccess(folderDetail.id, 'edit');\n };\n\n const menuOptions = (\n \n \n \n {(allowed) => (\n \n )}\n \n \n \n \n {(allowed) => (\n \n )}\n \n \n \n \n {(allowed) => (\n \n )}\n \n \n \n \n {(allowed) => (\n setCopyFolderVisible(true)}\n />\n )}\n \n \n \n \n {(allowed) => (\n setMoveFolderVisible(true)}\n />\n )}\n \n \n\n }\n disabled={!isAllowActionsPim}\n label={messagesProduct.bulkEditProduct}\n />\n }\n >\n \n \n \n );\n return (\n <>\n \n }\n label={Messages.folderActions}\n />\n \n \n \n {isExportProductModalOpen && (\n \n )}\n {isImportProductModalOpen && (\n \n )}\n \n {isEditFolderModalOpen ? (\n \n ) : null}\n \n );\n};\n\nexport default FolderDetailSection;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { RibbonBar, RibbonDivider } from 'common/components';\nimport ManageSharingSection from './components/sections/shared/ManageSharingSection';\nimport DetailSection from './components/sections/home-grid/DetailSection';\nimport FolderDetailSection from './components/sections/folder/FolderDetailSection';\nimport ManageScheduleDownload from 'pages/home/ribbon/components/controls/folders/ManageScheduleDownload';\n\nimport { ViewLayout, AdvanceStack, OtherLayout } from './components';\n\nimport { useFolderByLevel } from 'hooks/useFolderByLevel';\n\nconst FolderDetailRibbon = (props) => {\n const {\n folderDetail,\n handleLoading,\n onReloadWhenSaveSuccess,\n onMoveFolder,\n onCopyFolder,\n } = props;\n\n const { keepFolderBreadcrumb } = useFolderByLevel();\n\n const closeDetailCallback = () => {\n keepFolderBreadcrumb(true);\n };\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nFolderDetailRibbon.propTypes = {\n onSearch: PropTypes.func,\n toggleSearch: PropTypes.bool,\n};\n\nexport default FolderDetailRibbon;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { RibbonBar } from 'common/components';\nimport ManageSharingSection from './components/sections/shared/ManageSharingSection';\nimport DetailSection from './components/sections/home-grid/DetailSection';\nimport BackControl from './components/controls/home/Back';\n\nimport { ViewLayout, AdvanceStack } from './components';\nimport { HIDE_CLOSE_DETAIL_BUTTON } from 'static/Constants';\nimport { DISABLE_SHOW_PREVIEW_IN_HOME_RIBBON } from 'static/Constants';\n// const productsForMember = 'products/member';\n// const assetsForMember = 'assets/member';\n\nconst Home = () => {\n const pathname = window.location.pathname;\n // const isBackToMemberProfile =\n // pathname.includes(productsForMember) || pathname.includes(assetsForMember);\n // const isReportingsBack = pathname.includes('/reporting');\n\n const isDisableShowPreview = DISABLE_SHOW_PREVIEW_IN_HOME_RIBBON.some(\n (substring) => pathname.includes(substring)\n );\n\n return (\n \n \n \n \n \n {!HIDE_CLOSE_DETAIL_BUTTON.includes(window.location.pathname) && (\n \n )}\n \n );\n};\n\nHome.propTypes = {\n onSearch: PropTypes.func,\n toggleSearch: PropTypes.bool,\n};\n\nexport default Home;\n","import React from 'react';\nimport { useHistory } from 'react-router-dom';\n\nimport { ApartmentOutlined } from '@ant-design/icons';\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nimport { useGetProductFullView } from 'hooks';\nimport { useSsoProductParams } from 'hooks/useSso';\nimport Messages from 'i18n/messages/home';\nimport useToggleActiveRibbon from './hook';\n\nconst ProductHierarchy = ({ productId }) => {\n const history = useHistory();\n\n const { productFull } = useGetProductFullView({ productId });\n\n const { ssoParamUrl: ssoProductParams, productId: ssoProductId } =\n useSsoProductParams();\n\n const checkActiveContent = () => {\n const path = history?.location?.pathname;\n\n const regex = /\\/product\\/hierarchy\\/\\d+$/;\n return regex.test(path);\n };\n\n const isPathActive = checkActiveContent();\n const isActive = useToggleActiveRibbon(isPathActive);\n\n const handleClick = () => {\n if (isActive) {\n if (ssoProductParams) {\n history.push(`/product/${ssoProductId}/?${ssoProductParams}`);\n } else {\n history.push(`/product/${productFull?.productId}`);\n }\n } else {\n if (ssoProductParams) {\n history.push(`/product/hierarchy/${ssoProductId}?${ssoProductParams}`);\n } else {\n history.push(`/product/hierarchy/${productFull?.productId}`);\n }\n }\n };\n\n return (\n }\n label={Messages.productHierarchy}\n onClick={handleClick}\n toggle={isPathActive}\n disabled={!productFull?.productId}\n />\n );\n};\n\nexport default ProductHierarchy;\n","import React from 'react';\n\nimport { useHistory } from 'react-router-dom';\n\nimport { SafetyCertificateOutlined } from '@ant-design/icons';\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport useToggleActiveRibbon from './hook';\n\nimport { useGetProductFullView } from 'hooks';\nimport { useSsoProductParams } from 'hooks/useSso';\n\nimport Messages from 'i18n/messages/home';\n\nconst Subscription = ({ productId }) => {\n const history = useHistory();\n\n const { productFull } = useGetProductFullView({ productId });\n\n const { ssoParamUrl: ssoProductParams, productId: ssoProductId } =\n useSsoProductParams();\n\n const checkActiveContent = () => {\n const path = history?.location?.pathname;\n const regex = /\\/product\\/subscription\\/\\d+$/;\n return regex.test(path);\n };\n\n const isPathActive = checkActiveContent();\n const isActive = useToggleActiveRibbon(isPathActive);\n\n const handleClick = () => {\n if (productFull?.productId !== undefined) {\n if (isActive) {\n if (ssoProductParams) {\n history.push(`/product/${ssoProductId}/?${ssoProductParams}`);\n } else {\n history.push(`/product/${productFull?.productId}`);\n }\n } else {\n if (ssoProductParams) {\n history.push(\n `/product/subscription/${ssoProductId}?${ssoProductParams}`\n );\n } else {\n history.push(`/product/subscription/${productFull?.productId}`);\n }\n }\n }\n };\n\n return (\n }\n label={Messages.subscription}\n onClick={handleClick}\n toggle={isPathActive}\n disabled={!productFull?.productId}\n />\n );\n};\n\nexport default Subscription;\n","import React from 'react';\nimport { useHistory } from 'react-router-dom';\n\nimport { ProfileOutlined } from '@ant-design/icons';\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport useToggleActiveRibbon from './hook';\n\nimport { useSsoProductParams } from 'hooks/useSso';\n\nimport Messages from 'i18n/messages/home';\nimport { useGetProductFullView } from 'hooks';\n\nconst ProductDetailView = ({ productId: productIdProp }) => {\n const history = useHistory();\n\n const { productFull } = useGetProductFullView({ productId: productIdProp });\n\n const { ssoParamUrl: ssoProductParams, productId: ssoProductId } =\n useSsoProductParams();\n\n const checkActiveContent = () => {\n const path = history?.location?.pathname;\n const regex = /\\/product\\/detail\\/\\d+$/;\n return regex.test(path);\n };\n\n const isPathActive = checkActiveContent();\n const isActive = useToggleActiveRibbon(isPathActive);\n\n const handleClick = () => {\n if (isActive) {\n if (ssoProductParams) {\n history.push(`/product/${ssoProductId}/?${ssoProductParams}`);\n } else {\n history.push(`/product/${productFull?.productId}`);\n }\n } else {\n if (ssoProductParams) {\n history.push(`/product/detail/${ssoProductId}?${ssoProductParams}`);\n } else {\n history.push(`/product/detail/${productFull?.productId}`);\n }\n }\n };\n\n return (\n }\n label={Messages.productDetailView}\n onClick={handleClick}\n toggle={isPathActive}\n disabled={!productFull?.productId}\n />\n );\n};\n\nexport default ProductDetailView;\n","import { Checkbox, Typography } from 'antd';\nconst { Text } = Typography;\n/**\n * ? get all row data agrid\n * @param {*} gridInst\n * @returns\n */\nexport const getAllRows = (gridInst) => {\n let rowData = [];\n gridInst?.current?.api?.forEachNode((node) => rowData.push(node?.data));\n return rowData;\n};\n\n/**\n * ? remote errors from row\n * @param {*} rowItem\n * @param {*} errors\n * @returns\n */\nexport const removeErrorsFromRow = (rowItem, errors) => {\n const newError = (rowItem?.error || []).filter(\n (errorItem) => !errors.includes(errorItem)\n );\n return { ...rowItem, error: newError };\n};\n\n/**\n * ? add errors to row\n * @param {*} rowItem\n * @param {*} errors\n * @returns\n */\nexport const addErrorsToRow = (rowItem, errors) => {\n if (!errors && errors?.length <= 0) return rowItem;\n\n const newErrorList = errors.reduce((accErrorList, newErrorItem) => {\n if (!accErrorList.includes(newErrorItem)) {\n accErrorList.push(newErrorItem);\n }\n return accErrorList;\n }, rowItem?.error || []);\n\n return { ...rowItem, error: newErrorList };\n};\n\nexport const getFormattedValue = (snapshotData, name, enumType) => {\n const enumFound = enumType[name]?.find(\n (item) =>\n item.value === snapshotData || item.enumDisplayName === snapshotData\n );\n return enumFound?.displayName || enumFound?.enumDisplayName;\n};\n\nexport const formatCompareValue = (value) => {\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value?.length > 0 ? value : 'N/A';\n }\n\n return value || 'N/A';\n};\n\nexport const renderPopoverContent = (\n label,\n snapshotValue,\n supplierModifiedValue,\n formattedValue,\n type\n) => {\n if (snapshotValue !== supplierModifiedValue) {\n let value =\n type === 'checkbox' ? (\n \n ) : (\n formattedValue || snapshotValue?.toString() || 'N/A'\n );\n return (\n <>\n {label}: {value}\n \n );\n }\n};\n\nexport const checkSectionRequired = (requiredFields, section) => {\n if (!requiredFields?.length) return;\n\n const sectionPathKeyMap = {\n organoleptic:\n 'qaSpecProductSpecification.qaSpecProductSpecsOrganolepticCharacteristics',\n physical:\n 'qaSpecProductSpecification.qaSpecProductSpecsPhysicalAndChemicalCharacteristics',\n contaminant:\n 'qaSpecProductSpecification.qaSpecProductSpecsContaminantCharacteristics',\n microbiological:\n 'qaSpecProductSpecification.qaSpecProductSpecsMicrobiologicalCharacteristics',\n };\n\n const sectionPathKey = sectionPathKeyMap[section];\n\n if (!sectionPathKey) return false;\n\n return requiredFields.some((fieldFullPath) => {\n return fieldFullPath.includes(sectionPathKey);\n });\n};\n","import { useState } from 'react';\nimport { Row, Col, Form, Space, Button } from 'antd';\n\nimport { CloseOutlined, PlusOutlined, UploadOutlined } from '@ant-design/icons';\n\nimport { BasicFormItem } from 'common/components/form/basic-form';\nimport AddAssetPimModal from 'pages/product-full-view/components/modal/add-asset-pim-modal';\n\nimport SnapshotFormItem from 'pages/qa-spec/components/qa-spec-tab/SnapshotFormItem';\nimport { renderPopoverContent } from 'pages/qa-spec/utils';\n\nconst CertificateFormList = (props) => {\n const {\n type = 'text',\n isEdit,\n disabled,\n selectProps,\n name: nameForm,\n certificateType,\n snapshotData,\n supplierModifiedData,\n isLoadingSnapshot,\n } = props;\n\n const [isLinkToNewAssetModalOpen, setIsLinkToNewAssetModalOpen] =\n useState(false);\n\n const toggleLinkToNewAssetModal = () => {\n setIsLinkToNewAssetModalOpen((prev) => !prev);\n };\n\n return (\n <>\n \n {(fields, { add, remove }) => {\n const handleAddField = () => {\n add();\n };\n\n return (\n <>\n {fields.map(({ key, name, ...restField }) => {\n return (\n \n \n \n \n \n \n\n \n {isEdit && (\n \n remove(name)}\n style={{ color: 'red' }}\n />\n \n )}\n \n \n );\n })}\n {isEdit && (\n \n \n handleAddField()}\n icon={}\n disabled={disabled}\n type='primary'\n >\n Add field\n \n\n }\n onClick={toggleLinkToNewAssetModal}\n disabled={disabled}\n >\n Upload cetificate document\n \n \n \n )}\n \n );\n }}\n \n {isLinkToNewAssetModalOpen && (\n {\n toggleLinkToNewAssetModal();\n }}\n qaSpec\n />\n )}\n \n );\n};\n\nexport default CertificateFormList;\n","import { useSelector } from 'react-redux';\nimport { useParams } from 'react-router-dom';\nimport { useCheckMemberSupplier } from 'hooks';\nimport { useCheckSharedOnlyMyCompany } from 'hooks/useCheckPrivateMember';\nimport { useGetQaSpecDataHeader } from 'pages/qa-spec/query';\nimport { useGetMemberInfo } from 'hooks/useGetMemberInfo';\n\nimport userSelector from '@redux/user/selectors';\n\nconst useCheckAssignProductToSupplier = () => {\n const { id: productId } = useParams();\n\n const isMemberSupplierUser = useCheckMemberSupplier();\n const isSharedOnlyMember = useCheckSharedOnlyMyCompany();\n\n let userInfo = useSelector(userSelector.makeSelectUserInfo());\n\n const { memberInfo } = useGetMemberInfo();\n\n const isPrivateOrSupplierMember = isMemberSupplierUser || isSharedOnlyMember;\n\n const getIdCurrentMember = () => {\n if (isPrivateOrSupplierMember && !memberInfo) return userInfo?.member?.id;\n return memberInfo?.id;\n };\n\n const { qaSpecDataHeader } = useGetQaSpecDataHeader({\n id: productId,\n isEnabled: !!productId,\n });\n\n const checkAssignProductToSupplier = () => {\n const idMember = getIdCurrentMember();\n\n const isCurrentMemberAssignedToQaSpec =\n qaSpecDataHeader?.assignTo === idMember;\n\n const allowSubmitBtnStatus = ['open', 'rejected'];\n\n const isOpenOrRejected = allowSubmitBtnStatus.includes(\n qaSpecDataHeader?.status?.toLowerCase()\n );\n\n return isCurrentMemberAssignedToQaSpec && isOpenOrRejected;\n };\n\n return {\n checkAssignProductToSupplier,\n };\n};\n\nexport default useCheckAssignProductToSupplier;\n","export const getCertificateParams = (formValues) => {\n const disabledCertifier = {\n kosherCertifier: 'kosherYN',\n organicCertifier: 'organicYN',\n halalCertifier: 'halalYN',\n nonGMOCertifier: 'nonGMOYN',\n isoCertifier: 'isoyn',\n brcCertifier: 'brcyn',\n ifsCertifier: 'ifsyn',\n };\n return Object.keys(disabledCertifier).reduce((accumulator, currentKey) => {\n const checkValue = formValues[disabledCertifier[currentKey]];\n const value = formValues[currentKey];\n\n return { ...accumulator, [currentKey]: checkValue ? value : null };\n }, {});\n};\n\nexport const parsePackagingData = (data) => {\n if (data) {\n return {\n ...data,\n recyclableTypes: data?.recyclableTypes || [],\n secondaryLanguage: data?.secondaryLanguage || [],\n };\n }\n\n return {};\n};\n","import React, { useState, useContext, useMemo } from 'react';\n\nimport { sleep } from 'utils/delay';\n\nexport const QaEditTabCheckerContext = React.createContext({});\n\nexport const QaEditTabCheckerProvider = (props) => {\n const { children } = props;\n\n const [editItemList, setEditItemList] = useState(() => new Map([]));\n const [manipulateItem, setManipulateItem] = useState(null);\n\n const editItemListArray = useMemo(() => {\n return Array.from(editItemList);\n }, [editItemList]);\n\n const editItemCountByTab = useMemo(() => {\n let nextEditItemCountByTab = {};\n\n if (editItemListArray?.length > 0) {\n editItemListArray.forEach((editItem) => {\n const { tab } = editItem?.[1];\n\n if (nextEditItemCountByTab?.[tab]) {\n nextEditItemCountByTab[tab] += 1;\n } else {\n nextEditItemCountByTab[tab] = 1;\n }\n });\n }\n return nextEditItemCountByTab;\n }, [editItemListArray]);\n\n const addEditItem = (item) => {\n setEditItemList((prev) => new Map(prev).set(item?.id, item));\n };\n\n const removeEditItem = (item) => {\n setEditItemList((prev) => {\n const next = new Map(prev);\n next.delete(item?.id);\n return next;\n });\n };\n\n const forceSaveItem = async (itemId) => {\n setManipulateItem({ id: itemId, action: 'save' });\n await sleep(50);\n setManipulateItem(null);\n };\n\n const forceCancelItem = async (itemId) => {\n setManipulateItem({ id: itemId, action: 'cancel' });\n await sleep(50);\n setManipulateItem(null);\n };\n\n const forceChangeTab = async (itemId, tab) => {\n setManipulateItem({ id: itemId, tab, action: 'view' });\n await sleep(50);\n setManipulateItem(null);\n };\n\n // remove Editing Item(s) when change type\n const removeSpecialTab = (type) => {\n if (editItemListArray?.some((item) => item[0] === 'qa-components')) {\n if (type === 'Food') {\n removeEditItem({ id: 'qa-components' });\n }\n }\n if (editItemListArray?.some((item) => item[0] === 'qa-ingredient')) {\n if (type === 'HBC / OTC' || type === 'Non-Food') {\n removeEditItem({ id: 'qa-ingredient' });\n }\n }\n if (editItemListArray?.some((item) => item[0] === 'qa-fresh-meat')) {\n if (type !== 'Fresh - Meat') {\n removeEditItem({ id: 'qa-fresh-meat' });\n }\n }\n if (editItemListArray?.some((item) => item[0] === 'qa-fresh-seafood')) {\n if (type !== 'Fresh - Seafood') {\n removeEditItem({ id: 'qa-fresh-seafood' });\n }\n }\n if (\n editItemListArray?.some((item) => item[0] === 'qa-spec-fresh-produce')\n ) {\n if (type !== 'Fresh - Produce') {\n removeEditItem({ id: 'qa-spec-fresh-produce' });\n }\n }\n if (editItemListArray?.some((item) => item[0] === 'qa-spec-fresh-deli')) {\n if (type !== 'Fresh - Deli') {\n removeEditItem({ id: 'qa-spec-fresh-deli' });\n }\n }\n };\n\n return (\n \n {children && children}\n \n );\n};\n\nexport const useQaTabChecker = () => {\n const contextValue = useContext(QaEditTabCheckerContext);\n\n return contextValue;\n};\n","import React, { useEffect, useRef } from 'react';\nimport { useQaTabChecker } from './EditTabCheckerContext';\n\nconst CheckerWrapper = (props) => {\n const { isEdit, children, type = {}, hideSaveBtn = false } = props;\n\n const { id } = type;\n\n const { addEditItem, removeEditItem } = useQaTabChecker();\n\n useEffect(() => {\n const editItemInfo = {\n ...type,\n hideSaveBtn,\n };\n\n if (isEdit) {\n addEditItem(editItemInfo);\n } else {\n removeEditItem(editItemInfo);\n }\n }, [isEdit, type, hideSaveBtn]);\n\n return
{children && children}
;\n};\n\nconst SaveActionTriggerWrapper = (props) => {\n const { children, onSave, type } = props;\n\n const refManipulateItem = useRef();\n\n const { manipulateItem } = useQaTabChecker();\n\n useEffect(() => {\n const { id, action } = manipulateItem || {};\n\n if (\n manipulateItem &&\n id === type?.id &&\n action === 'save' &&\n !refManipulateItem.current\n ) {\n refManipulateItem.current = manipulateItem;\n onSave && onSave();\n }\n\n if (!manipulateItem) {\n refManipulateItem.current = null;\n }\n }, [manipulateItem, type, onSave]);\n\n return <>{children && children} ;\n};\n\nconst CancelActionTriggerWrapper = (props) => {\n const { children, onCancel, type } = props;\n\n const refManipulateItem = useRef();\n\n const { manipulateItem } = useQaTabChecker();\n\n useEffect(() => {\n const { id, action } = manipulateItem || {};\n if (\n manipulateItem &&\n id === type?.id &&\n action === 'cancel' &&\n !refManipulateItem.current\n ) {\n refManipulateItem.current = manipulateItem;\n onCancel && onCancel();\n }\n\n if (!manipulateItem) {\n refManipulateItem.current = null;\n }\n }, [manipulateItem, type, onCancel]);\n\n return <>{children && children} ;\n};\n\nconst TabCheckerWrapper = (props) => {\n const { children, onChangeTab } = props;\n\n const refManipulateItem = useRef();\n\n const { manipulateItem } = useQaTabChecker();\n\n useEffect(() => {\n const { action, tab } = manipulateItem || {};\n\n if (manipulateItem && action === 'view' && !refManipulateItem.current) {\n refManipulateItem.current = manipulateItem;\n onChangeTab && onChangeTab(tab);\n }\n\n if (!manipulateItem) {\n refManipulateItem.current = null;\n }\n }, [manipulateItem, onChangeTab]);\n\n return <>{children && children} ;\n};\n\nconst EditTabSectionWrapper = {\n CheckerWrapper,\n SaveActionTriggerWrapper,\n CancelActionTriggerWrapper,\n TabCheckerWrapper,\n};\n\nexport default EditTabSectionWrapper;\n","import React, { useState } from 'react';\nimport ReactCSS from 'reactcss';\n\nimport { Row, Col, Button, Typography, Space, Empty } from 'antd';\n\nimport {\n FormCancelButton,\n FormSaveButton,\n StyledModal,\n WithLoading,\n} from 'common/components';\n\nimport { useQaTabChecker } from './EditTabCheckerContext';\n\nimport { sleep } from 'utils/delay';\nimport { mapTabKeyToName } from './utils';\n\nconst { Text } = Typography;\n\nconst styles = ReactCSS({\n default: {\n editItem: {\n borderRadius: 4,\n boxShadow: `rgba(60, 64, 67, 0.3) 0px 1px 2px 0px,\n rgba(60, 64, 67, 0.15) 0px 1px 3px 1px`,\n padding: '4px 6px',\n marginBottom: 6,\n },\n viewBtn: {\n borderRadius: 3,\n },\n empty: {\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n },\n },\n});\n\nfunction EditTabConfirmModal(props) {\n const { onChangeTab, onCancel, tempActiveTab, ...restProps } = props;\n\n const [loading, setLoading] = useState(false);\n\n const {\n editItemListArray,\n forceSaveItem,\n forceCancelItem,\n forceChangeTab,\n } = useQaTabChecker();\n\n const focusEditItem = async (itemId, tabName) => {\n forceChangeTab(itemId, tabName);\n await sleep(200);\n const $item = document.getElementById(itemId);\n\n if ($item) {\n $item.scrollIntoView();\n }\n\n onCancel();\n };\n\n const modalProps = {\n title: 'Review Editing Item(s)',\n bodyStyle: {\n height: 255,\n },\n width: 700,\n onCancel,\n ...restProps,\n };\n\n const handleSaveEditItem = async (itemId) => {\n if (!itemId) return;\n await forceSaveItem(itemId);\n };\n\n const handleCancelEditItem = (itemId) => {\n if (!itemId) return;\n forceCancelItem(itemId);\n };\n\n const cancelEachtem = async (editItem) => {\n const { id } = editItem?.[1];\n await sleep(200);\n handleCancelEditItem(id);\n await sleep(200);\n };\n\n const onCancelAll = async () => {\n setLoading(true);\n\n for (const editItem of editItemListArray) {\n await cancelEachtem(editItem);\n }\n\n setLoading(false);\n };\n\n const footerRender = (\n
\n \n {editItemListArray?.length > 0 && (\n \n )}\n \n \n
\n );\n\n return (\n \n \n {editItemListArray?.length === 0 ? (\n \n ) : (\n <>\n {editItemListArray.map((item) => {\n const itemData = item?.[1] || {};\n const { name, id, tab } = itemData;\n\n return (\n \n \n {name}\n \n \n \n focusEditItem(id, tab)}\n >\n View\n \n {!itemData?.hideSaveBtn && (\n handleSaveEditItem(id)}\n />\n )}\n handleCancelEditItem(id)}\n />\n \n \n \n );\n })}\n \n )}\n \n \n );\n}\n\nexport default EditTabConfirmModal;\n","export const EDIT_SECTION = {\n PROD_SPEC_INFO: {\n id: 'qa-spec-product-info',\n name: 'Product Specification - Product Info',\n tab: 'product-specification',\n },\n PROD_FRESH_PRODUCE: {\n id: 'qa-spec-fresh-produce',\n name: 'Fresh - Produce',\n tab: 'fresh-produce',\n },\n PROD_FRESH_DELI: {\n id: 'qa-spec-fresh-deli',\n name: 'Fresh - Deli',\n tab: 'fresh-deli',\n },\n PROD_SPEC_ORGANOLEPTIC: {\n id: 'qa-spec-organoleptic',\n name: 'Product Specification - Organoleptic Characteristics',\n tab: 'product-specification',\n },\n PROD_SPEC_PHY_N_CHE: {\n id: 'qa-physic-n-chemical',\n name: 'Product Specification - Physical and Chemical Characteristics',\n tab: 'product-specification',\n },\n PROD_SPEC_CONTAMINANT: {\n id: 'qa-contaminent',\n name: 'Product Specification - Contaminant Characteristics',\n tab: 'product-specification',\n },\n PROD_SPEC_MICROBIOLOGICAL_CHARACTER: {\n id: 'qa-microbiological-characteristic',\n name: 'Product Specification - Microbiological Characteristics',\n tab: 'product-specification',\n },\n PROD_SPEC_DOC: {\n id: 'qa-prod-spec-document',\n name: 'Product Specification - Documents',\n tab: 'product-specification',\n },\n QA_INGREDIENT: {\n id: 'qa-ingredient',\n name: 'Ingredients',\n tab: 'ingredients',\n },\n QA_ALLERGEN: {\n id: 'qa-allergen',\n name: 'Allergens',\n tab: 'allergens',\n },\n QA_NUTRITION: {\n id: 'qa-nutrition',\n name: 'Facts Panel',\n tab: 'facts-panel',\n },\n QA_FORMULA: {\n id: 'qa-formula',\n name: 'Formula',\n tab: 'formula',\n },\n QA_MANUFACTURING_PROCESS_STAGE: {\n id: 'qa-manufacturing-process-stage',\n name: 'Manufacturing Process - Process Stage',\n tab: 'manufacturing-process',\n },\n QA_MANUFACTURING_LOCATION: {\n id: 'qa-manufacturing-location',\n name: 'Manufacturing Process - Manufacturing Location',\n tab: 'manufacturing-process',\n },\n QA_MANUFACTURING_DOCUMENT: {\n id: 'qa-manufacturing-document',\n name: 'Manufacturing Process - Documents',\n tab: 'manufacturing-process',\n },\n QA_CONTACT: {\n id: 'qa-contact',\n name: 'Contacts',\n tab: 'contacts',\n },\n QA_DOC_N_CERT_DOC: {\n id: 'qa-doc-n-cert-doc',\n name: 'Documents/ Certificates - Documents',\n tab: 'documents-certificates',\n },\n QA_DOC_N_CERT_CERT: {\n id: 'qa-doc-n-cert-cert',\n name: 'Documents/ Certificates - Certificates',\n tab: 'documents-certificates',\n },\n QA_COMPONENTS: {\n id: 'qa-components',\n name: 'Components',\n tab: 'components',\n },\n QA_FRESH_MEAT: {\n id: 'qa-fresh-meat',\n name: 'Fresh-Meat',\n tab: 'fresh-meat',\n },\n QA_FRESH_SEAFOOD: {\n id: 'qa-fresh-seafood',\n name: 'Fresh-Seafood',\n tab: 'fresh-seafood',\n },\n QA_PACKAGING: {\n id: 'qa-packaging',\n name: 'Labeling',\n tab: 'labeling',\n },\n QA_CLAIMS: {\n id: 'qa-claims',\n name: 'Claims',\n tab: 'claims',\n },\n QA_PRODUCT_CONTAINS: {\n id: 'qa-product-contains',\n name: 'Product Contains',\n tab: 'product-contains',\n },\n // QA_PET_NON_FOOD: {\n // id: 'qa-pet-non-food',\n // name: 'Pet Non Food',\n // tab: 'pet-non-food',\n // },\n QA_PET_FOOD: {\n id: 'qa-fet-food',\n name: 'Pet Food',\n tab: 'pet-food',\n },\n};\n\nexport const TAB_DEFINE = {\n 'product-specification': 'Product Specification',\n 'fresh-produce': 'Fresh - Produce',\n 'fresh-deli': 'Fresh - Deli',\n ingredients: 'Ingredients',\n allergens: 'Allergens',\n 'facts-panel': 'Facts Panel',\n formula: 'Formula',\n 'manufacturing-process': 'Manufacturing Process',\n contacts: 'Contacts',\n 'documents-certificates': 'Documents/ Certificates',\n components: 'Components',\n 'fresh-seafood': 'Fresh- Seafood',\n 'fresh-meat': 'Fresh - Meat',\n claims: 'Claims',\n labeling: 'Labeling',\n 'product-contains': 'Product Contains',\n 'pet-non-food': 'Pet Non-Food',\n 'pet-food': 'Pet Food',\n};\n","import { useState, useLayoutEffect, useRef } from 'react';\n\nconst useDetectSticky = (ref, observerSettings = { threshold: [1] }) => {\n const [isSticky, setIsSticky] = useState(false);\n const newRef = useRef();\n ref ||= newRef;\n\n useLayoutEffect(() => {\n const cachedRef = ref.current,\n observer = new IntersectionObserver(([e]) => {\n setIsSticky(e.intersectionRatio < 1);\n }, observerSettings);\n\n observer.observe(cachedRef);\n\n return () => {\n observer.unobserve(cachedRef);\n };\n }, []);\n\n return [isSticky, ref, setIsSticky];\n};\n\nexport { useDetectSticky };\n","import { useParams } from 'react-router-dom';\nimport { useGetQaSpecDataHeader } from 'pages/qa-spec/query';\n\nexport const useCheckQaSpecLocked = () => {\n const { id: productId } = useParams();\n\n const { qaSpecDataHeader } = useGetQaSpecDataHeader({\n id: productId,\n isEnabled: !!productId,\n });\n\n const checkQASpecLocked = () => {\n const unlockedStatus = ['submitted', 'approved'];\n\n return unlockedStatus.includes(qaSpecDataHeader?.status?.toLowerCase());\n };\n const isQASpecLocked = checkQASpecLocked();\n\n return {\n isQASpecLocked,\n };\n};\n","import React, {\n useState,\n useEffect,\n useImperativeHandle,\n forwardRef,\n} from 'react';\n\nimport { Typography, Button, Col, Row, Space } from 'antd';\nimport { EditOutlined } from '@ant-design/icons';\n\nimport { FormCancelButton, FormSaveButton } from 'common/components';\nimport { useCheckAllowEdit } from 'pages/qa-spec/hooks';\nimport { EditTabSectionWrapper } from 'pages/qa-spec/components/edit-tab-checker';\n\nimport { useDetectSticky } from 'hooks/useComponent';\nimport classnames from 'classnames';\n\nimport './EditContainer.less';\nimport { useCheckQaSpecLocked } from 'pages/qa-spec/hooks/useCheckQaSpecLocked';\n\nconst { Title } = Typography;\n\nconst EditContainer = (props, ref) => {\n const {\n title,\n children,\n buttons,\n extraButtons,\n allowEdit = true,\n handleCancel,\n handleSave,\n showSaveButton = true,\n showCancelButton = true,\n showEditButton = true,\n type,\n float = false,\n saveLoading = false,\n productId,\n editHook,\n onEditChange,\n } = props;\n\n const [isEdit, setIsEdit] = useState(false);\n const [isEditProps, setIsEditProps] = editHook || [];\n const editState = editHook ? isEditProps : isEdit;\n\n const handleSetEditState = (value) => {\n if (editHook) {\n setIsEditProps(value);\n return;\n }\n\n setIsEdit(value);\n };\n\n const [isSticky, refSticky] = useDetectSticky();\n\n const toggleEditMode = () => {\n handleSetEditState((prev) => !prev);\n };\n\n const onCancel = () => {\n toggleEditMode();\n handleCancel && handleCancel();\n };\n\n const onSave = () => {\n handleSave(toggleEditMode);\n };\n\n const hasPermissionEdit = useCheckAllowEdit(productId);\n\n const { isQASpecLocked } = useCheckQaSpecLocked();\n\n useEffect(() => {\n onEditChange && onEditChange(isEdit);\n }, [isEdit]);\n\n useImperativeHandle(ref, () => {\n return { onToggleEditMode: toggleEditMode };\n });\n\n return (\n
\n \n \n {title && (\n \n {title}\n \n )}\n \n\n \n \n \n {!isQASpecLocked ? (\n \n {editState && (\n <>\n {buttons?.map((buttonItem, idx) => (\n {buttonItem}\n ))}\n \n )}\n {editState && showSaveButton && (\n \n \n \n )}\n\n {showEditButton &&\n !editState &&\n allowEdit &&\n hasPermissionEdit && (\n }\n onClick={toggleEditMode}\n style={{ border: 'none' }}\n />\n )}\n\n {editState && showCancelButton && (\n \n \n \n )}\n\n {extraButtons?.map((buttonItem, idx) => (\n \n {buttonItem(editState)}\n \n ))}\n \n ) : null}\n
\n \n \n \n {children && children(editState)}\n \n \n );\n};\n\nexport default forwardRef(EditContainer);\n","import { AT_LEAST_ONE_ENTRY_GROUPS } from './hooks';\nimport { requiredFieldsMap } from 'pages/qa-spec/hooks/useGetQaSpecRequiredFields';\n\nexport const filterRequiredFieldsGroupData = ({\n groupsData,\n requiredFields,\n}) => {\n if (!groupsData) return [];\n if (!requiredFields) return [];\n\n return groupsData.reduce((accumulator, currentGroupData) => {\n const isAtLeastOneEntry = AT_LEAST_ONE_ENTRY_GROUPS.includes(\n currentGroupData.groupName\n );\n\n const fieldsData = filterRequiredFieldsOfGroup({\n requiredFields,\n fields: currentGroupData.fields,\n });\n\n const childGroupData =\n currentGroupData.childGroups?.length > 0\n ? filterRequiredFieldsGroupData({\n requiredFields,\n groupsData: currentGroupData.childGroups,\n })\n : [];\n\n const hasContent = fieldsData.length || childGroupData.length;\n\n //* if group does not have any field or child group, do not add to list\n return hasContent\n ? [\n ...accumulator,\n {\n ...currentGroupData,\n tooltip: isAtLeastOneEntry ? 'At least one entry' : null,\n fields: fieldsData,\n childGroups: childGroupData,\n },\n ]\n : accumulator;\n }, []);\n};\n\nconst filterRequiredFieldsOfGroup = ({ requiredFields, fields }) => {\n if (!fields) return [];\n\n const filteredFields = fields.reduce((accumulator, currentFieldItem) => {\n const standardFieldFullPath =\n requiredFieldsMap[currentFieldItem.fieldFullPath] ||\n currentFieldItem.fieldFullPath;\n\n const isRequired = requiredFields.includes(standardFieldFullPath);\n\n if (isRequired) {\n return [\n ...accumulator,\n { ...currentFieldItem, fieldFullPath: standardFieldFullPath },\n ];\n }\n\n return accumulator;\n }, []);\n\n return filteredFields;\n};\n\nexport const getGroupRequiredFields = ({ groupRequiredFields, groupName }) => {\n return groupRequiredFields.find((groupItem) => {\n return groupItem.groupName === groupName;\n });\n};\n","import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';\nimport { CustomNotification } from 'common/components';\nimport { saveQaSpecProductContain } from 'services/product';\nimport * as productServices from 'services/product';\nimport { forwardTo } from 'utils/common/route';\n\nexport const getQaContainTabDataQueryKey = (productId) => {\n return ['qa-spec', parseInt(productId), 'qa-spec-data-product-contains'];\n};\n\nexport const useGetQaProductContainTabData = ({ productId }, options) => {\n return useQuery({\n queryKey: getQaContainTabDataQueryKey(productId),\n queryFn: async () => {\n const response = await productServices.getProductContain({\n productId,\n });\n if (response?.isSuccess) {\n return response?.data;\n } else {\n CustomNotification.error(response?.message ?? 'Something went wrong!');\n forwardTo('/products');\n }\n },\n ...options,\n });\n};\n\nexport const useSaveQaProductContainTab = () => {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ productId, formData }) => {\n const params = { productId, ...formData };\n const response = await saveQaSpecProductContain(params);\n const { isSuccess, data, message } = response || {};\n\n if (isSuccess) {\n return Promise.resolve(data);\n } else if (message) {\n return Promise.reject(message);\n }\n },\n onSuccess: (data, { productId }) => {\n queryClient.invalidateQueries({\n queryKey: getQaContainTabDataQueryKey(productId),\n });\n CustomNotification.success('Update Product Contain data successfully!');\n },\n onError: (error) => {\n CustomNotification.error('Save Fail');\n },\n });\n};\n","import { Col, Popover, Row, Tooltip, Typography } from 'antd';\n\nimport {\n CheckOutlined,\n CloseOutlined,\n QuestionCircleTwoTone,\n QuestionCircleOutlined,\n} from '@ant-design/icons';\n\nimport { useRequiredFieldsValidation } from './hooks';\n\nimport { FullWidthSpace } from 'common/components';\n\nimport useCheckAssignProductToSupplier from 'pages/qa-spec/hooks/useCheckAssignProductToSupplier';\n\nimport { useGetQaSpecRequiredFieldsInQaSpecFullView } from 'pages/qa-spec/hooks/useGetQaSpecRequiredFields';\n\nexport const RequiredFieldsError = ({ productId, children }) => {\n const { checkAssignProductToSupplier } = useCheckAssignProductToSupplier();\n const isProductAssignedByRetailer = checkAssignProductToSupplier();\n\n const { data: requiredFields } = useGetQaSpecRequiredFieldsInQaSpecFullView({\n productId,\n });\n\n const { isAllFieldsValid } = useRequiredFieldsValidation(productId);\n\n const shouldShowValidateIcon =\n isProductAssignedByRetailer && requiredFields?.length > 0;\n\n return shouldShowValidateIcon ? (\n }\n trigger='hover'\n >\n
\n \n {children}\n
\n \n ) : null;\n};\n\nconst RequiredFieldsContent = ({ productId }) => {\n const { checkValidRequiredField, groupRequiredFields } =\n useRequiredFieldsValidation(productId);\n\n return (\n \n {groupRequiredFields.map((groupItem, index) => {\n return (\n \n );\n })}\n \n );\n};\n\nconst ErrorGroup = ({ type, groupItem, checkValidRequiredField }) => {\n const headerExtra = groupItem.tooltip ? (\n \n \n \n ) : null;\n\n return (\n \n {groupItem?.fields?.map((field) => {\n const isValidField = checkValidRequiredField({\n field,\n });\n const label = field.displayName;\n\n const icon = isValidField\n ? iconMessage['success']\n : iconMessage['error'];\n\n return {icon};\n })}\n {groupItem?.childGroups?.length > 0 ? (\n \n {groupItem?.childGroups?.map((groupItem, index) => {\n return (\n \n );\n })}\n \n ) : null}\n \n );\n};\n\nconst iconMessage = {\n error: ,\n success: ,\n};\n\nconst ErrorLayout = ({ header, type, headerExtra, children, ...rest }) => {\n return (\n
\n \n \n \n {header}\n \n \n\n {headerExtra ? headerExtra : null}\n \n\n
\n {children}\n
\n
\n );\n};\n\nconst ErrorItem = ({ label, children, flexIcon, ...rest }) => {\n return (\n \n \n {label}\n \n {children}\n \n );\n};\n","import React, { useState, useRef, useEffect } from 'react';\n\nimport { Tabs, Space, Popover } from 'antd';\n// import { dialogFunction } from 'common/components';\nimport { dialogFunction } from 'common/components';\n\nimport QaSpecTabHeader from './QaSpecTabHeader';\nimport ExpandTabButton from './ExpandTabButton';\nimport DownloadSpecButton from './DownloadSpecButton';\nimport LoadTestResultButton from './LoadTestResultButton';\nimport { RequiredFieldsError } from '../qa-spec-header-form/RequiredFieldsError';\n\nimport { useResize } from 'hooks/useResize';\nimport { useTabExpand } from 'hooks/useTabExpandProduct';\n\nimport { useCheckAllowEdit } from 'pages/qa-spec/hooks';\nimport { useBlockRouteChange } from 'hooks/router/block-routing';\nimport {\n useQaTabChecker,\n EditTabSectionWrapper,\n EditTabConfirmModal,\n} from 'pages/qa-spec/components/edit-tab-checker';\n\nimport { forwardTo } from 'utils/common/route';\n\nimport './QaSpecTab.less';\nimport { useCheckQaSpecLocked } from 'pages/qa-spec/hooks/useCheckQaSpecLocked';\nimport {\n CONTAINER_EXPANDED_WIDTH,\n CONTAINER_COLLAPSED_WIDTH,\n} from 'pages/qa-spec/constant';\n\nconst { TabPane } = Tabs;\n\nconst QaSpecTab = (props) => {\n const { productId, productHeaderImageSize, tabList = [] } = props;\n\n const { toggleTabExpand, isTabExpanded } = useTabExpand();\n const [activeTab, setActiveTab] = useState('product-specification');\n const [showEditTabConfirmModal, setShowEditTabConfirmModal] = useState();\n const tempActiveTab = useRef();\n const tabContainerRef = useRef();\n\n const [containerWidth] = useResize(tabContainerRef.current);\n const { editItemListArray } = useQaTabChecker();\n\n const { isQASpecLocked } = useCheckQaSpecLocked();\n\n const toggleEditTabConfirmModal = () => {\n setShowEditTabConfirmModal((prev) => !prev);\n };\n\n const handleChangeActiveTab = (activeKey) => {\n tempActiveTab.current = activeKey;\n if (editItemListArray?.length > 0) {\n toggleEditTabConfirmModal();\n } else {\n setActiveTab(activeKey);\n }\n };\n\n const onChangeTab = () => {\n setShowEditTabConfirmModal(false);\n setActiveTab(tempActiveTab.current);\n };\n\n const isAllowEditQaSpec = useCheckAllowEdit(productId);\n\n const checkActiveTab = () =>\n tabList?.some((item) => item?.key === activeTab && !!item?.visible);\n const hasActiveTab = checkActiveTab();\n\n useEffect(() => {\n if (!hasActiveTab) setActiveTab('product-specification');\n }, [hasActiveTab]);\n\n const {\n nextUrl,\n isShowModal: isShowWarningModal,\n onConfirmRouting,\n onCancleRouting,\n watchRoutingConfirm,\n } = useBlockRouteChange({\n isPreventRouting: editItemListArray?.length > 0,\n });\n\n useEffect(() => {\n if (isShowWarningModal) {\n const checkAllBlockedUrl = async () => {\n const confirmYes = await watchRoutingConfirm();\n\n if (nextUrl && confirmYes) {\n forwardTo(nextUrl);\n }\n };\n\n const handleClickOk = async () => {\n onConfirmRouting();\n checkAllBlockedUrl();\n };\n\n dialogFunction({\n type: 'warn',\n content: `Are you sure you want to leave without saving your changes?`,\n onCancel: () => {\n onCancleRouting();\n },\n onOk: handleClickOk,\n });\n }\n }, [\n isShowWarningModal,\n nextUrl,\n onConfirmRouting,\n onCancleRouting,\n watchRoutingConfirm,\n ]);\n\n const extraContent = (\n \n \n\n {!isQASpecLocked ? (\n <>{isAllowEditQaSpec ? : null}\n ) : null}\n\n \n\n \n \n );\n\n const checkShowTabActionPopover = () => {\n if (!containerWidth) return false;\n\n //* when expanded\n if (isTabExpanded) return containerWidth <= CONTAINER_EXPANDED_WIDTH;\n\n //* when not expanded\n return containerWidth <= CONTAINER_COLLAPSED_WIDTH;\n };\n\n const extraPopoverVisible = checkShowTabActionPopover();\n\n return (\n \n
\n
\n {containerWidth && !extraPopoverVisible ? extraContent : null}\n
\n\n \n \n {tabList.map((tabItem, idx) => {\n const { key, icon, des, content, visible } = tabItem;\n const isTabActive = key === activeTab;\n\n return visible ? (\n \n }\n key={key}\n style={{ padding: 8 }}\n >\n {content(isTabActive)}\n \n ) : null;\n })}\n \n \n \n
\n \n );\n};\n\nexport default QaSpecTab;\n","export const REQUIRED_FIELDS_QA_INGREDIENT = {\n ingredientStatements: {\n message: 'Ingredient Statement is required',\n label: 'Ingredient Statement',\n },\n nameOfIngredients: {\n message: 'Name Of Ingredients is required',\n label: 'Name',\n },\n countryOfOrigin: {\n message: 'Country Of Origin is required',\n label: 'Country Of Origin',\n },\n bioengineered: {\n message: 'Bioengineered is required',\n label: 'Bioengineered',\n },\n gmo: {\n message: 'GMO is required',\n label: 'GMO',\n },\n};\n","import { getAllRows } from 'pages/qa-spec/utils';\nimport { REQUIRED_FIELDS_QA_INGREDIENT } from './requiredFieldsQaIngredient';\n\nexport const coverIngredientStatementsData = ({\n data,\n currentIngredient,\n ingredientStatementValue,\n}) => {\n let ingredientStatements = [];\n if (currentIngredient?.index !== null) {\n ingredientStatements = data?.ingredientStatements?.map((item) => {\n if (currentIngredient?.index === item?.index)\n return {\n ...currentIngredient,\n ingredients: ingredientStatementValue,\n };\n return item;\n });\n } else {\n const defaultIngredientStatements = data?.ingredientStatements ?? [];\n\n ingredientStatements = [\n ...defaultIngredientStatements,\n {\n ...currentIngredient,\n ingredients: ingredientStatementValue,\n },\n ];\n }\n return ingredientStatements;\n};\n\nexport const createIngredientParams = ({ formInst, gridInst }) => {\n const { ingredientClaims } = formInst.getFieldsValue();\n const ingredientListForm = getAllRows(gridInst).map((ingredientItem) => {\n // ingredientsPartOf != null\n if (ingredientItem?.isChild) {\n const [value, parentId] = ingredientItem?.ingredientsPartOf?.split('.');\n return {\n ...ingredientItem,\n ingredientsPartOf: value,\n ingredientsPartOfId: parentId,\n digitalAssetId: ingredientItem?.documents?.digitalAssetId,\n };\n }\n return {\n ...ingredientItem,\n ingredientsPartOfId: null,\n digitalAssetId: ingredientItem?.documents?.digitalAssetId,\n };\n });\n\n const submitValue = {\n ingredientClaims,\n ingredients: ingredientListForm,\n };\n return submitValue;\n};\n\nexport const errorRequiredFieldsForSupplier = [\n REQUIRED_FIELDS_QA_INGREDIENT.nameOfIngredients.message,\n REQUIRED_FIELDS_QA_INGREDIENT.countryOfOrigin.message,\n REQUIRED_FIELDS_QA_INGREDIENT.gmo.message,\n REQUIRED_FIELDS_QA_INGREDIENT.bioengineered.message,\n];\n","import React from 'react';\n\nimport { Tooltip, Typography } from 'antd';\n\nimport './QaGridCell.less';\n\nconst TextRender = (props) => {\n const { value } = props;\n\n return (\n
\n \n \n {value}\n \n \n
\n );\n};\n\nexport default TextRender;\n","import { Popover } from 'antd';\n\nconst SnapshotCellWrapper = (props) => {\n const { children, snapshotValueRender, isHighlightChange } = props;\n\n return (\n \n \n
\n {children && children}\n
\n {isHighlightChange && (\n \n \n \n \n \n )}\n \n \n );\n};\n\nconst OriginValuePopover = (props) => {\n const { snapshotValueRender, children } = props;\n\n return (\n \n {children && children}\n \n );\n};\n\nexport default SnapshotCellWrapper;\n","import React from 'react';\n\nimport SnapshotCellWrapper from './SnapshotCellWrapper';\nimport TextRender from './TextRender';\nimport { formatCompareValue } from 'pages/qa-spec/utils';\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\n\nimport { isEqual } from 'lodash';\n\nconst TextRenderSnapshot = (props) => {\n const { isHighlightChange, snapshotValueRender, ...params } = props;\n\n const { column, rowIndex, data, context } = params;\n\n const { snapshotGridValues } = context || {};\n\n const useSnapshot = useCheckSnapshotForRetailer();\n\n const cellSnapshotValue = formatCompareValue(\n snapshotGridValues?.[rowIndex]?.[column.colId]\n );\n\n const rawCellValue = formatCompareValue(data?.[column.colId]);\n\n const defaultSnapshotValueRender = cellSnapshotValue;\n\n const defaultIsHighlightChange =\n !isEqual(`${rawCellValue}`, `${cellSnapshotValue}`) && useSnapshot;\n\n return (\n \n \n \n );\n};\n\nexport default TextRenderSnapshot;\n","import TextRender from '../components/qa-grid-cell/TextRender';\n\nimport {\n QA_ALLERGENS_COLUMNS,\n QA_INGREDIENT_COLUMNS,\n customWidthFormulaColumns,\n QA_FORMULA_COLUMNS,\n QA_FORMULA_ACTIVE_INGREDIENT_COLUMNS,\n INGREDIENT_LIMIT_CHARACTERS,\n} from 'pages/qa-spec/constant';\n\nimport * as productEndpoints from 'services/product/endpoints';\n\nimport { Typography } from 'antd';\n\nimport { QA_SPEC_DOCUMENT_FILE_TYPE } from 'pages/qa-spec/constant';\nimport { getAllRows } from './index';\n\nimport sortByKey from 'utils/sortByKey';\nimport { transformValueIngredientsPartOf } from './ingredient';\nimport TextRenderSnapshot from '../components/qa-grid-cell/TextRenderSnapshot';\n\nconst { Text } = Typography;\n\nconst minWidthSetting = {\n minWidth: 200,\n};\n\nlet initColSetting = {\n ...minWidthSetting,\n type: 'editableColumn',\n};\n\nconst SELECTION_RENDER_CONFIG = {\n valueGetter: (options, fieldName) => {\n return (params) => {\n const value = params.data?.[fieldName];\n\n const formatValue = options[fieldName]?.find(\n (option) => option.enumDisplayName === value\n )?.enumDisplayName;\n\n return formatValue;\n };\n },\n params: {\n mapValue: (value) => {\n if (value === 'null' || value === undefined) {\n return null;\n } else {\n return value;\n }\n },\n values: (options, fieldName, config = { sort: false }) => {\n const { sort } = config;\n\n const nextOptions = options[fieldName].map((option) => ({\n value: option.enumDisplayName,\n displayName: option.enumDisplayName,\n }));\n\n if (sort) {\n return sortByKey(nextOptions, 'displayName');\n }\n\n return nextOptions;\n },\n },\n};\n\nconst TEXT_RENDER_CONFIG = {\n params: { maxLength: (maxLength) => maxLength },\n};\n\nconst CUSTOM_CONFIG = {\n percentInFinalProduct: {\n minWidth: 250,\n },\n percentAddedOnProduction: {\n minWidth: 250,\n },\n};\n\nconst getCustomConfig = (fieldName) => {\n if (CUSTOM_CONFIG?.[fieldName]) {\n return CUSTOM_CONFIG;\n } else {\n return {};\n }\n};\n\n/**\n * ? create ingredient col def\n * @param {*} isEdit\n * @param {*} ingredientOptions\n * @returns\n */\n\nconst createIngredientColDef = (\n isEdit,\n ingredientOptions = {},\n productOwnerId,\n productId,\n _isToggleSnapshot\n) => {\n const isToggleSnapshot = !isEdit && _isToggleSnapshot;\n\n let columns = QA_INGREDIENT_COLUMNS.columns;\n if (!columns || columns?.length === 0) return [];\n\n let nextCols = columns.map((fieldItem) => {\n const { field } = fieldItem || {};\n let col = {};\n\n if (\n ['nameOfIngredients', 'function', 'percentAddedOnProduction'].includes(\n field\n )\n ) {\n col = {\n cellEditorSelector: (params) => {\n return {\n component: 'TextEditor',\n params: {\n maxLength: TEXT_RENDER_CONFIG.params.maxLength(\n INGREDIENT_LIMIT_CHARACTERS[field]\n ),\n showCount: true,\n },\n popup: true,\n };\n },\n ...getCustomConfig(field),\n cellRenderer: isToggleSnapshot ? 'TextRenderSnapshot' : 'TextRender',\n };\n }\n\n if (field === 'documents') {\n col = {\n minWidth: 350,\n cellRenderer: isToggleSnapshot\n ? 'FileUploadRenderSnapshot'\n : 'FileUploadRender',\n\n cellEditorSelector: (params) => {\n return {\n component: 'FileUploadEditor',\n params: {\n values: ingredientOptions.origin.map((ingredientItem) => ({\n value: ingredientItem.enumDisplayName,\n displayName: ingredientItem.enumDisplayName,\n })),\n apiUrl: productEndpoints.UPLOAD_PIM_ASSET,\n additionalBodyPayload: async () => {\n const additionalBodyPayload = {\n assetType: 'Document',\n assetSubType: 'General',\n OwnerId: productOwnerId,\n productId,\n };\n\n return additionalBodyPayload;\n },\n supportTypes: QA_SPEC_DOCUMENT_FILE_TYPE,\n confirmDeleteMessage: 'Are you sure you want to delete the file?',\n },\n\n popup: true,\n };\n },\n };\n }\n\n if (field === 'ingredientsPartOf') {\n col = {\n minWidth: 200,\n\n cellEditorSelector: (params) => {\n const options = getValueOptionsIngredientsPartsOf(params);\n\n return {\n component: 'SelectionEditor',\n params: {\n values: options.map((optionItem) => ({\n value: optionItem?.value,\n displayName:\n optionItem?.displayName === null\n ? ''\n : optionItem?.displayName,\n })),\n mapValue: SELECTION_RENDER_CONFIG.params.mapValue,\n },\n\n popup: true,\n };\n },\n cellRenderer: (params) => {\n const options = getValueOptionsIngredientsPartsOf(params);\n\n const value =\n options?.find((option) => option?.value === params?.value)\n ?.displayName ?? '';\n\n if (isToggleSnapshot) {\n const { column, rowIndex, context } = params;\n\n const { snapshotGridValues } = context || {};\n\n const cellSnapshotIngredientsPartOf =\n snapshotGridValues?.[rowIndex]?.[column.colId];\n\n // remove uuid from ingredientPartOf (\"result.uuid\")\n const filteredIngredientsPartOf = cellSnapshotIngredientsPartOf\n ? cellSnapshotIngredientsPartOf?.split('.')?.[0]\n : 'N/A';\n\n return (\n \n );\n }\n\n return ;\n },\n };\n }\n\n if (field === 'countryOfOrigin') {\n col = {\n minWidth: 300,\n cellRenderer: isToggleSnapshot\n ? 'CountryEditorRenderSnapshot'\n : 'CountryEditorRender',\n\n cellEditorSelector: (params) => {\n return {\n component: 'CountryEditor',\n popup: true,\n };\n },\n };\n }\n\n if (\n [\n 'ionized',\n 'allergens',\n 'gmo',\n 'religiousClaim',\n 'origin',\n 'bioengineered',\n ].includes(field)\n ) {\n col = {\n minWidth: 200,\n valueGetter: SELECTION_RENDER_CONFIG.valueGetter(\n ingredientOptions,\n field\n ),\n\n cellEditorSelector: (params) => {\n return {\n component: 'SelectionEditor',\n params: {\n values: SELECTION_RENDER_CONFIG.params.values(\n ingredientOptions,\n field,\n { sort: ['origin'].includes(field) ? true : false }\n ),\n mapValue: SELECTION_RENDER_CONFIG.params.mapValue,\n },\n popup: true,\n };\n },\n cellRenderer: isToggleSnapshot ? 'TextRenderSnapshot' : 'TextRender',\n };\n }\n\n if (field === 'percentInFinalProduct') {\n col = {\n minWidth: 250,\n\n cellEditorSelector: (params) => {\n return {\n component: 'NumericEditor',\n params: {\n max: INGREDIENT_LIMIT_CHARACTERS.percentInFinalProduct,\n min: 0,\n },\n popup: true,\n };\n },\n cellRenderer: isToggleSnapshot ? 'TextRenderSnapshot' : 'TextRender',\n };\n }\n\n if (field === 'ingredientSupplier') {\n col = {\n cellRenderer: isToggleSnapshot ? 'TextRenderSnapshot' : 'TextRender',\n };\n }\n\n col = {\n ...initColSetting,\n ...fieldItem,\n ...col,\n };\n\n return col;\n });\n\n //* add hierachy level idx\n\n const statusField = {\n ...minWidthSetting,\n field: 'error',\n displayName: 'Edit status',\n minWidth: 120,\n cellRenderer: 'StatusRender',\n };\n\n nextCols = [\n {\n ...minWidthSetting,\n field: 'levelIdx',\n displayName: 'Level',\n minWidth: 120,\n valueGetter: function (params) {\n const value = params.data?.levelIdx;\n return (\n \n {value}\n \n );\n },\n },\n ...nextCols,\n ];\n\n if (isEdit) {\n nextCols = [statusField, ...nextCols];\n }\n\n return nextCols;\n};\n\n/**\n * ? create allergen col default\n * @param {*} isEdit\n * @param {*} ingredientOptions\n * @returns\n */\n\nconst createAllergenColDef = (isEdit, options = {}, _isToggleSnapshot) => {\n const isToggleSnapshot = !isEdit && _isToggleSnapshot;\n\n let columns = QA_ALLERGENS_COLUMNS.columns;\n if (!columns || columns?.length === 0) return [];\n\n let nextCols = columns.map((fieldItem) => {\n const { field } = fieldItem || {};\n let col = {};\n\n if (field === 'isPresent') {\n col = {\n maxWidth: 120,\n cellRenderer: 'CheckboxRender',\n\n cellEditorSelector: (params) => {\n return {\n component: 'CheckboxEditor',\n popup: true,\n };\n },\n };\n }\n\n if (field === 'levelOfContainment') {\n col = {\n minWidth: 200,\n\n valueGetter: SELECTION_RENDER_CONFIG.valueGetter(options, field),\n\n cellEditorSelector: (params) => {\n return {\n component: 'SelectionEditor',\n params: {\n values: SELECTION_RENDER_CONFIG.params.values(options, field, {\n sort: true,\n }),\n disabled: params.data.isPresent === false,\n mapValue: SELECTION_RENDER_CONFIG.params.mapValue,\n },\n popup: true,\n };\n },\n cellRenderer: isToggleSnapshot ? 'TextRenderSnapshot' : 'TextRender',\n };\n }\n\n if (field === 'containmentSource') {\n col = {\n minWidth: 200,\n\n cellEditorSelector: (params) => {\n return {\n component: 'SelectionEditor',\n params: {\n values: SELECTION_RENDER_CONFIG.params.values(options, field, {\n sort: true,\n }),\n disabled: params.data.levelOfContainment !== 'May Contain',\n mapValue: SELECTION_RENDER_CONFIG.mapValue,\n },\n popup: true,\n };\n },\n cellRenderer: isToggleSnapshot ? 'TextRenderSnapshot' : 'TextRender',\n };\n }\n\n col = { ...initColSetting, ...fieldItem, ...col };\n\n return col;\n });\n\n const statusField = {\n ...minWidthSetting,\n field: 'error',\n displayName: 'Edit status',\n minWidth: 120,\n maxWidth: 120,\n cellRenderer: 'StatusRender',\n };\n\n if (isEdit) {\n nextCols = [statusField, ...nextCols];\n }\n\n return nextCols;\n};\n\nconst createFormulaColDef = ({\n productEnums,\n productOwnerId,\n productId,\n options,\n}) => {\n let columns = QA_FORMULA_COLUMNS({\n productEnums,\n productOwnerId,\n productId,\n options,\n }).columns;\n if (!columns || columns?.length === 0) return [];\n\n let initColSetting = {\n type: 'editableColumn',\n };\n\n let nextCols = columns.map((fieldItem) => {\n const DEFAULT_WIDTH = 200;\n\n return {\n ...initColSetting,\n ...fieldItem,\n minWidth: customWidthFormulaColumns[fieldItem?.field] ?? DEFAULT_WIDTH,\n };\n });\n\n return nextCols;\n};\n\nconst createFormulaActiveIngredientColDef = (options = {}) => {\n let columns = QA_FORMULA_ACTIVE_INGREDIENT_COLUMNS(options).columns;\n if (!columns || columns?.length === 0) return [];\n\n let initColSetting = {\n type: 'editableColumn',\n };\n\n let nextCols = columns.map((fieldItem) => {\n return {\n ...initColSetting,\n ...fieldItem,\n };\n });\n\n return nextCols;\n};\n\nconst createTextEditorRenderer =\n (maxLength = 150) =>\n () => {\n return {\n component: 'TextEditor',\n popup: true,\n params: {\n maxLength: maxLength,\n },\n };\n };\n\nconst createNumericEditorRenderer =\n ({ max, min }) =>\n () => {\n return {\n component: 'NumericEditor',\n popup: true,\n params: {\n max,\n min,\n },\n };\n };\n\nconst createSelectionEditorRenderer = (selectionParams) => () => {\n return {\n popup: true,\n component: 'SelectionEditor',\n params: {\n mapValue: (value) => {\n if (value === 'null' || value === undefined) {\n return null;\n } else {\n return value;\n }\n },\n ...selectionParams,\n },\n };\n};\n\nconst getValueOptionsIngredientsPartsOf = (params) => {\n const allRowData = getAllRows({ current: params });\n\n const options = allRowData\n ?.map((itemData) => {\n return {\n id: itemData.id,\n value: transformValueIngredientsPartOf(itemData),\n nameOfIngredients: itemData?.nameOfIngredients,\n displayName: `${itemData?.nameOfIngredients} - Level ${itemData?.levelIdx}`,\n };\n })\n .filter(\n (optionItem) =>\n optionItem?.nameOfIngredients && optionItem?.id !== params?.data?.id\n );\n\n return options;\n};\n\nexport {\n createIngredientColDef,\n createAllergenColDef,\n createFormulaColDef,\n createTextEditorRenderer,\n createNumericEditorRenderer,\n createSelectionEditorRenderer,\n createFormulaActiveIngredientColDef,\n};\n","import React, { useEffect, useMemo, useState, useRef } from 'react';\nimport { useParams } from 'react-router-dom';\nimport classnames from 'classnames';\nimport { Typography, Row, Col, Input } from 'antd';\n\nimport { WithQaGridHeader } from 'pages/qa-spec/components';\nimport {\n Form,\n FormAddButton,\n FormDeleteButton,\n CustomNotification,\n WithLoading,\n StyledModal,\n} from 'common/components';\n\nimport { sleep } from 'utils/delay';\nimport { useMutationIngredients } from './hook';\nimport { useGetEnumOptions } from 'pages/qa-spec/hooks';\nimport { coverIngredientStatementsData, createIngredientParams } from './utils';\nimport { useTabExpand } from 'hooks/useTabExpandProduct';\n\nimport { useGetIngredientGridHandlers } from 'pages/qa-spec/hooks/useIngredient';\nimport {\n validateIngredientGrid,\n getIngredientPercentTotal,\n validateWholeIngredientGrid,\n mappingInitialIngredientList,\n} from 'pages/qa-spec/utils/ingredient';\n\nimport { INGREDIENT_LIMIT_CHARACTERS } from 'pages/qa-spec/constant';\nimport { useReloadDocumentCertificateTab } from 'hooks/useReloadDocumentCertificateTab';\nimport { useSyncProductModules } from 'pages/product-full-view/components/product-new-detail-view/hooks';\nimport { useGetQaSpecRequiredFieldsInQaSpecFullView } from 'pages/qa-spec/hooks/useGetQaSpecRequiredFields';\nimport QaIngredientGrid from './QaIngredientGrid';\n\nimport { changeBreakout } from 'pages/product-full-view/components/product-media-area/multiple-panel/tab-ingredients/utils';\n\nimport useCheckAssignProductToSupplier from 'pages/qa-spec/hooks/useCheckAssignProductToSupplier';\nimport { REQUIRED_FIELDS_QA_INGREDIENT } from './requiredFieldsQaIngredient';\n\nimport './QaSpecIngredient.less';\nimport {\n IXONECertificationWrapper,\n TYPE_VIEW,\n} from 'common/components/product-add/IXONECertificationWrapper';\nimport useUpdateIXONEShield from 'common/components/product-add/useUpdateIXONEShield';\n\nconst { Title, Text } = Typography;\n\nconst IngredientForm = ({ visible, setVisible, ingredientsMode, data }) => {\n const { id: productId } = useParams();\n const [total, setTotal] = useState(0);\n const [selectedRows, setSelectedRows] = useState([]);\n\n const gridInst = useRef();\n const [formInst] = Form.useForm();\n const { tableStyle } = useTabExpand();\n\n const { checkAssignProductToSupplier } = useCheckAssignProductToSupplier();\n const isProductAssignedByRetailer = checkAssignProductToSupplier();\n\n const { reloadDocumentCertificateTab } = useReloadDocumentCertificateTab();\n\n const { handleSyncIngredients } = useSyncProductModules();\n const { mutation } = useMutationIngredients({ productId });\n\n const { data: requiredFields } = useGetQaSpecRequiredFieldsInQaSpecFullView({\n productId,\n });\n const { handleUpdateIXONEShield } = useUpdateIXONEShield();\n\n const isRequiredFieldForSupplier = Boolean(isProductAssignedByRetailer);\n\n const ingredientData = useMemo(() => {\n const total = getIngredientPercentTotal(data?.ingredients || []);\n setTotal(total);\n\n return {\n ingredientList: mappingInitialIngredientList(data?.ingredients) || [],\n ingredientForm: {\n ingredientStatement: data?.currentIngredient?.ingredients,\n ingredientClaims: data?.ingredientClaims,\n },\n };\n }, [data]);\n\n const ingredientOptions = useGetEnumOptions()?.ingredient;\n\n const {\n gridRequiredFields,\n getRequiredFieldsMessage,\n onCellEditingStopped,\n handleAddChildIngredient,\n handleAddIngredient,\n handleDeleteIngredient,\n } = useGetIngredientGridHandlers(gridInst, setTotal, productId);\n\n const checkFieldRequired = (fieldName) => {\n if (!requiredFields) return false;\n\n if (!isRequiredFieldForSupplier) return false;\n\n return requiredFields.includes(\n `qaSpecification.qaSpecIngredients.${fieldName}`\n );\n };\n\n const onGridReady = (params) => {\n getRequiredFieldsMessage();\n };\n\n const onRowSelected = () => {\n const selectedRows = gridInst.current.api.getSelectedNodes();\n setSelectedRows(selectedRows);\n };\n\n const handleCancel = async () => {\n setVisible(false);\n };\n\n const handleCreateParams = () => {\n const { ingredientStatement } = formInst.getFieldsValue();\n\n const ingredientStatements = coverIngredientStatementsData({\n data,\n currentIngredient: data?.currentIngredient,\n ingredientStatementValue: changeBreakout(ingredientStatement),\n });\n\n const submitValue = createIngredientParams({ formInst, gridInst });\n\n const params = {\n productId,\n ...submitValue,\n ingredientStatements: ingredientStatements || [\n ...data?.ingredientStatements,\n ],\n };\n\n return params;\n };\n\n const handleSave = async (ixoneIgnore) => {\n gridInst.current.api.stopEditing();\n\n await formInst.validateFields();\n\n await sleep(300);\n\n setSelectedRows([]);\n validateWholeIngredientGrid(gridInst, isProductAssignedByRetailer);\n const params = handleCreateParams();\n\n if (\n isRequiredSomeFieldsIngredientGrid &&\n params?.ingredients?.length <= 0\n ) {\n CustomNotification.error('Please add at least one row data to save');\n return;\n }\n\n const isGridHaveError =\n validateIngredientGrid(gridInst).checkIngredientGridHaveError();\n\n if (isGridHaveError) {\n CustomNotification.error(`Please resolve Ingredient grid's errors`);\n return;\n }\n\n mutation.mutate(params, {\n onSuccess: async (result) => {\n if (result?.isSuccess) {\n if (ingredientsMode === 'add')\n CustomNotification.success('Add Ingredients successfully');\n else\n CustomNotification.success('Update Ingredient data successfully!');\n reloadDocumentCertificateTab();\n handleSyncIngredients(productId);\n await handleUpdateIXONEShield(ixoneIgnore);\n setVisible(false);\n } else {\n CustomNotification.error(\n result?.message ?? 'Failed to update Ingredient data'\n );\n }\n },\n onError: (error) => {\n CustomNotification.error('Something went wrong!');\n },\n });\n };\n\n useEffect(() => {\n formInst.setFieldsValue(ingredientData?.ingredientForm);\n }, [JSON.stringify(ingredientData)]);\n\n const modalProps = {\n title: ingredientsMode === 'add' ? 'Add Ingredient' : 'Edit Ingredient',\n visible: visible,\n width: '60%',\n closable: true,\n maskClosable: false,\n onCancel: handleCancel,\n wrapClassName: 'ingredient-modal',\n okText: 'Submit',\n };\n\n const isRequiredSomeFieldsIngredientGrid =\n isRequiredFieldForSupplier && gridRequiredFields.length > 0;\n\n const ingredientGridTitle = (\n \n {isRequiredSomeFieldsIngredientGrid && (\n <>\n <Text type='danger'>*</Text>{' '}\n </>\n )}\n <Text>LIST INGREDIENTS IN DECLINING ORDER OF PERCENTAGE (</Text>\n <Text italic>\n include sub-ingredients, components of ingredients, additives, etc.).\n For ingredients purchased from multiple vendors, list each vendor within\n its own row.\n </Text>\n \n );\n\n const ingredientStatement = Form.useWatch('ingredientStatement', formInst);\n\n const showConfirmIXONEModal = (() => {\n return (\n JSON.stringify(changeBreakout(ingredientStatement)) !==\n JSON.stringify(data?.currentIngredient?.ingredients)\n );\n })();\n\n return (\n {\n handleSave(ixoneIgnore);\n }}\n >\n {(handleConfirmIXONE) => (\n \n \n <>\n \n \n \n \n Ingredient Statement\n \n }\n rules={[\n {\n required: checkFieldRequired('ingredientStatement'),\n message:\n REQUIRED_FIELDS_QA_INGREDIENT.ingredientStatements\n .message,\n },\n ]}\n >\n \n \n \n \n \n \n Ingredient Claims\n \n }\n >\n \n \n \n \n \n \n (\n \n ),\n () => (\n \n ),\n () => (\n \n ),\n ]}\n >\n {(isEdit) => {\n return (\n \n );\n }}\n \n \n \n \n \n \n Total: {total}%\n \n \n \n \n \n \n \n )}\n \n );\n};\n\nexport default IngredientForm;\n","import React from 'react';\n\nimport { useIsMutating } from '@tanstack/react-query';\n\nimport { Button, Typography, Form } from 'antd';\nimport { PlusOutlined } from '@ant-design/icons';\n\nimport { CustomNotification, StyledModal } from 'common/components';\nimport {\n GroupElementWrapper as AllergenAdditionWrapper,\n HeaderGroupElement as AllergenHeader,\n} from 'pages/product-full-view/shared/components';\n\nimport { useVisibleModal, useCheckPermissions } from 'hooks';\nimport { customAllergenKeys } from './hooks';\n\nimport { validateForm } from 'pages/product-full-view/components/product-new-detail-view/utils';\nimport { getAllRows } from 'pages/qa-spec/utils';\n\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\nimport { useCheckQaSpecLocked } from 'pages/qa-spec/hooks/useCheckQaSpecLocked';\n\nconst PERMISSION_ADD_CUSTOM_ALLERGEN = [\n {\n action: ABILITY_ACTION.EDIT,\n subject: ABILITY_SUBJECT.QA_SPECIFICATION,\n },\n];\n\nconst CustomAllergenAddition = (props) => {\n const {\n gridInstance,\n productId,\n regional,\n onAddCustomAllergen: onAddCustomAllergenProp,\n children,\n } = props;\n\n const [visible, { onModal, offModal }] = useVisibleModal();\n\n const customAllergenForm = Form.useFormInstance();\n\n const isMutatingCustomAllergen = useIsMutating({\n mutationKey: customAllergenKeys.addCustomAllergen(productId),\n });\n\n const hasAddAllergenPermission = useCheckPermissions(\n PERMISSION_ADD_CUSTOM_ALLERGEN\n );\n\n const { isQASpecLocked } = useCheckQaSpecLocked();\n\n const modalProps = {\n title: 'Add Allergen',\n visible,\n destroyOnClose: true,\n width: 700,\n maskClosable: false,\n okButtonProps: {\n loading: Boolean(isMutatingCustomAllergen),\n },\n };\n\n const handleValidateAllergen = async () => {\n const customAllergenValue = await customAllergenForm.validateFields();\n\n // converting data into a nested format in order to validate its value\n const mappingFormValues = {\n AllergenRelatedInformation: [\n {\n Allergen: [customAllergenValue],\n },\n ],\n };\n\n const validatedResult = validateForm({ formValues: mappingFormValues });\n\n if (validatedResult?.length > 0) {\n customAllergenForm.setFields([\n {\n name: 'ContainmentSource',\n errors: [\n \n \n {validatedResult[0].message}\n \n ,\n ],\n },\n ]);\n\n return 'failed';\n }\n\n customAllergenForm.setFields([\n {\n name: 'ContainmentSource',\n errors: [],\n },\n ]);\n\n return 'passed';\n };\n\n const handleCheckDuplicateAllergen = async () => {\n const {\n AllergenTypeCode: allergenType,\n } = await customAllergenForm.validateFields();\n\n const allRows = getAllRows(gridInstance);\n\n const allergenTypeList = allRows.map((row) =>\n row?.allergenType?.toLowerCase()\n );\n\n return allergenTypeList.includes(allergenType?.toLowerCase());\n };\n\n const handleSubmitAllergen = async () => {\n const isDuplicate = await handleCheckDuplicateAllergen();\n\n // ContainmentSource will be disabled until LevelOfContainmentCode is set to \"May Contain\".\n // This validation function is currently unnecessary, but we will keep this logic for future use in case it becomes useful for checking.\n const statusValidation = await handleValidateAllergen();\n\n if (isDuplicate) {\n CustomNotification.warning(\n 'The allergen field already exists. Please add a different field!'\n );\n return;\n }\n\n if (statusValidation === 'failed') return;\n\n onAddCustomAllergenProp && onAddCustomAllergenProp();\n offModal();\n };\n\n return (\n <>\n {!isQASpecLocked ? (\n {\n onModal();\n customAllergenForm.setFieldsValue({\n Regional: regional,\n });\n }}\n icon={}\n style={{ borderRadius: 4 }}\n disabled={!hasAddAllergenPermission}\n >\n Add value\n \n ) : null}\n\n {\n offModal();\n customAllergenForm.resetFields();\n }}\n {...modalProps}\n >\n \n \n {children}\n \n \n \n );\n};\n\nexport default CustomAllergenAddition;\n","import React from 'react';\n\nimport {\n Popover,\n Typography,\n Input,\n InputNumber,\n Checkbox,\n Select,\n Row,\n Col,\n} from 'antd';\n\nimport classnames from 'classnames';\n\nimport { WrapperSelect } from 'common/components';\n\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\n\nimport isEqual from 'lodash/isEqual';\n\nimport './RetailerSnapshot.less';\n\nconst { Option } = Select;\n\nexport const RetailerSnapshot = ({\n supplierModifiedValue,\n snapshotValue,\n highlightContent,\n children,\n ...rest\n}) => {\n const isToggleSnapshot = useCheckSnapshotForRetailer();\n\n const isDiffValue = !isEqual(supplierModifiedValue, snapshotValue);\n\n let element = children;\n\n if (isToggleSnapshot && isDiffValue) {\n element = (\n Previous Version}\n trigger='hover'\n overlayInnerStyle={{ minWidth: 400 }}\n content={highlightContent}\n {...rest}\n >\n
{children}
\n \n );\n }\n\n return element;\n};\n\nexport const RetailerSnapshotInput = (props) => {\n const { className, ...rest } = props;\n\n return (\n \n );\n};\n\nexport const RetailerSnapshotInputNumber = (props) => {\n const { className, ...rest } = props;\n\n return (\n \n );\n};\n\nexport const RetailerSnapshotTextarea = (props) => {\n const { className, ...rest } = props;\n\n return (\n \n );\n};\n\nexport const RetailerSnapshotCheckbox = (props) => {\n const { className, ...rest } = props;\n\n return (\n \n );\n};\n\nexport const RetailerSnapshotSelect = (props) => {\n const { className, children, ...rest } = props;\n\n return (\n \n {children}\n \n );\n};\n\nexport const RetailerSnapshotOption = (props) => {\n const { className, children, ...rest } = props;\n\n return (\n \n {children}\n \n );\n};\n\nexport const PrimaryFieldSnapshot = ({ variant = 'text', ...otherProps }) => {\n const isToggleSnapshot = useCheckSnapshotForRetailer();\n\n switch (variant) {\n case 'text':\n return isToggleSnapshot ? (\n \n ) : (\n \n );\n\n case 'textarea':\n return isToggleSnapshot ? (\n \n ) : (\n \n );\n\n case 'number':\n return isToggleSnapshot ? (\n \n ) : (\n \n );\n\n case 'select':\n return isToggleSnapshot ? (\n \n ) : (\n \n );\n\n case 'checkbox':\n return isToggleSnapshot ? (\n \n ) : (\n \n );\n\n default:\n return ;\n }\n};\n\nexport const HighlightContent = ({\n label,\n value,\n variant = 'text',\n ...otherProps\n}) => {\n return (\n \n \n {label}\n \n \n {variant === 'checkbox' ? (\n \n ) : (\n {value ?? 'N/A'}\n )}\n \n \n );\n};\n\nexport const HighlightContentCheckbox = ({ value }) => {\n return ;\n};\n","import React, { useEffect, useMemo, useState, useRef } from 'react';\nimport { Typography, Row, Col, Space, Menu } from 'antd';\n\nimport classnames from 'classnames';\n\nimport { cloneDeep } from 'lodash';\n\nimport { useParams } from 'react-router-dom';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { WithQaGridHeader } from 'pages/qa-spec/components';\nimport {\n WithLoading,\n CarouselNext,\n CarouselPrevious,\n useCarousel,\n CarouselSection,\n dialogFunction,\n CustomNotification,\n FormAddButton as AddButton,\n FormEditButton as EditButton,\n FormDeleteButton as DeleteButton,\n} from 'common/components';\n\nimport IngredientForm from './IngredientForm';\nimport QaIngredientGrid from './QaIngredientGrid';\n\nimport {\n GroupActions,\n MenuItem,\n} from 'pages/product-full-view/components/product-media-area/multiple-panel/components';\n\nimport {\n QaGroupAddition,\n QaGroupAssign,\n QaGroupDeletion,\n QaGroupEdit,\n QaGroupPreview,\n} from '../group-data';\n\nimport {\n useCheckAllowEdit,\n useCheckSnapshotForRetailer,\n useGetEnumOptions,\n} from 'pages/qa-spec/hooks';\nimport { useTabExpand } from 'hooks/useTabExpandProduct';\nimport { useCheckAllowManageGroupData } from 'hooks';\nimport {\n TYPE_GROUPS,\n useGetAllGroupProduct,\n useVisibleGroupModal,\n} from 'pages/product-full-view/components/product-media-area/shared/hooks';\n\nimport {\n queryKeyQaSpecIngredients,\n useGetIngredients,\n useGetIngredientsSnapshot,\n useMutationIngredients,\n} from './hook';\n\nimport {\n getIngredientPercentTotal,\n mappingInitialIngredientList,\n} from 'pages/qa-spec/utils/ingredient';\n\nimport { INGREDIENT_LIMIT_CHARACTERS } from 'pages/qa-spec/constant';\nimport { useReloadDocumentCertificateTab } from 'hooks/useReloadDocumentCertificateTab';\n\nimport { GroupLayoutProvider } from 'pages/product-full-view/components/product-media-area/multiple-panel/components/GroupLayoutProvider';\n\nimport { getCurrentSlide } from 'utils';\nimport { GroupPartName } from 'pages/product-full-view/components/product-media-area/multiple-panel/components';\nimport {\n getSelectedItemGroup,\n transformToTextGroupName,\n} from 'pages/product-full-view/components/product-media-area/shared/utils';\n\nimport { filterProductGroups } from 'pages/product-full-view/components/product-media-area/multiple-panel/tab-allergens/utils';\n\nimport { useCheckQaSpecLocked } from 'pages/qa-spec/hooks/useCheckQaSpecLocked';\nimport {\n HighlightContent,\n PrimaryFieldSnapshot,\n RetailerSnapshot,\n} from '../qa-prod-spec/snapshot/RetailerSnapshot';\nimport {\n IXONECertificationWrapper,\n IXONEShieldWarning,\n TYPE_VIEW,\n} from 'common/components/product-add/IXONECertificationWrapper';\nimport useUpdateIXONEShield from 'common/components/product-add/useUpdateIXONEShield';\n\nimport './QaSpecIngredient.less';\n\nconst { Title, Text } = Typography;\n\nconst QaSpecIngredient = () => {\n const { id: productId } = useParams();\n\n const [total, setTotal] = useState(0);\n const [visible, setVisible] = useState(false);\n const [ingredientsMode, setIngredientsMode] = useState('add');\n const [currentSlide, setCurrentSlide] = useState(0);\n\n const gridInst = useRef();\n const { tableStyle } = useTabExpand();\n const queryClient = useQueryClient();\n const { reloadDocumentWhenDelete } = useReloadDocumentCertificateTab();\n\n const { isLoading, data } = useGetIngredients(productId);\n const { qaIngredientsSnapshot } = useGetIngredientsSnapshot();\n const { handleUpdateIXONEShield } = useUpdateIXONEShield();\n\n const { productGroups } = useGetAllGroupProduct(productId);\n const { carouselRef, onPrevCarousel, onNextCarousel } = useCarousel();\n const ingredientOptions = useGetEnumOptions()?.ingredient;\n\n const ingredientStatements = data?.ingredientStatements?.length\n ? data?.ingredientStatements\n : [{}];\n\n const ingredientData = useMemo(() => {\n const total = getIngredientPercentTotal(data?.ingredients || []);\n setTotal(total);\n\n return {\n ingredientList: mappingInitialIngredientList(data?.ingredients) || [],\n };\n }, [data]);\n\n const ingredientDataSnapshot = useMemo(() => {\n if (qaIngredientsSnapshot?.length === 0) return [];\n\n const total = getIngredientPercentTotal(\n qaIngredientsSnapshot?.ingredients || []\n );\n setTotal(total);\n\n return {\n ingredientList:\n mappingInitialIngredientList(qaIngredientsSnapshot?.ingredients) || [],\n };\n }, [qaIngredientsSnapshot]);\n\n const getCurrentIngredient = () => {\n return ingredientsMode === 'add'\n ? { index: null, isRemoved: false }\n : ingredientStatements?.[currentSlide];\n };\n\n /* Group Actions */\n const {\n visibleModalAddGroup,\n visibleModalEditGroup,\n visibleModalPreviewGroup,\n visibleModalAssignGroup,\n visibleModalDeleteGroup,\n handler: { onGroupModal, offGroupModal },\n } = useVisibleGroupModal();\n\n const hasManageGroupPermission = useCheckAllowManageGroupData();\n\n const selectedIngredientGroupIds =\n ingredientStatements?.[currentSlide]?.groupIds ?? [];\n\n const selectedIngredientsStatement =\n ingredientStatements?.[currentSlide] ?? {};\n\n const { defaultGroup, selectedProductGroups } = getSelectedItemGroup(\n selectedIngredientGroupIds,\n productGroups\n );\n const filteredProductGroups = filterProductGroups(\n selectedIngredientGroupIds,\n productGroups\n );\n /* End Groups */\n\n const { mutation } = useMutationIngredients({ productId, setVisible });\n\n const confirmDelete = (ixoneIgnore) => {\n dialogFunction({\n type: 'warn',\n content: (\n \n Are you sure you want to delete current Ingredient Statement?\n \n ),\n okText: 'Delete',\n okButtonProps: {\n type: 'danger',\n },\n onOk: async () => {\n const cloneData = cloneDeep(data);\n\n const ingredientStatements = cloneData?.ingredientStatements;\n ingredientStatements[getCurrentSlide(carouselRef)] = {\n ...data?.ingredientStatements?.[getCurrentSlide(carouselRef)],\n isRemoved: true,\n };\n\n const params = {\n ...data,\n ingredientStatements,\n };\n await mutation.mutateAsync(params, {\n onSuccess: async (result) => {\n if (result?.isSuccess) {\n CustomNotification.success('Delete Ingredients successfully.');\n await handleUpdateIXONEShield(ixoneIgnore);\n } else {\n CustomNotification.error(result?.message);\n }\n },\n onError: () => {\n CustomNotification.error('Delete failed!');\n },\n });\n },\n });\n };\n\n useEffect(() => {\n if (reloadDocumentWhenDelete) {\n queryClient.invalidateQueries({\n queryKey: queryKeyQaSpecIngredients(productId),\n });\n }\n }, [reloadDocumentWhenDelete]);\n\n const isAllowEditQaSpec = useCheckAllowEdit();\n\n const { isQASpecLocked } = useCheckQaSpecLocked();\n\n const totalIngredientStatement = data?.ingredientStatements?.length || 0;\n\n return (\n <>\n \n \n \n {\n onPrevCarousel();\n }}\n />\n {\n onNextCarousel();\n }}\n />\n \n Total: {totalIngredientStatement} Ingredient(s)\n \n \n \n \n {!isQASpecLocked ? (\n \n {\n setVisible(true);\n setIngredientsMode('add');\n }}\n disabled={!isAllowEditQaSpec}\n />\n {\n setVisible(true);\n setIngredientsMode('edit');\n }}\n disabled={totalIngredientStatement === 0 || !isAllowEditQaSpec}\n />\n {\n confirmDelete(ixoneIgnore);\n }}\n >\n {(handleConfirmIXONE) => (\n \n )}\n \n\n (\n \n \n \n onGroupModal(TYPE_GROUPS.addGroup)}\n />\n \n \n onGroupModal(TYPE_GROUPS.previewGroup)}\n disabled={selectedProductGroups?.length === 0}\n />\n \n \n onGroupModal(TYPE_GROUPS.assignGroup)}\n disabled={\n filteredProductGroups?.length === 0 ||\n !hasManageGroupPermission\n }\n />\n \n \n onGroupModal(TYPE_GROUPS.editGroup)}\n disabled={\n selectedProductGroups?.length === 0 ||\n !hasManageGroupPermission\n }\n />\n \n \n onGroupModal(TYPE_GROUPS.deleteGroup)}\n disabled={\n selectedProductGroups?.length === 0 ||\n !hasManageGroupPermission\n }\n />\n \n \n \n )}\n >\n \n \n \n ) : null}\n \n \n {\n setCurrentSlide(e);\n }}\n >\n {ingredientStatements?.map((item, index) => {\n const title = transformToTextGroupName(item?.groupIds, productGroups);\n\n const ingredientStatementSnapshot =\n qaIngredientsSnapshot?.ingredientStatements?.[index];\n\n return (\n \n \n \n \n \n \n Ingredient Statement\n \n\n \n }\n >\n \n \n \n \n \n \n \n Ingredient Claims\n \n\n \n }\n >\n \n \n \n \n \n \n \n LIST INGREDIENTS IN DECLINING ORDER OF PERCENTAGE (\n \n include sub-ingredients, components of ingredients,\n additives, etc.). For ingredients purchased from\n multiple vendors, list each vendor within its own\n row.\n \n \n }\n >\n {(isEdit) => {\n return (\n \n );\n }}\n \n \n \n \n \n \n Total: {total}%\n \n \n \n \n \n );\n })}\n \n\n {visible && (\n \n )}\n\n {/* Group Data */}\n {visibleModalAddGroup && (\n \n )}\n\n {visibleModalEditGroup && (\n \n \n \n )}\n\n {visibleModalAssignGroup && (\n \n )}\n\n {visibleModalPreviewGroup && (\n \n )}\n\n {visibleModalDeleteGroup && (\n \n )}\n {/* End Group Data */}\n \n );\n};\n\nconst QaIngredientSnapshot = (props) => {\n const { isSuccess } = useGetIngredientsSnapshot();\n const isToggleSnapshot = useCheckSnapshotForRetailer();\n\n if (isSuccess && isToggleSnapshot) {\n return ;\n }\n\n return <>{props.children};\n};\n\nexport default QaSpecIngredient;\n","import { Typography } from 'antd';\n\nconst FormLabel = ({ label }) => {\n return {label && label};\n};\n\nconst SnapshotFormLabel = ({ label, snapshotFieldValue }) => {\n return (\n \n :  {snapshotFieldValue}\n \n );\n};\n\nexport { FormLabel, SnapshotFormLabel };\n","import React, { useCallback, useEffect, useState } from 'react';\n\nimport { Popover } from 'antd';\n\nimport classnames from 'classnames';\n\nimport './SnapshotWrapper.less';\n\nconst SnapshotInputWrapper = (props) => {\n const {\n children, //* input render\n snapshotValue,\n snapshotValueRenderFn,\n showSnapshot = true,\n checkShowSnapshotFn,\n style = {},\n wrapperStyle = {},\n popoverProps = {},\n getInputValue,\n ...formItemToInputProps\n } = props;\n\n const { valuePropName = 'value' } = formItemToInputProps || {};\n\n const inputValue = props?.[valuePropName];\n\n const renderChildren = () => {\n return children\n ? React.Children.map(children, (childInput) => {\n return React.cloneElement(childInput, {\n [valuePropName]: inputValue,\n ...formItemToInputProps,\n ...childInput.props,\n });\n })\n : null;\n };\n\n const { isShowSnapshot, snapshotValueRender } = useSnapshotWrapper({\n checkShowSnapshotFn,\n inputValue,\n showSnapshot,\n snapshotValueRenderFn,\n snapshotValue,\n });\n\n useEffect(() => {\n getInputValue && getInputValue(inputValue);\n }, [inputValue, getInputValue]);\n\n return (\n \n \n
{renderChildren()}
\n \n \n );\n};\n\nconst SnapshotValuePopover = (props) => {\n const { children, snapshotValueRender, isShowSnapshot, popoverProps } = props;\n\n return (\n \n
\n {children && children}\n
\n \n );\n};\n\nconst SnapshotFormItemWrapper = (props) => {\n const {\n children,\n snapshotValueRenderFn,\n checkShowSnapshotFn,\n snapshotValue,\n showOverlay,\n } = props;\n const [inputValue, setInputValue] = useState();\n\n const getInputValue = useCallback((value) => {\n setInputValue(value);\n }, []);\n\n const { isShowSnapshot, snapshotValueRender } = useSnapshotWrapper({\n checkShowSnapshotFn,\n inputValue,\n showOverlay,\n snapshotValueRenderFn,\n snapshotValue,\n });\n\n if (typeof children !== 'function') return null;\n\n return (\n \n {children({ getInputValue, showSnapshot: isShowSnapshot })}\n \n );\n};\n\nconst useSnapshotWrapper = ({\n checkShowSnapshotFn,\n inputValue,\n showSnapshot,\n snapshotValueRenderFn,\n snapshotValue,\n}) => {\n const isShowSnapshot = checkShowSnapshotFn\n ? checkShowSnapshotFn({ value: inputValue })\n : showSnapshot;\n\n const snapshotValueRender = snapshotValueRenderFn\n ? snapshotValueRenderFn({ value: inputValue })\n : snapshotValue;\n\n return { isShowSnapshot, snapshotValueRender };\n};\n\nexport { SnapshotInputWrapper, SnapshotValuePopover, SnapshotFormItemWrapper };\n","import { SnapshotFormLabel } from './FormLabel';\n\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\nimport { formatCompareValue } from 'pages/qa-spec/utils';\nimport { get, isEqual } from 'lodash';\n\nconst useGetSnapshotFormItemWrapperProps = ({ snapshotValues }) => {\n const useSnapshot = useCheckSnapshotForRetailer();\n\n const getSnapshotFormItemWrapperProps = ({ fieldPath, label }) => {\n const snapshotFieldValue = get(snapshotValues, fieldPath);\n const procSnapshotFieldValue = formatCompareValue(snapshotFieldValue);\n\n return {\n snapshotValue: (\n \n ),\n checkShowSnapshotFn: ({ value }) => {\n const procValue = formatCompareValue(value);\n\n const isShowSnapshot =\n !isEqual(procValue, procSnapshotFieldValue) &&\n useSnapshot &&\n snapshotValues;\n\n return Boolean(isShowSnapshot);\n },\n };\n };\n\n return { getSnapshotFormItemWrapperProps };\n};\n\nexport { useGetSnapshotFormItemWrapperProps };\n","import React, { useMemo } from 'react';\n\nimport { Select } from 'antd';\nimport WrapperSelect from 'common/components/select';\nimport { findProductPropertyEnums } from 'pages/product-full-view/components/product-detail-view/utils';\n\nimport { useGetProductEnums } from 'hooks';\n\nconst { Option } = Select;\n\nconst EditInputCountry = (props) => {\n const { mode = 'single', value } = props;\n\n const country = useMemo(() => {\n if (Array.isArray(value)) {\n return value;\n } else if (!value) {\n return mode === 'single' ? value : [];\n } else {\n return value;\n }\n }, [value, mode]);\n\n const { productEnums } = useGetProductEnums();\n const countryCodeEnum = findProductPropertyEnums(\n 'CountryCodeEnum',\n productEnums\n );\n\n return (\n \n (option?.value ?? '').toLowerCase().includes(input.toLowerCase())\n }\n value={country}\n {...props}\n >\n {countryCodeEnum.map((countryItem) => {\n return (\n \n \n {countryItem.enumDisplayName}\n \n \n );\n })}\n
\n );\n};\n\nexport default EditInputCountry;\n","import React, { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from 'react-intl';\n\nimport { Col, Row, Typography, Input, Form, Select, Button } from 'antd';\n\nimport messages from 'i18n/messages/home';\nimport { skuPropertiesList, defaultType } from 'pages/qa-spec/constant';\nimport EditInputCountry from 'common/components/form/edit-input-country/EditInputCountry';\nimport { WrapperSelect } from 'common/components';\nimport { CountryEditorRender } from 'pages/qa-spec/components';\n\nimport SelectCategory from 'pages/home/ribbon/components/sections/product/SelectCategory';\nimport { generateIdsBySelectedKey } from 'pages/company-profile/components/tabs/system/category-management/utils';\n\nimport { useCheckPermissions, useGetEnumsByEnumName } from 'hooks';\nimport { useGetQaSpecRequiredFieldsInQaSpecFullView } from 'pages/qa-spec/hooks/useGetQaSpecRequiredFields';\nimport { SHOULD_ASSIGN_PRODUCT_CATEGORY } from 'static/Permission';\nimport sortByKey from 'utils/sortByKey';\nimport { sortBy } from 'lodash';\nimport useCheckAssignProductToSupplier from 'pages/qa-spec/hooks/useCheckAssignProductToSupplier';\nimport classnames from 'classnames';\nimport { red } from '@ant-design/colors';\n\nimport './QaSpecHeaderProperty.less';\n\nimport { useGetSnapshotQaDataHeader } from './hook';\nimport SnapshotFormItem from '../qa-spec-tab/SnapshotFormItem';\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\nimport { renderPopoverContent } from 'pages/qa-spec/utils';\n\nconst { Text, Paragraph } = Typography;\nconst { TextArea } = Input;\nconst { Option } = Select;\n\nconst formItemProps = {\n labelCol: {\n flex: '190px',\n },\n};\n\nconst styleLabelApplicable = {\n margin: '0px 0px 5px 0px',\n};\n\nconst QaSpecHeaderProperty = ({\n isEditable,\n qaSpecDataHeader,\n setCategoryList,\n}) => {\n const { checkAssignProductToSupplier } = useCheckAssignProductToSupplier();\n const isProductAssignedToSupplier = checkAssignProductToSupplier();\n\n return (\n <>\n {isEditable ? (\n \n ) : (\n \n \n \n )}\n \n );\n};\n\nconst RenderEditHeaderProperty = ({\n setCategoryList,\n qaSpecDataHeader,\n isProductAssignedToSupplier,\n}) => {\n const intl = useIntl();\n const form = Form.useFormInstance();\n\n const [visibleModal, setVisibleModal] = useState(false);\n\n const qaTypeEnums = useGetEnumsByEnumName('ProductOverviewTypeCodeEnum');\n\n const qaSmartLabelTemplateEnum = useGetEnumsByEnumName(\n 'SmartLabelTemplateEnum'\n );\n\n const countryCodeEnum = useGetEnumsByEnumName('CountryCodeEnum');\n\n const hasPermissionAssignCategory = useCheckPermissions(\n SHOULD_ASSIGN_PRODUCT_CATEGORY\n );\n\n const { data: requiredFields } = useGetQaSpecRequiredFieldsInQaSpecFullView({\n productId: qaSpecDataHeader?.productId,\n });\n\n const checkRequiredField = (fieldName) => {\n if (!isProductAssignedToSupplier) return false;\n\n if (!requiredFields) return false;\n\n return requiredFields.includes(`qaSpecification.${fieldName}`);\n };\n\n const handleSelectedCategory = (node, formValue) => {\n let params = {};\n\n if (node) {\n const categoryList = generateIdsBySelectedKey(node?.key);\n for (let i = 0; i < categoryList.length; i++) {\n params[`category${i + 1}Id`] = categoryList[i];\n }\n } else {\n for (let i = 0; i < 4; i++) {\n params[`category${i + 1}Id`] = null;\n }\n }\n\n setCategoryList(params);\n form.setFieldsValue({\n ...form.getFieldsValue(),\n ...formValue,\n });\n };\n\n const QASkuProperty = {\n selectType: {\n component: (\n \n {sortByKey(qaTypeEnums, 'enumDisplayName').map((item) => {\n const valueOption = item.enumDisplayName ?? defaultType;\n return (\n \n );\n })}\n \n ),\n selectProps: {\n options: sortBy(qaTypeEnums, ['displayName']),\n inputProps: {\n allowClear: true,\n showSearch: true,\n },\n },\n },\n selectSmartLabel: {\n component: (\n \n {sortByKey(qaSmartLabelTemplateEnum, 'enumDisplayName').map(\n (item) => {\n const valueOption = item.enumDisplayName ?? defaultType;\n return (\n \n );\n }\n )}\n \n ),\n selectProps: {\n options: sortBy(qaSmartLabelTemplateEnum, ['displayName']),\n inputProps: {\n allowClear: true,\n showSearch: true,\n },\n },\n },\n input: {\n component: ,\n },\n disableInput: {\n component: ,\n },\n countrySelect: {\n component: ,\n selectProps: {\n options: sortBy(countryCodeEnum, ['enumDisplayName']),\n inputProps: {\n allowClear: true,\n showSearch: true,\n },\n },\n },\n };\n\n return (\n <>\n
\n {skuPropertiesList(isProductAssignedToSupplier)?.map((item, idx) => {\n const label = intl.formatMessage(messages[item.label]);\n\n const isRequired = checkRequiredField(item.value);\n const itemRules = item.rules || [];\n const rules = [\n { required: isRequired, message: `${label} is required` },\n ...itemRules,\n ];\n\n return (\n \n {intl.formatMessage(messages[item.label])}\n \n }\n style={{ marginBottom: '6px' }}\n name={item.value}\n className={`qa-sku-form__${item.value}`}\n rules={rules}\n {...formItemProps}\n >\n {QASkuProperty[item.inputType]?.component}\n \n );\n })}\n \n \n }\n className={`qa-sku-form__select-category`}\n style={{ marginBottom: '6px' }}\n {...formItemProps}\n >\n setVisibleModal(true)}\n disabled={!hasPermissionAssignCategory}\n >\n Select Category\n \n \n \n
\n \n \n \n {intl.formatMessage(messages.qaSpecApplicableReferenceStandard)}\n \n \n\n \n \n \n \n \n \n );\n};\n\nconst RenderHeaderProperties = ({\n qaSpecDataHeader,\n isProductAssignedToSupplier,\n}) => {\n const intl = useIntl();\n\n const { id: productId } = useParams();\n\n const isToggleSnapshot = useCheckSnapshotForRetailer();\n\n const { data: snapshotData, isLoading } = useGetSnapshotQaDataHeader({\n productId,\n enabled: !!productId && isToggleSnapshot,\n });\n\n const { data: requiredFields } = useGetQaSpecRequiredFieldsInQaSpecFullView({\n productId: qaSpecDataHeader?.productId,\n });\n\n const checkRequiredField = (fieldName) => {\n if (!isProductAssignedToSupplier) return false;\n\n if (!requiredFields) return false;\n\n return requiredFields.includes(`qaSpecification.${fieldName}`);\n };\n\n const renderValueSku = (field, value) => {\n if (field.toLowerCase() === 'supplierlocation')\n return (\n \n );\n\n return value;\n };\n\n const getQaSpecHeaderValue = (field, data) => {\n const isCategoryField = field.indexOf('category') > -1;\n const isTypeField = field === 'type';\n\n const value = isCategoryField ? data?.[field]?.categoryName : data?.[field];\n\n if (isTypeField && !value) return defaultType;\n\n return value;\n };\n\n return (\n <>\n
\n {skuPropertiesList(isProductAssignedToSupplier)?.map((item, idx) => {\n const supplierModifiedData =\n getQaSpecHeaderValue(item.value, qaSpecDataHeader) ?? '';\n\n const snapshotHeaderData =\n getQaSpecHeaderValue(item.value, snapshotData) ?? '';\n\n const needRequiredMark = checkRequiredField(item.value);\n\n const isDiffWithPreVersion =\n snapshotHeaderData !== supplierModifiedData;\n const shouldHighlight = isDiffWithPreVersion && isToggleSnapshot;\n return (\n <>\n \n \n \n {needRequiredMark && (\n \n *\n \n )}\n \n {intl.formatMessage(messages[item.label])}:\n \n \n \n {isLoading ? (\n <> {renderValueSku(item.value, supplierModifiedData)}\n ) : (\n \n {renderValueSku(item.value, supplierModifiedData)}\n \n )}\n \n \n \n \n );\n })}\n
\n \n \n \n \n {intl.formatMessage(messages.qaSpecApplicableReferenceStandard)}\n \n \n \n \n \n \n );\n};\n\nexport default QaSpecHeaderProperty;\n","import React from 'react';\nimport { Checkbox } from 'antd';\n\nconst CheckboxRender = (props) => {\n const { value } = props;\n\n return (\n \n \n \n );\n};\n\nexport default CheckboxRender;\n","import React from 'react';\n\nimport { Typography, Tooltip } from 'antd';\n\nconst { Text } = Typography;\n\nconst StringTooltipRender = (params) => {\n const { value } = params;\n\n return (\n \n \n {value && value}\n \n \n );\n};\n\nexport default StringTooltipRender;\n","import React from 'react';\n\nimport { Tooltip, Typography, List } from 'antd';\nimport { CheckCircleTwoTone, WarningTwoTone } from '@ant-design/icons';\n\nimport reactCSS from 'reactcss';\nimport useCheckAssignProductToSupplier from 'pages/qa-spec/hooks/useCheckAssignProductToSupplier';\n\nconst styles = reactCSS({\n default: {\n iconDefault: {\n fontSize: 18,\n },\n commonAntIcon: {\n fontSize: 20,\n },\n iconWrapper: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginTop: -2,\n },\n },\n});\n\nconst StatusRender = (props) => {\n const { value } = props;\n const { checkAssignProductToSupplier } = useCheckAssignProductToSupplier();\n\n const isProductAssignedByRetailer = checkAssignProductToSupplier();\n\n const isHaveError = value?.length > 0;\n\n let errorMessage = (\n \n {isHaveError ? (\n \n ) : (\n \n )}\n \n );\n\n if (isProductAssignedByRetailer) {\n const titleTooltip = (\n (\n \n \n {item}\n \n \n )}\n />\n );\n\n errorMessage = (\n \n {isHaveError ? (\n \n ) : (\n \n )}\n \n );\n }\n\n return (\n \n
{errorMessage}
\n \n );\n};\n\nexport default StatusRender;\n","import React from 'react';\n\nconst DefaultCellRender = (params) => {\n const { value } = params;\n\n return (\n \n
{value && value}
\n \n );\n};\n\nexport default DefaultCellRender;\n","import React, { useMemo } from 'react';\nimport reactCSS from 'reactcss';\nimport { isArray } from 'lodash';\nimport { Typography, Tooltip } from 'antd';\n\nconst { Text } = Typography;\n\nconst styles = reactCSS({\n default: {\n wrapper: { paddingRight: 17, paddingLeft: 7, position: 'relative' },\n contentWrapper: { overflow: 'hidden' },\n content: {\n display: 'inline-block',\n width: 'max-content',\n },\n text: {\n display: 'inline-block',\n alignItems: 'center',\n marginRight: 6,\n },\n dot: {\n position: 'absolute',\n right: 4,\n zIndex: 10,\n bottom: 1,\n },\n },\n});\n\nconst CountryEditorRender = (params) => {\n const { value, wrapperStyle = {} } = params;\n\n const country = useMemo(() => {\n if (isArray(value)) {\n return value;\n } else if (value) {\n return value?.split(', ') || [];\n } else {\n return [];\n }\n }, [value]);\n\n return (\n
\n \n
\n \n {country.join(', ')}\n \n
\n \n
\n );\n};\n\nexport default CountryEditorRender;\n","import React from 'react';\n\nimport SnapshotCellWrapper from './SnapshotCellWrapper';\nimport CountryEditorRender from './CountryEditorRender';\n\nimport { isEqual } from 'lodash';\nimport { formatCompareValue } from 'pages/qa-spec/utils';\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\n\nconst CountryEditorRenderSnapshot = (props) => {\n const { column, rowIndex, data, context } = props;\n\n const { snapshotGridValues } = context || {};\n\n const useSnapshot = useCheckSnapshotForRetailer();\n\n const cellSnapshotValue = formatCompareValue(\n snapshotGridValues?.[rowIndex]?.[column.colId]\n );\n\n const rawCellValue = formatCompareValue(data?.[column.colId]);\n\n const isHighlightChange =\n !isEqual(rawCellValue, cellSnapshotValue) && useSnapshot;\n\n return (\n \n \n \n );\n};\n\nexport default CountryEditorRenderSnapshot;\n","import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport ReactDOM from 'react-dom';\n\nimport {\n UploadOutlined,\n LoadingOutlined,\n DeleteFilled,\n DownloadOutlined,\n EyeOutlined,\n} from '@ant-design/icons';\n\nimport PreviewableModal from 'common/components/previewable-modal/PreviewableModal';\nimport { UploadFile, dialogFunction } from 'common/components';\n\nimport { Button, Row, Col, Image, Typography, Space } from 'antd';\n\nimport { UPLOAD_MAX_SIZE } from 'static/Constants';\n\nimport { mapOriginalFileTypeToImage } from 'utils/fileType';\nimport { checkShowPdfPreview } from 'utils/checkShowPdfPreview';\nimport * as api from 'config/axios';\n\nimport './FileUploadEditor.less';\nimport { useCheckQaSpecLocked } from 'pages/qa-spec/hooks/useCheckQaSpecLocked';\n\nconst { Text } = Typography;\n\nexport const FileUploadEditor = forwardRef((props, ref) => {\n const {\n value: initValue,\n apiUrl,\n additionalBodyPayload = {},\n supportTypes = [],\n confirmDeleteMessage,\n column,\n } = props;\n\n const [value, setValue] = useState(initValue);\n const [editing, setEditing] = useState(true);\n const [loading, setLoading] = useState(false);\n const [fileInfo, setFileInfo] = useState(null);\n const [isPreviewOpen, setIsPreviewOpen] = useState(false);\n\n const refContainer = useRef(null);\n const refUpload = useRef();\n\n const { isQASpecLocked } = useCheckQaSpecLocked();\n\n const { linkPreview, extensionFile } = checkShowPdfPreview(\n value?.pdfPreview,\n value?.linkUrl,\n value?.fileType\n );\n\n useEffect(() => {\n focus();\n }, []);\n\n useImperativeHandle(ref, () => {\n return {\n getValue() {\n return value;\n },\n };\n });\n\n useEffect(() => {\n if (!editing) {\n props.stopEditing();\n }\n }, [editing]);\n\n const focus = () => {\n window.setTimeout(() => {\n let container = ReactDOM.findDOMNode(refContainer.current);\n if (container) {\n container.focus();\n }\n });\n };\n\n const handleUploadSuccess = (res) => {\n if (!res?.data) return;\n\n try {\n const { isSuccess, data } = res?.data;\n\n if (isSuccess) {\n setValue({\n documentName: fileInfo?.fileName,\n thumb: mapOriginalFileTypeToImage(fileInfo?.fileName),\n linkUrl: null,\n fileType: null,\n digitalAssetId: data?.assetId,\n });\n }\n } catch (e) {}\n };\n\n const onFileChange = (fileList) => {\n if (!fileList) return;\n const file = fileList.slice(-1).pop();\n if (!file) return;\n\n const status = file?.status;\n\n if (status === 'uploading') {\n setLoading(true);\n setFileInfo({ fileName: file?.name });\n }\n\n if (status === 'done') {\n setLoading(false);\n setFileInfo({ fileName: file?.name });\n }\n };\n\n const onRemoveFile = () => {\n setValue(null);\n };\n\n const handleRemoveFile = () => {\n confirmDeleteMessage\n ? dialogFunction({\n type: 'warn',\n content: confirmDeleteMessage,\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: () => {\n onRemoveFile();\n },\n })\n : onRemoveFile();\n };\n\n const handleDownloadFile = () => {\n value?.linkUrl &&\n api.sendDownload({\n url: value?.linkUrl,\n });\n };\n\n const width = column.getActualWidth() || 300;\n\n return (\n \n \n \n {value?.documentName ? : <>No File}\n \n \n \n }\n onClick={() => setIsPreviewOpen(true)}\n style={{ border: 'none' }}\n disabled={!value?.linkUrl || !value?.fileType}\n />\n }\n onClick={handleDownloadFile}\n style={{ border: 'none' }}\n disabled={!value?.linkUrl}\n />\n\n {loading ? (\n \n ) : (\n }\n onClick={() => {\n refUpload.current.handleClickUpload();\n }}\n style={{ border: 'none' }}\n />\n )}\n {!isQASpecLocked ? (\n }\n onClick={handleRemoveFile}\n style={{ border: 'none' }}\n disabled={!value}\n />\n ) : null}\n \n \n \n
\n \n
\n {isPreviewOpen && (\n setIsPreviewOpen(false)}\n isDownload={false}\n isDocument={true}\n downloadLink={value?.linkUrl}\n />\n )}\n \n );\n});\n\nexport const FileViewer = ({ data }) => {\n return (\n \n \n \n \n \n {data?.documentName}\n \n \n );\n};\n","import React, { useState } from 'react';\n\nimport { Row, Col, Space, Button } from 'antd';\n\nimport { DownloadOutlined, EyeOutlined } from '@ant-design/icons';\n\nimport { FileViewer } from './FileUploadEditor';\nimport PreviewableModal from 'common/components/previewable-modal/PreviewableModal';\n\nimport * as api from 'config/axios';\nimport { checkShowPdfPreview } from 'utils/checkShowPdfPreview';\n\nconst FileUploadRender = (props) => {\n const { value } = props;\n const [isPreviewOpen, setIsPreviewOpen] = useState(false);\n\n const { linkPreview, extensionFile } = checkShowPdfPreview(\n value?.pdfPreview,\n value?.linkUrl,\n value?.fileType\n );\n\n const handleDownloadFile = () => {\n value?.linkUrl &&\n api.sendDownload({\n url: value?.linkUrl,\n });\n };\n\n return (\n \n {value && (\n \n \n {value?.documentName && }\n \n \n \n }\n onClick={() => setIsPreviewOpen(true)}\n style={{ border: 'none' }}\n disabled={!value?.linkUrl || !value?.fileType}\n />\n }\n onClick={handleDownloadFile}\n style={{ border: 'none' }}\n disabled={!value?.linkUrl}\n />\n \n \n \n )}\n\n {isPreviewOpen && (\n setIsPreviewOpen(false)}\n isDownload={false}\n isDocument={true}\n downloadLink={value?.linkUrl}\n fileSize={value?.fileSize}\n />\n )}\n \n );\n};\n\nexport default FileUploadRender;\n","import React from 'react';\n\nimport SnapshotCellWrapper from './SnapshotCellWrapper';\nimport FileUploadRender from './FileUploadRender';\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\n\nimport { isEqual } from 'lodash';\n\nconst FileUploadRenderSnapshot = (props) => {\n const { snapshotValueRender, ...params } = props;\n const { column, rowIndex, data, context } = params;\n const { snapshotGridValues } = context || {};\n\n const useSnapshot = useCheckSnapshotForRetailer();\n\n const cellSnapshotValue = snapshotGridValues?.[rowIndex]?.[column.colId];\n const rawCellValue = data?.[column.colId];\n\n const defaultSnapshotValueRender = cellSnapshotValue ? (\n \n ) : (\n 'N/A'\n );\n\n const isHighlightChange =\n !isEqual(rawCellValue?.digitalAssetId, cellSnapshotValue?.digitalAssetId) &&\n useSnapshot;\n\n return (\n \n \n \n );\n};\n\nexport default FileUploadRenderSnapshot;\n","import React from 'react';\n\nimport SnapshotCellWrapper from './SnapshotCellWrapper';\n\nimport CheckboxRender from './CheckboxRender';\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\n\nconst CheckboxRenderSnapshot = (props) => {\n const { column, rowIndex, data, context } = props;\n\n const { snapshotGridValues } = context || {};\n\n const useSnapshot = useCheckSnapshotForRetailer();\n\n const cellSnapshotValue = snapshotGridValues?.[rowIndex]?.[column.colId];\n const rawCellValue = data?.[column.colId];\n\n const isHighlightChange = cellSnapshotValue !== rawCellValue && useSnapshot;\n\n return (\n \n {cellSnapshotValue === null || cellSnapshotValue === undefined ? (\n 'N/A'\n ) : (\n \n )}\n \n }\n >\n \n \n );\n};\n\nexport default CheckboxRenderSnapshot;\n","import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\n\nimport { Select } from 'antd';\n\nimport { sleep } from 'utils/delay';\n\nimport './SelectionEditor.less';\n\nconst { Option } = Select;\n\nexport const SelectionEditor = forwardRef((props, ref) => {\n const { values, value: initValue, mode, mapValue, disabled, column } = props;\n\n const [value, setValue] = useState(initValue);\n const [editing, setEditing] = useState(true);\n const refContainer = useRef(null);\n const refSelect = useRef();\n\n const refValue = useRef(undefined);\n\n const focus = () => {\n setTimeout(() => {\n refSelect.current?.focus && refSelect.current.focus();\n }, [100]);\n };\n\n useEffect(() => {\n focus();\n }, []);\n\n useEffect(() => {\n if (!editing) {\n props.stopEditing();\n }\n }, [editing]);\n\n const extractValue = (value) => {\n return mapValue ? mapValue(value) : value;\n };\n\n const handleChange = (value) => {\n const nextValue = extractValue(value);\n setValue(nextValue);\n refValue.current = nextValue;\n props.stopEditing();\n };\n\n const valueItemType =\n typeof values?.[0]?.displayName === 'string' ? 'object' : 'string';\n\n const handleInputKeyDown = async (e) => {\n if (e.key === 'Delete') {\n setValue(null);\n refValue.current = null;\n setEditing(false);\n return;\n }\n\n if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n e.preventDefault();\n } else {\n await sleep(200);\n const $dropDownActiveItem = document.querySelector(\n 'div.ant-select-item-option-active > div.ant-select-item-option-content > div.option-item'\n );\n\n if ($dropDownActiveItem) {\n const activeValue = $dropDownActiveItem.getAttribute('value');\n refValue.current = activeValue;\n }\n }\n };\n\n const handleMouseEnter = (e, idx) => {\n const nextRefValue =\n valueItemType === 'string' ? values?.[idx] : value?.[idx]?.value;\n\n refValue.current = extractValue(nextRefValue);\n };\n\n useImperativeHandle(ref, () => {\n return {\n getValue() {\n if (refValue.current === undefined) {\n return value;\n } else {\n const procValue = refValue.current;\n refValue.current = undefined;\n return procValue;\n }\n },\n };\n });\n\n const width = column.getActualWidth() || 300;\n\n return (\n \n \n {values.map((valueItem, idx) => {\n const key = valueItemType === 'string' ? valueItem : valueItem?.value;\n const displayName =\n valueItemType === 'string' ? valueItem : valueItem?.displayName;\n\n return (\n handleMouseEnter(e, idx)}\n className='ag-editor__selection-option'\n >\n
\n {displayName}\n
\n \n );\n })}\n \n \n );\n});\n","import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\n\nimport { Select } from 'antd';\nimport { isArray } from 'lodash';\nimport { sleep } from 'utils/delay';\n\nimport { useGetProductEnums } from 'hooks';\nimport { findProductPropertyEnums } from 'pages/product-full-view/components/product-detail-view/utils';\n\nimport './CountryEditor.less';\n\nconst { Option } = Select;\n\nexport const CountryEditor = forwardRef((props, ref) => {\n const { mode = 'multiple', listString = true, column } = props;\n\n const { productEnums } = useGetProductEnums();\n\n const countryCodeEnum = findProductPropertyEnums(\n 'CountryCodeEnum',\n productEnums\n );\n\n const processValue = (value) => {\n if (isArray(value)) {\n return value;\n } else if (value) {\n return value?.split(', ') || [];\n } else {\n return [];\n }\n };\n\n const [country, setCountry] = useState(processValue(props.value));\n const [editing, setEditing] = useState(true);\n const refContainer = useRef(null);\n const refSelect = useRef();\n const refValue = useRef(undefined);\n\n const focus = () => {\n setTimeout(() => {\n refSelect.current?.focus && refSelect.current.focus();\n }, [100]);\n };\n\n useEffect(() => {\n focus();\n }, []);\n\n const getCountryListInString = (countryValue) => {\n return listString ? countryValue : countryValue.join(', ');\n };\n\n useImperativeHandle(ref, () => {\n return {\n getValue() {\n if (refValue.current === undefined) {\n return getCountryListInString(country);\n } else {\n const procValue = getCountryListInString(refValue.current);\n refValue.current = undefined;\n return procValue;\n }\n },\n };\n });\n\n useEffect(() => {\n if (!editing) {\n props.stopEditing();\n }\n }, [editing]);\n\n const handleChange = (value) => {\n if (!value) {\n setCountry([]);\n return;\n }\n if (typeof value === 'string') {\n setCountry([value]);\n return;\n }\n setCountry(value);\n };\n\n const handleKeyInMultipleMode = async (e) => {\n if (e.key === 'Control') {\n await sleep(100);\n\n const $dropDownActiveItem = document.querySelector(\n 'div.ant-select-item-option-active > div.ant-select-item-option-content > span.option-item-value'\n );\n\n if ($dropDownActiveItem) {\n const nextValue = [...country];\n\n const activeValue = $dropDownActiveItem.getAttribute('value');\n\n const foundActiveValueIdx = country.findIndex(\n (valueItem) => valueItem === activeValue\n );\n\n if (foundActiveValueIdx !== -1) {\n nextValue.splice(foundActiveValueIdx, 1);\n } else {\n nextValue.push(activeValue);\n }\n\n setCountry(nextValue);\n }\n }\n };\n\n const handleKeyInSingleMode = async (e) => {\n if (e.key === 'Delete') {\n setCountry([]);\n refValue.current = [];\n setEditing(false);\n return;\n }\n\n if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n e.preventDefault();\n } else {\n await sleep(100);\n const $dropDownActiveItem = document.querySelector(\n 'div.ant-select-item-option-active > div.ant-select-item-option-content > span.option-item-value'\n );\n\n if ($dropDownActiveItem) {\n const activeValue = $dropDownActiveItem.getAttribute('value');\n const nextValue = [activeValue];\n\n refValue.current = nextValue;\n }\n }\n };\n\n const handleInputKeyDown = async (e) => {\n if (e.key === 'Delete') {\n setCountry([]);\n setEditing(false);\n return;\n }\n\n if (mode === 'multiple') {\n await handleKeyInMultipleMode(e);\n }\n\n if (mode === 'single') {\n await handleKeyInSingleMode(e);\n }\n };\n\n const width = column.getActualWidth() || 300;\n\n return (\n \n \n {countryCodeEnum?.map((countryItem) => {\n return (\n \n \n {countryItem.enumDisplayName}\n \n \n );\n })}\n \n \n );\n});\n","import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\n\nimport { InputNumber } from 'antd';\n\nimport './NumericEditor.less';\n\nexport const NumericEditor = forwardRef((props, ref) => {\n const { value: initValue, column, ...restProps } = props;\n\n const [value, setValue] = useState(initValue);\n const [editing, setEditing] = useState(true);\n const refContainer = useRef(null);\n const refInput = useRef(null);\n\n const focus = () => {\n setTimeout(() => {\n if (refInput.current && refInput.current?.focus) {\n refInput.current.focus();\n }\n }, [100]);\n };\n\n useEffect(() => {\n focus();\n }, []);\n\n useImperativeHandle(ref, () => {\n return {\n getValue() {\n return value;\n },\n };\n });\n\n useEffect(() => {\n if (!editing) {\n props.stopEditing();\n }\n }, [editing]);\n\n const handleChange = (value) => {\n setValue(value);\n };\n\n const handleEnter = () => {\n setEditing(false);\n };\n\n const width = column.getActualWidth() || 300;\n\n return (\n \n \n \n );\n});\n","import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { Checkbox } from 'antd';\n\nimport './CheckboxEditor.less';\n\nexport const CheckboxEditor = forwardRef((props, ref) => {\n const { value: initValue, column, node } = props;\n\n const [value, setValue] = useState(initValue);\n const [editing, setEditing] = useState(true);\n const refContainer = useRef(null);\n\n const focus = () => {\n setTimeout(() => {\n let container = ReactDOM.findDOMNode(refContainer.current);\n\n if (container && container?.focus) {\n container.focus();\n }\n }, [100]);\n };\n\n useEffect(() => {\n focus();\n }, []);\n\n useImperativeHandle(ref, () => {\n return {\n getValue() {\n return value;\n },\n };\n });\n\n useEffect(() => {\n if (!editing) {\n props.stopEditing();\n }\n }, [editing]);\n\n const handleChange = (e) => {\n setValue(e.target.checked);\n };\n\n const handleInputKeyDown = (e) => {\n e.stopPropagation();\n if (e.key === 'c' || e.key === 'Control') {\n e.preventDefault();\n setValue((prev) => !prev);\n }\n };\n\n const width = column.getActualWidth() || 300;\n const height = node?.rowHeight || 42;\n\n return (\n \n \n \n );\n});\n","import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\n\nimport { Input, Button, Dropdown, Menu } from 'antd';\nimport { DownOutlined } from '@ant-design/icons';\n\nimport './FreeTextSelector.less';\n\nexport const FreeTextSelector = forwardRef((props, ref) => {\n const { values, value: initValue, overlayClassName, disabled } = props;\n\n const [value, setValue] = useState(initValue);\n const [editing, setEditing] = useState(true);\n const refInput = useRef(null);\n\n const onSelectMenu = ({ key }) => {\n setValue(key);\n };\n\n const focus = () => {\n window.setTimeout(() => {\n if (refInput.current) {\n refInput.current.focus({ cursor: 'all' });\n }\n });\n };\n\n const handleChange = (e) => {\n setValue(e.target.value);\n };\n\n useImperativeHandle(ref, () => {\n return {\n getValue() {\n return value;\n },\n };\n });\n\n useEffect(() => {\n focus();\n }, []);\n\n useEffect(() => {\n if (!editing) {\n props.stopEditing();\n }\n }, [editing]);\n\n const optionsMenu = (\n \n {values.map((option) => {\n return {option.displayName};\n })}\n \n );\n\n return (\n
\n \n \n \n
\n );\n});\n","import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n useMemo,\n } from 'react';\n import ReactDOM from 'react-dom';\n \n import { Select } from 'antd';\n \n import { isArray } from 'lodash';\n \n import CountryCodes from 'static/CountryCode';\n \n import * as CountryFlagList from 'react-flags-select';\n \n import './CountryEditor.less';\n \n const { Option } = Select;\n \n export const CountryEditorSingle = forwardRef((props, ref) => {\n const processValue = (value) => {\n if (isArray(value)) {\n return value.join(', ');\n } else if (value) {\n return value?.split(', ') || [];\n } else {\n return [];\n }\n };\n \n const [country, setCountry] = useState(processValue(props.value));\n const [editing, setEditing] = useState(true);\n const refContainer = useRef(null);\n \n useEffect(() => {\n focus();\n }, []);\n \n useImperativeHandle(ref, () => {\n return {\n getValue() {\n return country;\n },\n };\n });\n \n useEffect(() => {\n if (!editing) {\n props.stopEditing();\n }\n }, [editing]);\n \n const focus = () => {\n window.setTimeout(() => {\n let container = ReactDOM.findDOMNode(refContainer.current);\n if (container) {\n container.focus();\n }\n });\n };\n \n const handleChange = (value) => {\n setCountry(value);\n };\n \n const CountryList = useMemo(() => {\n let countryListObject = {};\n let countryListArray = [];\n for (const [key, value] of Object.entries(CountryCodes)) {\n const flagKey = `${key.slice(0, 1)}${key\n .slice(1, 2)\n .toLocaleLowerCase()}`;\n const newValue = { name: value, flag: CountryFlagList[flagKey]() };\n countryListObject[key] = newValue;\n countryListArray.push(newValue);\n }\n \n return { countryListObject, countryListArray };\n }, []);\n \n return (\n
\n \n {CountryList.countryListArray.map((countryItem) => {\n return (\n \n );\n })}\n \n
\n );\n });\n ","import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\n\nimport { Input } from 'antd';\n\nimport { sleep } from 'utils/delay';\n\nimport './TextEditor.less';\n\nexport const TextEditor = forwardRef((props, ref) => {\n const { value: initValue, maxLength, column, ...restProps } = props;\n\n const [value, setValue] = useState(initValue);\n const [editing, setEditing] = useState(true);\n const refContainer = useRef(null);\n const refInput = useRef(null);\n\n const focus = async () => {\n await sleep(50);\n if (refContainer.current && refContainer.current?.focus) {\n refContainer.current.focus();\n }\n await sleep(150);\n if (refInput.current && refInput.current?.focus) {\n refInput.current.focus();\n }\n };\n\n useEffect(() => {\n focus();\n }, []);\n\n useImperativeHandle(ref, () => {\n return {\n getValue() {\n return value;\n },\n };\n });\n\n useEffect(() => {\n if (!editing) {\n props.stopEditing();\n }\n }, [editing]);\n\n const handleChange = (e) => {\n setValue(e.target.value);\n };\n\n const handleEnter = () => {\n setEditing(false);\n };\n\n // const isRenderTextarea = maxLength >= MAX_LENGTH_RENDER_TEXT_AREA;\n const isRenderTextarea = false;\n\n const width = column.getActualWidth() || 300;\n\n return (\n \n {isRenderTextarea ? (\n \n ) : (\n \n )}\n \n );\n});\n","import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n useMemo,\n} from 'react';\n\nimport { Select, Tooltip, Typography } from 'antd';\n\nimport { FontColorsOutlined } from '@ant-design/icons';\n\nimport { sleep } from 'utils/delay';\n\nimport classnames from 'classnames';\n\nimport './SelectionFreeText.less';\n\nconst { Option } = Select;\nconst { Text } = Typography;\n\nexport const SelectionFreeText = forwardRef((props, ref) => {\n const {\n values,\n value: initValue,\n mode = 'single',\n mapValue,\n disabled,\n maxLength,\n column,\n } = props;\n\n const processInitValue = useMemo(() => {\n if (initValue === null || initValue === undefined || initValue === '') {\n return [];\n } else {\n return [initValue];\n }\n }, [initValue]);\n\n const [value, setValue] = useState(processInitValue);\n const [editing, setEditing] = useState(true);\n\n const refContainer = useRef(null);\n const refSelect = useRef();\n\n const refValue = useRef(undefined);\n const refSearchValue = useRef(undefined);\n\n const focus = async () => {\n await sleep(50);\n if (refContainer.current && refContainer.current?.focus) {\n refContainer.current.focus();\n }\n await sleep(150);\n if (refSelect.current && refSelect.current?.focus) {\n refSelect.current.focus();\n }\n };\n\n useEffect(() => {\n focus();\n }, []);\n\n useEffect(() => {\n if (!editing) {\n props.stopEditing();\n }\n }, [editing]);\n\n const extractValue = (value) => {\n return mapValue ? mapValue(value) : value;\n };\n\n const isValidLength = (value) => {\n if (!maxLength === null || maxLength === undefined || !value) return true;\n return maxLength && value?.length <= maxLength;\n };\n\n const handleChange = (value) => {\n let nextValue = value.slice(-1)[0];\n\n nextValue = nextValue ? extractValue(nextValue) : undefined;\n\n if (nextValue) {\n const isSelectedItemInList = values\n .map((item) => item?.value)\n .includes(nextValue);\n\n if (isSelectedItemInList) {\n if (!isValidLength(nextValue)) return;\n } else {\n nextValue = maxLength ? nextValue.slice(0, maxLength) : nextValue;\n }\n }\n\n nextValue = nextValue ? [nextValue] : [];\n\n setValue(nextValue);\n refValue.current = nextValue;\n };\n\n const valueItemType =\n typeof values?.[0]?.displayName === 'string' ? 'object' : 'string';\n\n const getActiveDropDownItem = () => {\n const $dropDownActiveItem = document.querySelector(\n 'div.ant-select-item-option-active > div.ant-select-item-option-content > div.option-item'\n );\n\n if ($dropDownActiveItem) {\n const activeValue = $dropDownActiveItem.getAttribute('value');\n\n return activeValue;\n } else {\n return undefined;\n }\n };\n\n const handleInputKeyDown = async (e) => {\n if (e.key === 'Delete') {\n setValue([]);\n refValue.current = [];\n setEditing(false);\n return;\n }\n\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n await sleep(200);\n\n const activeValue = getActiveDropDownItem();\n\n if (activeValue !== undefined) {\n refValue.current = [activeValue];\n } else if (activeValue === undefined) {\n refValue.current = [refSearchValue.current];\n }\n }\n };\n\n const onSearch = (searchValue) => {\n const valid = isValidLength(searchValue);\n\n if (searchValue) {\n if (valid) {\n refSearchValue.current = searchValue;\n refValue.current = [searchValue];\n } else {\n const trimValue = maxLength\n ? searchValue.slice(0, maxLength)\n : searchValue;\n refSearchValue.current = trimValue;\n refValue.current = [trimValue];\n }\n }\n };\n\n const getTagValueInString = (valueArray) => {\n return valueArray.join(', ');\n };\n\n useImperativeHandle(ref, () => {\n return {\n getValue() {\n if (refValue.current === undefined) {\n return getTagValueInString(value);\n } else {\n const procValue = getTagValueInString(refValue.current);\n\n refValue.current = undefined;\n return procValue;\n }\n },\n };\n });\n\n const width = column.getActualWidth() || 300;\n\n return (\n 0,\n })}\n tabIndex={1}\n style={{ width }}\n >\n
\n \n {values?.map((valueItem, idx) => {\n const key =\n valueItemType === 'string' ? valueItem : valueItem?.value;\n const displayName =\n valueItemType === 'string' ? valueItem : valueItem?.displayName;\n\n return (\n \n
\n {displayName}\n
\n \n );\n })}\n \n {maxLength && (\n
\n \n {value?.[0]?.length || 0}/{maxLength}\n \n
\n )}\n \n \n \n
\n \n );\n});\n","import React, { useState, useEffect, useRef, useMemo } from 'react';\n\nimport { AgGridReact, AgGridColumn } from 'ag-grid-react';\n\nimport CheckboxRender from '../qa-grid-cell/CheckboxRender';\nimport StringTooltipRender from '../qa-grid-cell/StringTooltipRender';\nimport StatusRender from '../qa-grid-cell/StatusRender';\nimport DefaultCellRender from '../qa-grid-cell/DefaultCellRender';\nimport CountryEditorRender from '../qa-grid-cell/CountryEditorRender';\nimport CountryEditorRenderSnapshot from '../qa-grid-cell/CountryEditorRenderSnapshot';\nimport TextRender from '../qa-grid-cell/TextRender';\nimport TextRenderSnapshot from '../qa-grid-cell/TextRenderSnapshot';\nimport FileUploadRender from '../qa-grid-cell/FileUploadRender';\nimport FileUploadRenderSnapshot from '../qa-grid-cell/FileUploadRenderSnapshot';\nimport CheckboxRenderSnapshot from '../qa-grid-cell/CheckboxRenderSnapshot';\n\nimport { SelectionEditor } from '../qa-grid-cell/SelectionEditor';\nimport { CountryEditor } from '../qa-grid-cell/CountryEditor';\nimport { NumericEditor } from '../qa-grid-cell/NumericEditor';\nimport { CheckboxEditor } from '../qa-grid-cell/CheckboxEditor';\nimport { FreeTextSelector } from '../qa-grid-cell/FreeTextSelector';\nimport { FileUploadEditor } from '../qa-grid-cell/FileUploadEditor';\nimport { CountryEditorSingle } from '../qa-grid-cell/CountryEditorSingle';\nimport { TextEditor } from '../qa-grid-cell/TextEditor';\nimport { SelectionFreeText } from '../qa-grid-cell/SelectionFreeText';\n\nimport classnames from 'classnames';\n\nimport 'ag-grid-enterprise/dist/styles/ag-grid.css';\nimport 'ag-grid-enterprise/dist/styles/ag-theme-alpine.css';\nimport './QaGridEdit.less';\n\nconst QaGridEdit = (props) => {\n const {\n gridData = [],\n fields,\n gridInst,\n rowClassRules,\n getRowNodeId,\n onCellEditingStopped,\n isEdit,\n onRowSelected,\n snapshotGridValues,\n onReady,\n ...otherProps\n } = props;\n\n const gridRef = useRef();\n let refAllowEdit = useRef(false);\n\n const [gridApi, setGridApi] = useState(null);\n const [gridColumnApi, setGridColumnApi] = useState(null);\n\n const isCellEditable = (params) => {\n return refAllowEdit.current;\n };\n\n const columnTypes = useMemo(() => {\n return {\n editableColumn: {\n editable: (params) => {\n return isCellEditable(params);\n },\n cellStyle: (params) => {\n // if (isCellEditable(params)) {\n // return { backgroundColor: 'lightBlue' };\n // }\n },\n },\n };\n }, []);\n\n const onGridReady = (params) => {\n setGridApi(params.api);\n setGridColumnApi(params.columnApi);\n if (gridInst) {\n gridInst.current = {\n api: params.api,\n columnApi: params.columnApi,\n };\n\n onReady && onReady(params);\n }\n };\n\n const procField = useMemo(() => {\n const nullEditor = () => {};\n\n return fields.map((fieldItem) => {\n return {\n cellEditorSelector: nullEditor,\n ...fieldItem,\n };\n });\n }, [fields]);\n\n useEffect(() => {\n if (gridData && gridApi) {\n gridApi.refreshCells();\n }\n }, [gridData, gridApi]);\n\n useEffect(() => {\n if (gridApi) {\n gridApi.redrawRows();\n }\n }, [rowClassRules, gridApi, JSON.stringify(snapshotGridValues)]);\n\n useEffect(() => {\n refAllowEdit.current = isEdit;\n\n gridRef.current.api && gridRef.current.api.redrawRows();\n }, [isEdit]);\n\n const gridContext = useMemo(() => {\n return {\n snapshotGridValues,\n };\n }, [JSON.stringify(snapshotGridValues)]);\n\n return (\n
\n
\n \n {\n let rowData = [];\n params.api.forEachNode((node) => rowData.push(node.data));\n }}\n rowClassRules={rowClassRules}\n getRowNodeId={getRowNodeId}\n onCellEditingStopped={onCellEditingStopped}\n rowSelection='multiple'\n overlayNoRowsTemplate='No Rows to Show'\n onRowSelected={onRowSelected}\n singleClickEdit={true}\n alwaysShowHorizontalScroll={true}\n alwaysShowVerticalScroll={true}\n {...otherProps}\n >\n {procField &&\n procField?.length > 0 &&\n procField.map((fieldItem, idx) => {\n const cellRendererConfig = fieldItem?.cellRendererFramework\n ? { cellRenderer: fieldItem?.cellRenderer }\n : {};\n\n const cellEditorDefault = {\n cellEditorSelector: (params) => {\n return {\n component: 'TextEditor',\n popup: true,\n };\n },\n cellRenderer: 'TextRender',\n };\n\n const agGridColumnProps = {\n ...cellEditorDefault,\n ...fieldItem,\n ...cellRendererConfig,\n };\n\n return ;\n })}\n \n
\n
\n \n );\n};\n\nexport default QaGridEdit;\n","import React, { useEffect, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport { Row, Col, Typography, Input } from 'antd';\n\nimport { CustomNotification, WithLoading, Form } from 'common/components';\nimport { EditContainer } from 'pages/qa-spec/components';\n\nimport EditInputCountry from 'common/components/form/edit-input-country/EditInputCountry';\nimport { SectionWrapper } from 'common/components';\nimport CountryEditorRender from '../qa-grid-cell/CountryEditorRender';\n\nimport Messages from 'i18n/messages/qa-spec';\n\nimport {\n useGetQaSpecDataContact,\n useQueryQaContactDataSnapshot,\n} from './queries';\nimport { useGetQaSpecRequiredFieldsInQaSpecFullView } from 'pages/qa-spec/hooks/useGetQaSpecRequiredFields';\n\nimport { apiHandler } from 'utils/api';\nimport { saveQaSpecDataContact } from 'services/qaSpec';\nimport useCheckAssignProductToSupplier from 'pages/qa-spec/hooks/useCheckAssignProductToSupplier';\n\nimport { titleQAContactSection } from 'pages/qa-spec/constant';\nimport { QA_SPEC_CONTACT } from 'pages/qa-spec/constant';\nimport {\n SnapshotInputWrapper,\n SnapshotFormItemWrapper,\n} from 'pages/qa-spec/components/form';\n\nimport {\n EditTabSectionWrapper,\n EDIT_SECTION,\n} from 'pages/qa-spec/components/edit-tab-checker';\n\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\n\nimport { formatCompareValue } from 'pages/qa-spec/utils';\nimport { isEqual, get } from 'lodash';\n\nimport './QaSpecContact.less';\n\nconst { Text } = Typography;\n\nconst QaSpecContacts = ({ id }) => {\n const intl = useIntl();\n\n const { qaSpecDataContact, refetchQaSpecDataContact } =\n useGetQaSpecDataContact({\n id,\n isEnabled: !!id,\n });\n\n const successMessage = intl.formatMessage(\n Messages.updateQASpecContactSuccess\n );\n const errorMessage = intl.formatMessage(Messages.updateQASpecContactFailed);\n\n const { productId, ...propertyContact } = qaSpecDataContact;\n\n const { checkAssignProductToSupplier } = useCheckAssignProductToSupplier();\n const isProductAssignedByRetailer = checkAssignProductToSupplier();\n\n const { data: requiredFields } = useGetQaSpecRequiredFieldsInQaSpecFullView({\n productId,\n });\n\n const [form] = Form.useForm();\n const [loading, setLoading] = useState(false);\n\n const useSnapshot = useCheckSnapshotForRetailer();\n\n const { data: qaSpecContactDataSnapshot } = useQueryQaContactDataSnapshot({\n productId: id,\n enabled: Boolean(productId && useSnapshot),\n });\n\n useEffect(() => {\n form.setFieldsValue(propertyContact);\n }, [form, JSON.stringify(propertyContact)]);\n\n const onCancel = () => {\n form.resetFields();\n form.setFieldsValue(propertyContact);\n };\n\n const editQaSpecDataSuccessfully = () => {\n refetchQaSpecDataContact();\n setLoading(false);\n };\n\n const onFinallyEditSuccessfully = (toggleEdit) => {\n toggleEdit();\n };\n\n const onSaveHeader = async (toggleEdit) => {\n try {\n const values = await form.validateFields();\n setLoading(true);\n const params = { ...values, productId };\n apiHandler({\n service: saveQaSpecDataContact,\n params,\n successMessage,\n errorMessage,\n successCallback: editQaSpecDataSuccessfully,\n onFinally: () => onFinallyEditSuccessfully(toggleEdit),\n });\n } catch (error) {\n if (error?.errorFields?.length > 0) {\n CustomNotification.error('Please resolve errors in the Contact tab.');\n }\n setLoading(false);\n }\n };\n\n const layoutCol = {\n labelCol: {\n xxl: { span: 11 },\n xl: { span: 10 },\n },\n wrapperCol: {\n xxl: { span: 13 },\n xl: { span: 15 },\n },\n };\n\n const isRequiredFieldsForSupplier = Boolean(isProductAssignedByRetailer);\n\n const getSnapshotFormItemWrapperProps = ({ fieldPath, labelComp }) => {\n const snapshotFieldValue = get(qaSpecContactDataSnapshot, fieldPath);\n const procSnapshotFieldValue = formatCompareValue(snapshotFieldValue);\n\n return {\n checkShowSnapshotFn: ({ value }) => {\n const procValue = formatCompareValue(value);\n\n const isShowSnapshot =\n !isEqual(procValue, procSnapshotFieldValue) &&\n useSnapshot &&\n qaSpecContactDataSnapshot;\n\n return Boolean(isShowSnapshot);\n },\n snapshotValue: (\n \n
{labelComp}
\n \n {':'} {procSnapshotFieldValue}\n \n
\n ),\n };\n };\n\n const checkContactFieldRequired = ({ section, fieldName }) => {\n if (!isRequiredFieldsForSupplier) return false;\n if (!requiredFields) return false;\n\n const sectionMap = {\n primaryBusiness: 'primaryBusinessContact',\n primaryQc: 'primaryQcContact',\n _24Hour: '_24HourContact',\n };\n const requiredFieldSection = sectionMap[section];\n\n if (!requiredFieldSection) return false;\n\n return requiredFields.includes(\n `qaSpecification.qaSpecContacts.${requiredFieldSection}.${fieldName}`\n );\n };\n\n const renderField = (isEdit, fields, sectionKey) => {\n const inputCollection = {\n text: ,\n phone: ,\n country: isEdit ? (\n \n ) : (\n \n ),\n };\n\n return fields.map((field) => {\n const InputField = inputCollection[field.type];\n\n const label = intl.formatMessage(Messages?.[field.name]);\n\n const isRequired = checkContactFieldRequired({\n section: sectionKey,\n fieldName: field.name,\n });\n\n const fieldRule = field?.rules || [];\n const rules = [\n {\n required: isRequired,\n message: `${label ? label : 'This field'} is required`,\n },\n ...fieldRule,\n ];\n\n const labelComp = ;\n\n const FieldComponent = () => {\n if (useSnapshot) {\n return (\n \n {(inputWrapperProps) => (\n \n \n {InputField}\n \n \n )}\n \n );\n }\n\n return (\n \n {InputField}\n \n );\n };\n\n return {FieldComponent()};\n });\n };\n\n const renderSection = (isEdit, section) => {\n return (\n \n {renderField(isEdit, section.fields, section.key)}\n \n );\n };\n\n return (\n \n
\n \n {(edit) => {\n return (\n \n \n \n {Object.entries(QA_SPEC_CONTACT).map(([key, value]) => {\n return (\n \n {renderSection(edit, QA_SPEC_CONTACT[key])}\n \n );\n })}\n \n \n \n );\n }}\n \n \n
\n );\n};\n\nconst FormLabel = ({ label, type }) => {\n return (\n <>\n {type === 'phone' ? (\n
\n \n {label}\n \n
\n ) : (\n \n {label}\n \n )}\n \n );\n};\n\nexport default QaSpecContacts;\n","import React from 'react';\n\nimport { Input, DatePicker, Select } from 'antd';\n\nimport { Form, StyledModal } from 'common/components';\n\nimport * as constants from 'static/Constants';\n\nimport { DOCUMENT_CERTIFICATE_LIMIT_CHARACTER } from 'pages/qa-spec/constant';\n\nimport { WrapperSelect } from 'common/components';\n\nimport * as Const from 'static/Constants';\n\nconst ModalUpdateDocumentOrCertification = ({\n type,\n formInstance,\n ...otherProps\n}) => {\n const renderFormItemDocument = () => {\n return (\n \n \n prevValues !== currentValues\n }\n >\n {({ getFieldValue }) => {\n const options = Const.QA_SPEC_DOCUMENT_SUBTYPE.sort();\n\n return (\n \n \n {options.map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n );\n }}\n \n\n \n \n \n {/* \n \n */}\n \n );\n };\n\n const renderFormItemCertification = () => {\n return (\n \n \n \n {Const.DOCUMENT_CERTIFICATE_FIELD?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n \n \n \n \n \n \n \n \n \n \n );\n };\n\n return (\n \n {type === 'document'\n ? renderFormItemDocument()\n : renderFormItemCertification()}\n \n );\n};\n\nexport default ModalUpdateDocumentOrCertification;\n","import { useEffect } from 'react';\n\nimport { importFormDate } from 'utils/formatDate';\n\nexport const useSetFormUpdateDocsAndCertification = ({\n isEnabled,\n type,\n dataForm,\n formInstance,\n}) => {\n useEffect(() => {\n if (isEnabled) {\n if (type === 'document') {\n formInstance.setFieldsValue(dataForm);\n } else {\n const { certificateExpiryDate } = dataForm;\n formInstance.setFieldsValue({\n ...dataForm,\n certificateExpiryDate: importFormDate(certificateExpiryDate),\n });\n }\n }\n return;\n }, [dataForm, type, isEnabled, formInstance]);\n};\n","import { useState } from 'react';\n\nimport SnapshotCellWrapper from './SnapshotCellWrapper';\nimport { Button } from 'antd';\nimport { DownloadOutlined, EyeOutlined } from '@ant-design/icons';\nimport { CustomNotification } from 'common/components';\nimport PreviewableModal from 'common/components/previewable-modal/PreviewableModal';\n\nimport { checkShowPdfPreview } from 'utils/checkShowPdfPreview';\nimport * as api from 'config/axios';\nimport { isEqual } from 'lodash';\n\nconst CellActionRenderSnapshotWrapper = (props) => {\n const { children, isHighlightChange, snapshotValueRender, ...params } = props;\n const { context, rowIndex, data } = params;\n const { snapshotGridValues } = context || {};\n\n const snapshotData = snapshotGridValues?.[rowIndex];\n\n const defaultIsHighlightChange = !isEqual(\n snapshotData?.linkUrl,\n data?.linkUrl\n );\n\n return (\n \n )\n }\n >\n {children && children}\n \n );\n};\n\nconst CellActionSnapshot = (props) => {\n const { snapshotData } = props;\n const [visible, setVisible] = useState(false);\n const [rowPreview, setRowPreview] = useState();\n\n const { linkPreview, extensionFile } = checkShowPdfPreview(\n rowPreview?.pdfPreview,\n rowPreview?.linkUrl,\n rowPreview?.fileType\n );\n\n return (\n <>\n }\n onClick={() => {\n setRowPreview(snapshotData);\n setVisible(true);\n }}\n disabled={!snapshotData}\n />\n }\n onClick={() => {\n const downloadUrl = snapshotData?.linkUrl;\n\n if (!downloadUrl) {\n CustomNotification.error('Could not download file!');\n }\n api.sendDownload({\n url: downloadUrl,\n });\n }}\n disabled={!snapshotData}\n />\n {visible && (\n setVisible(false)}\n downloadLink={rowPreview?.linkUrl}\n isDownload={false}\n fileType={extensionFile}\n fileSize={rowPreview?.fileSize}\n isDocument={true}\n />\n )}\n \n );\n};\n\nexport default CellActionRenderSnapshotWrapper;\n","import { formatMDY } from 'utils/formatDate';\nimport TextRenderSnapshot from 'pages/qa-spec/components/qa-grid-cell/TextRenderSnapshot';\nimport CellActionRenderSnapshotWrapper from 'pages/qa-spec/components/qa-grid-cell/CellActionRenderSnapshotWrapper';\n\nexport const getCellRenderer = ({\n snapshotGridValues,\n useSnapshot,\n CellRenderAction,\n}) => {\n return useSnapshot\n ? {\n TextRender: 'TextRenderSnapshot',\n TextRenderForDate: (params) => {\n const { column, rowIndex } = params;\n\n const cellSnapshotValue =\n snapshotGridValues?.[rowIndex]?.[column.colId];\n\n const snapshotValueRender = cellSnapshotValue\n ? formatMDY(cellSnapshotValue)\n : 'N/A';\n\n return (\n \n );\n },\n CellRenderAction: (params) => {\n return (\n \n \n \n );\n },\n }\n : {\n TextRender: 'TextRender',\n TextRenderForDate: 'TextRender',\n CellRenderAction,\n };\n};\n","import { useQueryClient, useQuery } from '@tanstack/react-query';\nimport * as productServices from 'services/product';\n\nconst qaSpecDocAndCerKeys = {\n docsSnapshot: (productId) => [\n 'pim',\n 'snapshot',\n parseInt(productId),\n 'qa-spec-doc/cer-docs',\n ],\n certsSnapshot: (productId) => [\n 'pim',\n 'snapshot',\n parseInt(productId),\n 'qa-spec-doc/cer-certs',\n ],\n};\n\nexport const useQueryQaSpecDocumentSnapshotData = ({\n productId,\n ...options\n}) => {\n return useQuery({\n queryKey: qaSpecDocAndCerKeys.docsSnapshot(productId),\n queryFn: async () => {\n const { isSuccess, data, message } =\n await productServices.getQaSpecSnapshotDataDocument({ productId });\n if (isSuccess) {\n return data;\n }\n\n return Promise.reject(message || 'Server Error');\n },\n ...options,\n });\n};\n\nexport const useQueryQaSpecCertificateSnapshotData = ({\n productId,\n ...options\n}) => {\n return useQuery({\n queryKey: qaSpecDocAndCerKeys.certsSnapshot(productId),\n queryFn: async () => {\n const { isSuccess, data, message } =\n await productServices.getQaSpecSnapshotDataCertificate({ productId });\n if (isSuccess) {\n return data;\n }\n\n return Promise.reject(message || 'Server Error');\n },\n ...options,\n });\n};\n\nexport const getQaCertificatesDataQueryKey = (productId) => {\n return [\n 'pim',\n 'get-qa-spec-data-certificates',\n { params: { productId: parseInt(productId) } },\n ];\n};\n\nexport const useGetQaCertificatesData = ({ productId }, options) => {\n const queryClient = useQueryClient();\n\n const invalidateQuery = () => {\n queryClient.invalidateQueries({\n queryKey: getQaCertificatesDataQueryKey(productId),\n });\n };\n const query = useQuery({\n queryKey: getQaCertificatesDataQueryKey(productId),\n ...options,\n });\n\n return { ...query, invalidateQuery };\n};\n","import React, {\n useEffect,\n useState,\n useCallback,\n useRef,\n useMemo,\n} from 'react';\nimport PropTypes from 'prop-types';\nimport { useSelector } from 'react-redux';\n\nimport {\n DownloadOutlined,\n DeleteOutlined,\n EyeOutlined,\n EditOutlined,\n} from '@ant-design/icons';\nimport classnames from 'classnames';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { Row, Col, Typography, Button, Space } from 'antd';\n\nimport {\n Form,\n FormButton,\n dialogFunction,\n CustomNotification,\n FormCancelButton,\n FormEditButton,\n} from 'common/components';\nimport ModalUpdateDocumentOrCertification from './ModalUpdateDocsAndCertificates';\nimport PreviewableModal from 'common/components/previewable-modal/PreviewableModal';\nimport AddAssetPimModal from 'pages/product-full-view/components/modal/add-asset-pim-modal';\n\nimport * as qaSelectors from 'pages/qa-spec/controllers/selectors';\n\nimport { useSetFormUpdateDocsAndCertification } from './hooks';\nimport { useCheckQaSpecLocked } from 'pages/qa-spec/hooks/useCheckQaSpecLocked';\nimport { useCheckAllowEdit } from 'pages/qa-spec/hooks';\nimport { useTabExpand } from 'hooks/useTabExpandProduct';\nimport { useReloadDocumentCertificateTab } from 'hooks/useReloadDocumentCertificateTab';\n\nimport { bytesToMegaBytes } from 'utils/string';\nimport { formatMDY, exportFormDate } from 'utils/formatDate';\nimport { checkShowPdfPreview } from 'utils/checkShowPdfPreview';\n\nimport { getQaContainTabDataQueryKey } from 'pages/qa-spec/components/qa-product-contain/queries';\n\nimport * as api from 'config/axios';\nimport * as services from 'services/product';\nimport * as servicesQaSpec from 'services/qaSpec';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/qa-spec';\n\nimport 'ag-grid-enterprise/dist/styles/ag-grid.css';\nimport 'ag-grid-enterprise/dist/styles/ag-theme-alpine.css';\n\nimport { QaGridEdit } from 'pages/qa-spec/components';\n\nimport { getCellRenderer } from './utils';\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\nimport {\n useQueryQaSpecCertificateSnapshotData,\n useQueryQaSpecDocumentSnapshotData,\n} from './queries';\n\nimport './QaSpecDocsAndCertificates.less';\n\nconst QaSpecDocsAndCertificates = ({ productId }) => {\n const intl = useIntl();\n const docGridRef = useRef(null);\n const cerGridRef = useRef(null);\n const queryClient = useQueryClient();\n\n const reloadDocumentAndCertificateTab = useSelector(\n qaSelectors.selectReloadDocumentAndCertificate()\n );\n\n const [rowDataDoc, setRowDataDoc] = useState([]);\n const [rowDataCer, setRowDataCer] = useState([]);\n const [isLinkToNewAssetModalOpen, setIsLinkToNewAssetModalOpen] =\n useState(false);\n const [addType, setAddStype] = useState('');\n const [visible, setVisible] = useState(false);\n\n const [isEdit, setIsEdit] = useState(false);\n\n const [isEditCer, setIsEditCer] = useState(false);\n\n const [rowPreview, setRowPreview] = useState();\n\n const [formInstance] = Form.useForm();\n\n const [selectedRow, setSelectedRow] = useState({\n document: null,\n certificate: null,\n });\n\n const [visibleModalUpdate, setVisibleModalUpdate] = useState({\n type: null,\n value: false,\n });\n\n const useSnapshot = useCheckSnapshotForRetailer(productId);\n const { data: snapshotDocsData } = useQueryQaSpecDocumentSnapshotData({\n productId,\n enabled: Boolean(productId && useSnapshot),\n });\n const { data: snapshotCertsData } = useQueryQaSpecCertificateSnapshotData({\n productId,\n enabled: Boolean(productId && useSnapshot),\n });\n\n const snapshotDocsGridData = snapshotDocsData?.documents;\n const snapshotCertsGridData = snapshotCertsData?.certificates;\n\n const { tableStyle } = useTabExpand();\n\n const { toggleReloadDocumentWhenDelete } = useReloadDocumentCertificateTab();\n\n useSetFormUpdateDocsAndCertification({\n isEnabled: Boolean(visibleModalUpdate.value),\n type: visibleModalUpdate.type,\n formInstance,\n dataForm:\n visibleModalUpdate.type === 'document'\n ? selectedRow.document\n : selectedRow.certificate,\n });\n\n const { isQASpecLocked } = useCheckQaSpecLocked();\n\n const { linkPreview, extensionFile } = checkShowPdfPreview(\n rowPreview?.pdfPreview,\n rowPreview?.linkUrl,\n rowPreview?.fileType\n );\n\n const invalidateData = () => {\n //* reload product contain tab\n queryClient.invalidateQueries({\n queryKey: getQaContainTabDataQueryKey(productId),\n });\n };\n\n const handleDelete = useCallback((linkId, isDocumentType) => {\n services\n .qaSpecUnLinkToDocCer({ linkId: linkId })\n .then((response) => {\n const name = isDocumentType ? 'Document' : 'Certificate';\n if (response?.isSuccess) {\n CustomNotification.success(\n intl.formatMessage(Messages.qaSpecDocsAndCerRemoveMessageSuccess, {\n name,\n })\n );\n if (isDocumentType) {\n getQaSpecDoc();\n clearSelectedRow('document');\n toggleReloadDocumentWhenDelete();\n return;\n }\n\n getQaSpecCer();\n clearSelectedRow('certificate');\n //* reload product contain tab\n invalidateData();\n } else {\n CustomNotification.error(response?.message);\n }\n })\n .catch((e) => {})\n .finally(() => {});\n }, []);\n\n const handleDeleteModal = useCallback(\n (linkId, isDocumentType) => {\n dialogFunction({\n type: 'warn',\n content: 'Are you sure you want to delete the selected item?',\n okText: 'Delete',\n okButtonProps: {\n type: 'danger',\n },\n onOk: () => handleDelete(linkId, isDocumentType),\n });\n },\n [handleDelete]\n );\n\n const CellRenderAction = useCallback(\n (params) => {\n const isDocumentType = params?.data.hasOwnProperty('documentName');\n\n return (\n <>\n }\n onClick={() => {\n setRowPreview(params?.data);\n setVisible(true);\n }}\n />\n }\n onClick={() => {\n const downloadUrl = params?.data?.linkUrl;\n\n if (!downloadUrl) {\n CustomNotification.error('Could not download file!');\n }\n api.sendDownload({\n url: downloadUrl,\n });\n }}\n />\n {!isQASpecLocked ? (\n }\n onClick={() => {\n handleDeleteModal(params?.data?.linkId, isDocumentType);\n }}\n />\n ) : null}\n \n );\n },\n [isQASpecLocked, handleDeleteModal]\n );\n\n const formatFileSize = (params) => {\n return `${bytesToMegaBytes(params.value)} MB`;\n };\n\n const columnDefsDoc = useMemo(() => {\n const cellRenderer = getCellRenderer({\n snapshotGridValues: snapshotDocsGridData,\n useSnapshot,\n CellRenderAction,\n });\n\n const cols = [\n {\n dataType: 'string',\n displayName: 'Document Name',\n field: 'documentName',\n fieldNameCamelCase: 'documentName',\n cellRenderer: cellRenderer['TextRender'],\n },\n // {\n // dataType: 'string',\n // displayName: 'Document Type',\n // fieldName: 'documentType',\n // fieldNameCamelCase: 'documentType',\n // },\n {\n dataType: 'string',\n displayName: 'Type',\n field: 'type',\n fieldNameCamelCase: 'type',\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n dataType: 'string',\n displayName: 'Sub Type',\n field: 'subtype',\n fieldNameCamelCase: 'subtype',\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n dataType: 'string',\n displayName: 'File Type',\n field: 'fileType',\n fieldNameCamelCase: 'fileType',\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n dataType: 'string',\n displayName: 'File Size',\n field: 'fileSize',\n fieldNameCamelCase: 'fileSize',\n valueGetter: (params) => {\n return `${bytesToMegaBytes(params?.data.fileSize)} MB`;\n },\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n dataType: 'DateTime',\n displayName: 'Upload Date',\n field: 'uploadDate',\n fieldName: 'uploadData',\n fieldNameCamelCase: 'uploadDate',\n valueGetter: ({ data }) => formatMDY(data?.['uploadDate']),\n cellRenderer: cellRenderer['TextRenderForDate'],\n },\n {\n displayName: '',\n field: 'actions',\n cellRenderer: cellRenderer['CellRenderAction'],\n cellRendererParams: {\n isDocumentType: true,\n },\n },\n ];\n\n return cols.map((fieldItem) => {\n const nullCellEditor = () => {};\n\n return {\n cellEditorSelector: nullCellEditor,\n ...fieldItem,\n minWidth: 100,\n width: 200,\n flex: fieldItem?.fieldName === 'actions' ? 0 : 1,\n };\n });\n }, [useSnapshot, CellRenderAction, JSON.stringify(snapshotDocsGridData)]);\n\n const columnDefsCer = useMemo(() => {\n const cellRenderer = getCellRenderer({\n snapshotGridValues: snapshotCertsGridData,\n useSnapshot,\n CellRenderAction,\n });\n\n const cols = [\n {\n dataType: 'string',\n displayName: 'Certificate',\n field: 'certificate',\n fieldNameCamelCase: 'certificate',\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n dataType: 'string',\n displayName: 'Certificate Type',\n field: 'certificateType',\n fieldNameCamelCase: 'certificateType',\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n dataType: 'string',\n displayName: 'Certificate Body',\n field: 'certificateBody',\n fieldNameCamelCase: 'certificateBody',\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n dataType: 'DateTime',\n displayName: 'Certificate Expiry Date',\n field: 'certificateExpiryDate',\n fieldNameCamelCase: 'certificateExpiryDate',\n valueGetter: ({ data }) => formatMDY(data?.['certificateExpiryDate']),\n cellRenderer: cellRenderer['TextRenderForDate'],\n },\n {\n displayName: '',\n field: 'actions',\n cellRenderer: cellRenderer['CellRenderAction'],\n },\n ];\n\n return cols.map((fieldItem) => {\n const nullCellEditor = () => {};\n\n return {\n cellEditorSelector: nullCellEditor,\n ...fieldItem,\n minWidth: 100,\n width: 200,\n flex: fieldItem?.fieldName === 'actions' ? 0 : 1,\n };\n });\n }, [useSnapshot, CellRenderAction, JSON.stringify(snapshotCertsGridData)]);\n\n const getQaSpecDoc = useCallback(() => {\n services\n .getQaSpeecDataDocument({ productId })\n .then((response) => {\n if (response?.isSuccess && response?.data?.documents)\n setRowDataDoc(response?.data?.documents);\n })\n .catch((e) => {})\n .finally(() => {});\n }, [productId]);\n\n const getQaSpecCer = useCallback(() => {\n services\n .getQaSpeecDataCertificate({ productId })\n .then((response) => {\n if (response?.isSuccess && response?.data?.certificates)\n setRowDataCer(response?.data?.certificates);\n })\n .catch((e) => {})\n .finally(() => {});\n }, [productId]);\n\n const fetchQaSpecDocAndCer = () => {\n getQaSpecDoc();\n getQaSpecCer();\n };\n\n useEffect(() => {\n fetchQaSpecDocAndCer();\n }, []);\n\n useEffect(() => {\n if (reloadDocumentAndCertificateTab) {\n fetchQaSpecDocAndCer();\n }\n }, [reloadDocumentAndCertificateTab]);\n\n const clearSelectedRow = (grid) => {\n setSelectedRow((prevState) => ({ ...prevState, [grid]: null }));\n\n const gridInstance =\n grid === 'document' ? docGridRef?.current : cerGridRef?.current;\n\n gridInstance.api.deselectAll();\n };\n\n const reloadGrid = () => {\n if (addType === 'Document') {\n clearSelectedRow('document');\n getQaSpecDoc();\n } else {\n clearSelectedRow('certificate');\n getQaSpecCer();\n }\n handleToggleLinkAssetModal();\n };\n\n const handleToggleLinkAssetModal = () => {\n setIsLinkToNewAssetModalOpen((prev) => !prev);\n };\n\n const handleNewDoc = () => {\n setAddStype('Document');\n handleToggleLinkAssetModal();\n };\n const handleNewCer = () => {\n setAddStype('Certificate');\n handleToggleLinkAssetModal();\n };\n\n const toggleEditMode = useCallback(() => {\n setIsEdit((prev) => !prev);\n }, []);\n const toggleEditModeCer = useCallback(() => {\n setIsEditCer((prev) => !prev);\n }, []);\n\n const onCancel = () => {\n toggleEditMode();\n docGridRef?.current?.api.deselectAll();\n setSelectedRow((prevRow) => ({\n ...prevRow,\n document: null,\n }));\n };\n const onCancelCer = () => {\n toggleEditModeCer();\n cerGridRef?.current?.api.deselectAll();\n setSelectedRow((prevRow) => ({\n ...prevRow,\n certificate: null,\n }));\n };\n\n const onCancelModalUpdate = () => {\n setVisibleModalUpdate({\n type: '',\n value: false,\n });\n };\n\n const handleUpdateDocsAndCertificate = async () => {\n const values = await formInstance.validateFields();\n const isDocumentType = visibleModalUpdate.type === 'document';\n const name = isDocumentType ? 'Document' : 'Certificate';\n let params = {};\n\n try {\n if (isDocumentType) {\n params = {\n ...params,\n linkId: selectedRow?.document?.linkId,\n documentName: values.documentName,\n subtype: values?.subtype,\n documentType: selectedRow?.document?.documentType,\n type: selectedRow?.document?.type,\n };\n } else {\n params = {\n ...params,\n documentType: selectedRow?.certificate?.type,\n type: selectedRow?.certificate?.type,\n subtype: selectedRow?.certificate?.subtype,\n linkId: selectedRow?.certificate?.linkId,\n certificate: values.certificate,\n certificateBody: values.certificateBody,\n certificateExpiryDate: exportFormDate(values.certificateExpiryDate),\n certificateType: values?.certificateType,\n };\n }\n\n const response = await servicesQaSpec.updateDocumentOrCertification(\n params\n );\n\n if (response?.isSuccess) {\n CustomNotification.success(\n intl.formatMessage(Messages.qaSpecDocsAndCerUpdateMessageSuccess, {\n name,\n })\n );\n onCancelModalUpdate();\n if (isDocumentType) {\n getQaSpecDoc();\n clearSelectedRow('document');\n toggleReloadDocumentWhenDelete();\n } else {\n getQaSpecCer();\n clearSelectedRow('certificate');\n //* reload product contain tab\n invalidateData();\n }\n } else {\n CustomNotification.error(response?.message ?? ' Something went wrong');\n }\n } catch (error) {}\n };\n\n const hasPermissionEdit = useCheckAllowEdit(productId);\n\n return (\n
\n \n \n \n \n \n \n \n \n \n Documents\n \n \n {!isQASpecLocked ? (\n <>\n {isEdit && (\n \n \n \n\n \n setVisibleModalUpdate({\n value: true,\n type: 'document',\n })\n }\n />\n \n \n \n )}\n {!isEdit && hasPermissionEdit && (\n \n }\n onClick={toggleEditMode}\n style={{ border: 'none' }}\n />\n \n )}\n \n ) : null}\n \n \n \n \n {columnDefsDoc && columnDefsDoc.length > 0 && (\n \n {\n if (!event?.node?.selected) return;\n\n setSelectedRow((prevRow) => ({\n ...prevRow,\n document: event.data,\n }));\n }}\n fields={columnDefsDoc}\n snapshotGridValues={snapshotDocsGridData}\n defaultColDef={{ resizable: true }}\n isEdit={isEdit}\n />\n \n )}\n \n \n \n \n \n \n \n \n \n \n Certificates\n \n \n {!isQASpecLocked ? (\n <>\n {isEditCer && (\n \n \n \n \n setVisibleModalUpdate({\n value: true,\n type: 'certificate',\n })\n }\n />\n \n \n \n )}\n {!isEditCer && hasPermissionEdit && (\n \n }\n onClick={toggleEditModeCer}\n style={{ border: 'none' }}\n />\n \n )}\n \n ) : null}\n \n \n \n \n {columnDefsCer && columnDefsCer.length > 0 && (\n \n {\n if (!event?.node?.selected) return;\n\n setSelectedRow((prevRow) => ({\n ...prevRow,\n certificate: event.data,\n }));\n }}\n fields={columnDefsCer}\n defaultColDef={{ resizable: true }}\n isEdit={isEdit}\n snapshotGridValues={snapshotCertsGridData}\n />\n \n )}\n \n \n \n \n \n \n {isLinkToNewAssetModalOpen && (\n \n )}\n {visible && (\n setVisible(false)}\n downloadLink={rowPreview?.linkUrl}\n isDownload={false}\n fileType={extensionFile}\n fileSize={rowPreview?.fileSize}\n isDocument={true}\n />\n )}\n\n {visibleModalUpdate.value && (\n \n )}\n \n \n \n
\n );\n};\n\nQaSpecDocsAndCertificates.propTypes = {\n productItemModules: PropTypes.object,\n};\nexport default QaSpecDocsAndCertificates;\n","import React, { useState } from 'react';\nimport { injectIntl } from 'react-intl';\nimport { useDispatch } from 'react-redux';\nimport { ArrowLeftOutlined } from '@ant-design/icons';\n\nimport { Row, Col, Select, Input, Space } from 'antd';\n\nimport {\n Form,\n FormCancelButton,\n FormCreateButton,\n WrapperSelect,\n CustomNotification,\n} from 'common/components';\n\nimport { qaSpecLinkProductToMSDSDocument } from 'services/product';\nimport * as constants from 'static/Constants';\nimport { sleep } from 'utils/delay';\n\nimport * as brandingActions from '@redux/branding/actions';\n\nimport { DOCUMENT_CERTIFICATE_LIMIT_CHARACTER } from 'pages/qa-spec/constant';\n\nconst layoutCol = {\n labelCol: {\n xxl: { span: 10 },\n xl: { span: 10 },\n },\n wrapperCol: {\n xxl: { span: 12 },\n xl: { span: 12 },\n },\n};\n\nconst CreateMSDSDocumentForm = (props) => {\n const { assetId, onReloadPage, productInfo, handleBackToCreateAsset } = props;\n\n const [loading, setLoading] = useState('');\n\n const [msdsDocForm] = Form.useForm();\n\n const dispatch = useDispatch();\n\n const specificInformationSectionView = () => {\n return (\n \n <>\n \n \n {constants.ASSET_TYPE?.slice()\n .sort()\n .map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n\n \n \n {['MSDS'].map((item, index) => {\n return (\n \n {item}\n \n );\n })}\n \n \n \n\n \n \n \n\n \n \n );\n };\n\n const createMSDSDoc = () => {\n msdsDocForm\n .validateFields()\n .then(async () => {\n let documentName = msdsDocForm.getFieldValue('documentName');\n\n setLoading('add');\n\n const qaSpecLinkDocumentParams = {\n digitalAssetId: assetId,\n productItemId: productInfo.productId,\n documentName: documentName,\n };\n\n const linkResponse = await qaSpecLinkProductToMSDSDocument(\n qaSpecLinkDocumentParams\n );\n\n //* BE doest not update link data instantly\n await sleep(1000);\n\n if (linkResponse.isSuccess) {\n CustomNotification.success(\n 'Link data has been updated successfully!'\n );\n onReloadPage && onReloadPage();\n } else {\n CustomNotification.error('Link data has been updated failed!');\n }\n setLoading('');\n dispatch(brandingActions.getBrandingNoLoading());\n })\n .catch((e) => {\n if (e?.errorFields?.length > 0) {\n CustomNotification.error('Please fill out all required fields');\n } else {\n CustomNotification.error('Failed to submit form');\n }\n });\n };\n\n return (\n \n {specificInformationSectionView()}\n\n \n \n \n \n }\n onClick={() =>\n handleBackToCreateAsset && handleBackToCreateAsset()\n }\n disabled={loading}\n />\n\n \n \n \n \n \n \n );\n};\n\nexport default injectIntl(CreateMSDSDocumentForm);\n","import React, { useState } from 'react';\n\nimport { useParams } from 'react-router-dom';\n\nimport PropTypes from 'prop-types';\n\n//? COMPONENT\nimport { Form, Row, Col, Modal, Steps } from 'antd';\n\nimport {\n StyledModal,\n StepForm,\n WithAbsoluteContainer,\n} from 'common/components';\nimport CreateMSDSDocumentForm from 'pages/product-full-view/components/modal/add-document-msds/CreateMSDSDocumentForm';\nimport UploadPimAsset from 'pages/product-full-view/components/modal/add-asset-pim-modal/UploadPimAsset';\n\n//? REDUX\nimport { useGetProductFullView } from 'hooks';\n\nconst currentStepDefine = [0, 1];\nconst stepDefault = currentStepDefine[0];\n\nconst assetIdDefine = [null, '', Number];\nconst assetIdDefault = assetIdDefine[0];\n\nconst { Step } = Steps;\n\nconst CreateMSDSDocumentModal = (props) => {\n const { onCloseModal, getDocument } = props;\n\n const [preview, setPreview] = useState(null);\n const [assetId, setAssetId] = useState(assetIdDefault);\n const [currentStep, setCurrentStep] = useState(stepDefault);\n const [isAllowedUpload, setIsAllowedUpload] = useState(false);\n\n const { id: productId } = useParams();\n\n const { productFull } = useGetProductFullView({ productId });\n\n const productInfo = props.productDetail || productFull;\n\n const [formInstance] = Form.useForm();\n\n const onSelectAttachFile = (fileList) => {\n if (!fileList) return;\n const file = fileList.slice(-1).pop();\n if (!file) return;\n\n setAssetId(assetIdDefault);\n\n if (file?.status === 'error.fileType') {\n setIsAllowedUpload(false);\n return;\n }\n\n setIsAllowedUpload(true);\n };\n\n const handleCancelPreview = () => setPreview({ previewVisible: false });\n\n const handleBackToCreateAsset = () => setCurrentStep(0);\n\n const handleMoveToLinkAsset = () => setCurrentStep(1);\n\n const handleUploadSuccess = (res) => {\n if (!res?.data) return;\n\n const { data } = res?.data;\n\n if (!assetId) {\n setAssetId(data?.assetId);\n }\n handleMoveToLinkAsset();\n setIsAllowedUpload(false);\n };\n\n //!- RENDER\n const stepDefine = [\n {\n step: 0,\n component: (\n \n ),\n },\n {\n step: 1,\n component: (\n {\n getDocument && getDocument();\n }}\n />\n ),\n },\n ];\n\n return (\n setCurrentStep((prev) => prev + 1)}\n maskClosable={false}\n footer={null}\n visible\n destroyOnClose\n >\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nCreateMSDSDocumentModal.propTypes = {\n addType: PropTypes.string,\n onCloseModal: PropTypes.func,\n getImagery: PropTypes.func,\n};\n\nexport default CreateMSDSDocumentModal;\n","import React, { useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport { useDispatch } from 'react-redux';\nimport { UploadOutlined } from '@ant-design/icons';\n\nimport classnames from 'classnames';\nimport {\n Row,\n Col,\n Button,\n Typography,\n Space,\n Select,\n Tooltip,\n Input,\n} from 'antd';\nimport {\n PlusOutlined,\n MinusCircleOutlined,\n CloseOutlined,\n} from '@ant-design/icons';\nimport { sortBy } from 'lodash';\n\nimport {\n Form,\n SectionWrapper,\n WithLoading,\n TargetMarketInput,\n WrapperSelect,\n CustomNotification,\n} from 'common/components';\nimport { EditContainer, CountryEditorRender } from 'pages/qa-spec/components';\nimport AddAssetPimModal from 'pages/product-full-view/components/modal/add-asset-pim-modal';\nimport DietaryCertificateUploadBtn from './DietaryCertificateUploadBtn';\nimport {\n EditTabSectionWrapper,\n EDIT_SECTION,\n} from 'pages/qa-spec/components/edit-tab-checker';\nimport EditInputCountry from 'common/components/form/edit-input-country/EditInputCountry';\n\nimport { qaToggleReloadDocumentCertificateTab } from 'pages/qa-spec/controllers/actions';\n\nimport {\n useProductSpecInfo,\n useAutoFocusAddedField,\n useMutationUploadCertificate,\n checkIsInvalidCountryOfOrigin,\n} from 'pages/qa-spec/hooks/useProductSpecInfo';\nimport { findProductPropertyEnums } from 'pages/product-full-view/components/product-detail-view/utils';\n\nimport { useGetEnumsByEnumName, useGetProductEnums } from 'hooks';\n\nimport {\n DAIRY_SECTION_TEXT_AREA,\n DAIRY_SECTION_TEXT_AREA_2,\n MINIMUM_INPUT_FIELD,\n PRODUCT_SPEC_FORM_SECTION_SCHEMA,\n} from '../../constant';\n\nimport Messages from 'i18n/messages/qa-spec';\nimport CreateMSDSDocumentModal from 'pages/product-full-view/components/modal/add-document-msds/CreateMSDSDocumentModal';\nimport {\n HighlightContent,\n PrimaryFieldSnapshot,\n RetailerSnapshot,\n} from './snapshot/RetailerSnapshot';\n\nimport UploadCertificate from './UploadCertificate';\nimport sortByKey from 'utils/sortByKey';\n\nimport useCheckAssignProductToSupplier from 'pages/qa-spec/hooks/useCheckAssignProductToSupplier';\nimport { useGetQaSpecSnapshot } from './snapshot/hooks';\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\n\nimport { useGetQaSpecRequiredFieldsInQaSpecFullView } from 'pages/qa-spec/hooks/useGetQaSpecRequiredFields';\nimport { useGetEnumOptions } from 'pages/qa-spec/hooks';\nimport {\n IXONECertificationWrapper,\n TYPE_VIEW,\n} from 'common/components/product-add/IXONECertificationWrapper';\n\nconst { Text } = Typography;\n\nconst { Option } = Select;\n\nconst { TextArea } = Input;\n\nconst QaSpecProductInfo = (props) => {\n const { productLoading, refetchProductItems, productId, productFull } = props;\n const intl = useIntl();\n const [form] = Form.useForm();\n const dispatch = useDispatch();\n\n const editContainerRef = useRef();\n\n const [isLinkToNewAssetModalOpen, setIsLinkToNewAssetModalOpen] =\n useState(false);\n\n const { dataQaSpecSnapshot } = useGetQaSpecSnapshot();\n\n const [visible, setVisible] = useState(false);\n const [isAddDocumentForMSDS, setIsAddDocumentForMSDS] = useState(false);\n const [certificateType, setCertificateType] = useState();\n\n const { mutationUploadCertificate } = useMutationUploadCertificate({\n id: productId,\n });\n\n const { checkAssignProductToSupplier } = useCheckAssignProductToSupplier();\n const { data: requiredFields } = useGetQaSpecRequiredFieldsInQaSpecFullView({\n productId,\n });\n\n const isProductAssignedByRetailer = checkAssignProductToSupplier();\n\n const isRequiredCountryOfOrigin =\n isProductAssignedByRetailer &&\n requiredFields?.includes(\n 'qaSpecification.qaSpecProductSpecification.countryOfOrigin'\n );\n\n const {\n dataProductSpec,\n loading,\n isSubmitted,\n countryOfOrigin,\n setCountryOfOrigin,\n nonfoodIngredientStatement,\n setNonfoodIngredientStatement,\n onSubmit,\n onValuesChange,\n disabledCertifier,\n checkRequiredField,\n onCancel,\n } = useProductSpecInfo({\n productId,\n form,\n productLoading,\n refetchProductItems,\n isRequiredCountryOfOrigin,\n });\n\n const { productEnums } = useGetProductEnums();\n\n const countryCodeEnum = productEnums?.filter(\n (type) => type.enumName === 'CountryCodeEnum'\n );\n\n const countrySubDivisionEnum = productEnums?.filter(\n (type) => type.enumName === 'CountrySubDivisionCodeISO3166_2Enum'\n );\n\n const languageCodeEnum = productEnums?.filter(\n (type) => type.enumName === 'LanguageCodeEnum'\n );\n\n const enumOptions = useGetEnumOptions()?.productSpec;\n\n const kosherCertifier = Form.useWatch('kosherCertifier', form) || [];\n const organicCertifier = Form.useWatch('organicCertifier', form) || [];\n const halalCertifier = Form.useWatch('halalCertifier', form) || [];\n const nonGMOCertifier = Form.useWatch('nonGMOCertifier', form) || [];\n const ISOCertifier = Form.useWatch('ISOCertifier', form) || [];\n const BRCCertifier = Form.useWatch('BRCCertifier', form) || [];\n const IFSCertifier = Form.useWatch('IFSCertifier', form) || [];\n const selectedCertifier = [\n ...kosherCertifier,\n ...organicCertifier,\n ...halalCertifier,\n ...nonGMOCertifier,\n ...ISOCertifier,\n ...BRCCertifier,\n ...IFSCertifier,\n ];\n\n const layoutCol = {\n labelCol: { span: 12 },\n wrapperCol: {\n span: 12,\n },\n };\n\n const { inputRef, onAddField } = useAutoFocusAddedField();\n\n const msdsWatch = Form.useWatch('msds', form);\n\n const handleAddCountryOfOrigin = () => {\n if (countryOfOrigin) {\n setCountryOfOrigin((s) => s.concat({}));\n } else {\n setCountryOfOrigin([{}]);\n }\n };\n\n const handleRemoveCountryOfOrigin = (index) => {\n setCountryOfOrigin(countryOfOrigin.filter((val, i) => index !== i));\n };\n const handleAddNIStatement = () => {\n if (nonfoodIngredientStatement) {\n setNonfoodIngredientStatement((s) => s.concat({}));\n } else {\n setNonfoodIngredientStatement([{}]);\n }\n };\n\n const handleRemoveNIStatement = (index) => {\n setNonfoodIngredientStatement(\n nonfoodIngredientStatement.filter((val, i) => index !== i)\n );\n };\n const openModalToUploadCertificate = (_certificateType) => {\n setIsLinkToNewAssetModalOpen((prev) => !prev);\n setCertificateType(_certificateType);\n };\n\n const handleCloseModalUploadCertificate = () => {\n setIsLinkToNewAssetModalOpen((prev) => !prev);\n setCertificateType(null);\n dispatch(qaToggleReloadDocumentCertificateTab());\n };\n\n const handCloseModalUploadDocMSDS = () => {\n setIsAddDocumentForMSDS((prev) => !prev);\n dispatch(qaToggleReloadDocumentCertificateTab());\n setCertificateType(null);\n };\n\n const handleOpenModalMSDSDocument = () => {\n setIsAddDocumentForMSDS(true);\n };\n\n const eggsGradingList = useGetEnumsByEnumName('EggsGradingEnum');\n const usdaGradingList = useGetEnumsByEnumName('UsdaGradingEnum');\n\n const renderSection = (isEdit, section) => {\n return (\n \n {renderField(isEdit, section.fields, section.key)}\n \n );\n };\n\n const renderField = (isEdit, fields, sectionKey) => {\n const minimumInputNumber = MINIMUM_INPUT_FIELD.includes(sectionKey)\n ? 0\n : undefined;\n\n const inputCollection = {\n text: ,\n number: (\n \n ),\n checkbox: ,\n targetMarket: isEdit ? (\n \n ) : (\n \n ),\n country: isEdit ? (\n trigger.parentNode}\n mode='multiple'\n />\n ) : (\n \n ),\n select: (params) => {\n const { options: optionConfig } = params || {};\n\n const options =\n typeof optionConfig === 'function'\n ? optionConfig(enumOptions)\n : optionConfig;\n\n return isEdit ? (\n \n {options?.map((option) => (\n \n {option?.enumDisplayName}\n \n ))}\n \n ) : (\n \n );\n },\n textarea: (params) => {\n const { inputProps } = params || {};\n\n return (\n \n );\n },\n productContainsBioengineeredIngredients: (\n \n {['Yes', 'No'].map((option) => (\n \n {option}\n \n ))}\n \n ),\n };\n\n return fields.map((field) => {\n const label = intl.formatMessage(Messages?.[sectionKey]?.[field.name]);\n\n const { inputRender } = field;\n\n const requiredFieldForSupplier = checkRequiredField(\n requiredFields,\n field?.name\n );\n\n const isAWGOwnerRequired =\n field?.name === 'productContainsBioengineeredIngredients' &&\n productFull?.ownerId === +process.env.REACT_APP_AWG_ID;\n\n const rules =\n (requiredFieldForSupplier && isProductAssignedByRetailer) ||\n isAWGOwnerRequired\n ? [\n {\n required: true,\n message: `${label || 'This field'} is required`,\n },\n ]\n : null;\n\n const InputField = inputRender || inputCollection[field.type];\n\n const valuePropName = {\n valuePropName: field.type === 'checkbox' ? 'checked' : undefined,\n };\n\n const snapshotValue = dataQaSpecSnapshot?.[`${field?.name}`];\n\n const formItemProps = field?.formItemProps || {};\n\n return (\n \n {field.isList ? (\n renderFormList(isEdit, field, sectionKey)\n ) : (\n \n }\n >\n {label} }}>\n {label}\n \n }\n rules={rules}\n {...valuePropName}\n {...formItemProps}\n >\n {typeof InputField === 'function'\n ? InputField({ ...field, isEdit })\n : InputField}\n \n \n )}\n \n );\n });\n };\n\n const renderFormList = (isEdit, fieldSchema, sectionKey) => {\n const disabled = disabledCertifier[fieldSchema.name];\n\n const dataList = dataProductSpec?.[`${fieldSchema.name}`] ?? [];\n const dataListSnapshot = dataQaSpecSnapshot?.[`${fieldSchema.name}`] ?? [];\n\n return (\n \n {(fields, { add, remove }) => {\n const handleAddField = () => {\n add();\n onAddField(fields?.length);\n };\n\n return (\n <>\n {fields.map(({ key, name, ...restField }, idx) => {\n const options = fieldSchema.enum\n ? findProductPropertyEnums(fieldSchema.enum, productEnums)\n : [];\n\n return (\n \n \n \n }\n key={`${key}-${idx}`}\n >\n \n {fieldSchema.type === 'select' &&\n isEdit &&\n !disabled ? (\n \n {options.map((option) =>\n option ? (\n \n {option.enumDisplayName}\n \n ) : null\n )}\n \n ) : (\n inputRef(ref, idx)}\n disabled={disabled}\n readOnly={!isEdit}\n variant='text'\n />\n )}\n \n \n \n \n \n remove(name)}\n style={{ color: 'red' }}\n />\n \n \n \n );\n })}\n \n \n handleAddField()}\n icon={}\n disabled={disabled}\n type='primary'\n >\n Add field\n \n \n \n \n \n );\n }}\n \n );\n };\n\n const renderLocation = (isEdit, section) => {\n return (\n \n {renderField(isEdit, section.fields, section.key)}\n \n \n \n Country of Origin\n \n }\n required={isRequiredCountryOfOrigin}\n >\n {isEdit && (\n \n handleAddCountryOfOrigin()}\n icon={}\n >\n Add field\n \n\n {isRequiredCountryOfOrigin &&\n isSubmitted &&\n checkIsInvalidCountryOfOrigin(countryOfOrigin) && (\n \n Country of Origin is required\n \n )}\n \n )}\n \n {countryOfOrigin?.length > 0 &&\n countryOfOrigin.map((val, index) => {\n const snapshotCountryOfOrigin =\n dataQaSpecSnapshot?.countryOfOrigin ?? [];\n const snapshotCountryCode =\n snapshotCountryOfOrigin?.[`${index}`]?.countryCode;\n const snapshotCountrySubdivisionString =\n snapshotCountryOfOrigin?.[\n `${index}`\n ]?.countrySubdivisionCode?.join(', ');\n\n const countrySubdivisionString =\n val?.countrySubdivisionCode?.join(', ');\n\n return (\n \n \n handleRemoveCountryOfOrigin(index)}\n />\n \n \n \n \n }\n >\n \n \n option?.value\n ?.toLowerCase()\n .indexOf(input?.toLowerCase()) >= 0\n }\n onChange={(value) => {\n const temp = [...countryOfOrigin];\n temp[index].countryCode = value;\n setCountryOfOrigin(temp);\n }}\n >\n {sortBy(countryCodeEnum?.[0]?.enumProperties, [\n 'enumDisplayName',\n 'enumGroup',\n ])?.map((item, index) => (\n \n {item?.enumDisplayName}\n \n ))}\n \n \n \n\n \n }\n >\n \n {isEdit ? (\n \n option?.value\n ?.toLowerCase()\n .indexOf(input?.toLowerCase()) >= 0\n }\n onChange={(value) => {\n const temp = [...countryOfOrigin];\n temp[index].countrySubdivisionCode = value;\n setCountryOfOrigin(temp);\n }}\n >\n {sortBy(\n countrySubDivisionEnum?.[0]?.enumProperties,\n ['enumDisplayName', 'enumGroup']\n )?.map((item, index) => (\n \n {item?.enumDisplayName}\n \n ))}\n \n ) : (\n \n \n \n )}\n \n \n \n \n \n );\n })}\n \n \n \n );\n };\n\n const renderStatement = (isEdit, section) => {\n return (\n \n {renderField(isEdit, section.fields, section.key)}\n \n \n \n Nonfood Ingredient Statement\n \n }\n >\n {isEdit && (\n \n handleAddNIStatement()}\n icon={}\n >\n Add field\n \n \n )}\n \n {nonfoodIngredientStatement?.length > 0 &&\n nonfoodIngredientStatement.map((val, index) => {\n const nonfoodIngredientStatementSnapshot =\n dataQaSpecSnapshot?.nonfoodIngredientStatement ?? [];\n\n const nonfoodIngredientStatementItemSnapshot =\n nonfoodIngredientStatementSnapshot?.[`${index}`] ?? {};\n\n const {\n value: valueSnapshot,\n languageCode: languageCodeSnapshot,\n codeListVersion: codeListVersionSnapshot,\n formattingPattern: formattingPatternSnapshot,\n sequenceNumber: sequenceNumberSnapshot,\n } = nonfoodIngredientStatementItemSnapshot;\n\n return (\n \n \n handleRemoveNIStatement(index)}\n />\n \n \n \n \n \n }\n >\n {\n const temp = [...nonfoodIngredientStatement];\n temp[index].value = e.target.value;\n setNonfoodIngredientStatement(temp);\n }}\n />\n \n \n \n \n }\n >\n \n option?.value\n ?.toLowerCase()\n .indexOf(input?.toLowerCase()) >= 0\n }\n onChange={(value) => {\n const temp = [...nonfoodIngredientStatement];\n temp[index].languageCode = value;\n setNonfoodIngredientStatement(temp);\n }}\n >\n {sortBy(languageCodeEnum?.[0]?.enumProperties, [\n 'enumDisplayName',\n 'enumGroup',\n ])?.map((item, index) => (\n \n {`${\n item.enumDescription\n } - (${item.enumCode.toUpperCase()})`}\n \n ))}\n \n \n \n \n \n }\n >\n {\n const temp = [...nonfoodIngredientStatement];\n temp[index].codeListVersion = e.target.value;\n setNonfoodIngredientStatement(temp);\n }}\n />\n \n \n \n \n }\n >\n {\n const temp = [...nonfoodIngredientStatement];\n temp[index].formattingPattern = e.target.value;\n setNonfoodIngredientStatement(temp);\n }}\n />\n \n \n \n \n }\n >\n {\n const temp = [...nonfoodIngredientStatement];\n temp[index].sequenceNumber = value;\n setNonfoodIngredientStatement(temp);\n }}\n />\n \n \n \n \n \n );\n })}\n \n \n \n );\n };\n\n const renderMeatFishField = (isEdit) => {\n const { usdaGrade, usdaShieldId, eggsGrading } = dataProductSpec ?? {};\n\n const {\n usdaGrade: snapshotUsdaGrade,\n usdaShieldId: snapshotUsdaShieldId,\n eggsGrading: snapshotEggsGrading,\n } = dataQaSpecSnapshot ?? {};\n\n const addDocument = ({ successCallback, ...payload }) => {\n const params = {\n productItemId: productId,\n linkType: 'CERTIFICATE',\n ...payload,\n };\n mutationUploadCertificate.mutate(params, {\n onSuccess: () => {\n setVisible(false);\n successCallback();\n CustomNotification.success(\n 'Update certificate document successfully.'\n );\n },\n onError: () => {\n setVisible(false);\n CustomNotification.error('Update failed.');\n },\n });\n };\n\n return (\n \n \n \n }\n >\n \n USDA / Canadian Grading\n \n }\n >\n \n document.getElementById('meat-fish-field')\n }\n disabled={!isEdit}\n >\n {sortByKey(usdaGradingList, 'enumDisplayName')?.map(\n (property, index) => (\n \n {property.enumDisplayName\n ? property.enumDisplayName\n : property.enumDescription}\n \n )\n )}\n \n \n \n \n \n \n }\n >\n USDA Shield ID}\n >\n \n \n \n \n \n \n Certificate Badge or Other Certifications\n \n }\n >\n }\n danger\n disabled={!isEdit}\n onClick={() => setVisible(true)}\n >\n Upload certificate document\n \n \n \n \n \n }\n >\n Eggs Grading}\n >\n \n document.getElementById('meat-fish-field')\n }\n disabled={!isEdit}\n >\n {sortByKey(eggsGradingList, 'enumDisplayName')?.map(\n (property, index) => (\n \n {property.enumDisplayName\n ? property.enumDisplayName\n : property.enumDescription}\n \n )\n )}\n \n \n \n \n {visible && (\n \n )}\n \n );\n };\n\n // const TextAreaField = ({ readOnly, item }) => {\n // const { displayName, fieldName, limitCharacters } = item;\n // return (\n // {displayName}}\n // labelCol={{ span: 24 }}\n // wrapperCol={{ span: 24 }}\n // >\n // \n // \n // );\n // };\n\n const TextAreaField = ({ readOnly, item }) => {\n const { displayName, fieldName, limitCharacters } = item;\n const supplierModifiedValue = dataProductSpec?.[`${fieldName}`];\n const snapshotValue = dataQaSpecSnapshot?.[`${fieldName}`];\n\n return (\n \n }\n >\n {displayName}}\n labelCol={{ span: 24 }}\n wrapperCol={{ span: 24 }}\n >\n \n \n \n );\n };\n\n return (\n \n
\n {\n const toggleEditMode = editContainerRef?.current?.onToggleEditMode;\n onSubmit(toggleEditMode, ixoneIgnore);\n }}\n showModal\n type={TYPE_VIEW.EDIT_PRODUCT}\n >\n {(handleConfirmIXONE) => (\n {\n handleConfirmIXONE({\n originalData: dataProductSpec,\n changedFields: await form.validateFields(),\n });\n }}\n handleCancel={onCancel}\n float\n >\n {(isEdit) => {\n return (\n \n {\n handleConfirmIXONE({\n originalData: dataProductSpec,\n changedFields: await form.validateFields(),\n });\n }}\n >\n \n \n {renderSection(\n isEdit,\n PRODUCT_SPEC_FORM_SECTION_SCHEMA.DATE_CODING\n )}\n {renderStatement(\n isEdit,\n PRODUCT_SPEC_FORM_SECTION_SCHEMA.STATEMENT\n )}\n {renderLocation(\n isEdit,\n PRODUCT_SPEC_FORM_SECTION_SCHEMA.LOCATION\n )}\n
\n \n }\n >\n \n \n {intl.formatMessage(\n Messages.USDA_WIC_eligible_label\n )}\n \n \n }\n valuePropName='checked'\n >\n \n \n \n
\n \n }\n >\n \n \n {intl.formatMessage(\n Messages.MSDSRequired\n )}\n \n \n }\n valuePropName='checked'\n >\n \n \n \n
\n
\n \n\n \n {renderSection(\n isEdit,\n PRODUCT_SPEC_FORM_SECTION_SCHEMA.SHELF_LIFE\n )}\n {renderSection(\n isEdit,\n PRODUCT_SPEC_FORM_SECTION_SCHEMA.DIETARY\n )}\n {renderSection(\n isEdit,\n PRODUCT_SPEC_FORM_SECTION_SCHEMA.CASE_TEMPERATURE\n )}\n {renderSection(\n isEdit,\n PRODUCT_SPEC_FORM_SECTION_SCHEMA.POLYFLUOROALKYL_SUBSTANCES\n )}\n \n \n {DAIRY_SECTION_TEXT_AREA.map((item, index) => {\n return (\n \n );\n })}\n \n }\n >\n \n Gluten Free Claim\n \n }\n valuePropName='checked'\n labelCol={{ flex: '120px' }}\n >\n \n \n \n {DAIRY_SECTION_TEXT_AREA_2.map((item, index) => {\n return (\n \n );\n })}\n {renderMeatFishField(isEdit)}\n \n \n \n \n );\n }}\n \n )}\n \n
\n {isLinkToNewAssetModalOpen && (\n {\n handleCloseModalUploadCertificate();\n }}\n qaSpec\n />\n )}\n {isAddDocumentForMSDS && (\n {\n handCloseModalUploadDocMSDS();\n }}\n />\n )}\n
\n );\n};\n\nconst MsdsRequiredField = (props) => {\n const { isEdit, msdsWatch, handleOpenModalMSDSDocument, ...restProps } =\n props;\n return (\n
\n \n {msdsWatch && (\n \n Load\n \n )}\n
\n );\n};\n\nconst QaSpecProductSnapshot = (props) => {\n const { isSuccess, dataQaSpecSnapshot } = useGetQaSpecSnapshot();\n const isToggleSnapshot = useCheckSnapshotForRetailer();\n\n if (isSuccess && isToggleSnapshot && dataQaSpecSnapshot) {\n return ;\n }\n\n return <>{props.children};\n};\n\nexport default QaSpecProductInfo;\n","import { useState, useEffect } from 'react';\n\nimport { v4 as uuidv4 } from 'uuid';\nimport _ from 'lodash';\n\nimport { getAllRows } from 'pages/qa-spec/utils';\nimport { sleep } from 'utils/delay';\n\nexport const useQaSpecGrid = (props = {}) => {\n const {\n gridData = [],\n gridInst,\n isGridEditing,\n customInitRowData = (gridData) => gridData,\n resetGridCallback,\n } = props;\n\n const [rowData, setRowData] = useState([]);\n const [selectedRow, setSelectedRow] = useState(null);\n\n const initRowData = () => {\n if (isGridEditing) return;\n\n const transformedRowData = customInitRowData(gridData);\n\n setRowData(transformedRowData || []);\n\n mapUidData();\n };\n\n const mapUidData = () => {\n setRowData((prevState) =>\n prevState?.map((dataItem) => {\n const newUuid = uuidv4();\n\n return { ...dataItem, uuid: dataItem?.id ?? newUuid };\n })\n );\n };\n\n const selectGridRow = (row) => {\n const selectedRows = gridInst.current.api.getSelectedNodes();\n\n //* clear selected if row === null\n setSelectedRow(row === null ? null : selectedRows[0]);\n };\n\n const addGridRow = (initialRowData = {}) => {\n const newUuid = uuidv4();\n\n const allRowData = getAllRows(gridInst);\n\n const newRowIndex = allRowData?.length;\n\n gridInst.current.api.applyTransaction({\n add: [{ uuid: newUuid, ...initialRowData }],\n addIndex: newRowIndex,\n });\n\n gridInst.current.api.ensureIndexVisible(newRowIndex);\n\n const newRow = gridInst.current.api.getRowNode(newUuid);\n newRow.setSelected(true, true);\n };\n\n const deleteSelectedGridRow = () => {\n const selectedRows = gridInst.current.api.getSelectedNodes();\n\n const removeList = selectedRows.map(\n (selectedRowItem) => selectedRowItem?.data\n );\n\n gridInst.current.api.applyTransaction({\n remove: removeList,\n });\n\n setSelectedRow(null);\n };\n\n const resetGridData = async () => {\n gridInst.current.api.stopEditing();\n\n gridInst.current.api.setRowData(_.cloneDeep(rowData));\n\n setSelectedRow(null);\n await sleep(1000);\n resetGridCallback && resetGridCallback();\n };\n\n useEffect(() => {\n initRowData();\n }, [JSON.stringify(gridData)]);\n\n return {\n gridInst,\n rowData,\n setRowData,\n selectedRow,\n setSelectedRow,\n selectGridRow,\n addGridRow,\n deleteSelectedGridRow,\n resetGridData,\n mapUidData,\n };\n};\n","import { ORGANOLEPTIC_CHARACTERISTICS_ERRORS } from 'pages/qa-spec/constant';\n\nexport const ORGANOLEPTIC_CHARACTERISTICS_REQUIRED_FIELDS = {\n appearance: {\n specification: {\n message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.SPECIFICATION,\n },\n tolerance: {\n message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.TOLERANCE,\n },\n frequency: { message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.FREQUENCY },\n releaseCriteria: { message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.RELEASE },\n },\n color: {\n specification: {\n message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.SPECIFICATION,\n },\n tolerance: {\n message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.TOLERANCE,\n },\n frequency: { message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.FREQUENCY },\n releaseCriteria: { message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.RELEASE },\n },\n 'aroma/odor': {\n specification: {\n message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.SPECIFICATION,\n },\n tolerance: {\n message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.TOLERANCE,\n },\n frequency: { message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.FREQUENCY },\n releaseCriteria: { message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.RELEASE },\n },\n 'flavor/taste': {\n specification: {\n message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.SPECIFICATION,\n },\n tolerance: {\n message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.TOLERANCE,\n },\n frequency: { message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.FREQUENCY },\n releaseCriteria: { message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.RELEASE },\n },\n texture: {\n specification: {\n message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.SPECIFICATION,\n },\n tolerance: {\n message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.TOLERANCE,\n },\n frequency: { message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.FREQUENCY },\n releaseCriteria: { message: ORGANOLEPTIC_CHARACTERISTICS_ERRORS.RELEASE },\n },\n};\n","import { useState, useEffect, useRef, useMemo, useCallback } from 'react';\n\nimport { isEqual } from 'lodash';\nimport cloneDeep from 'lodash/cloneDeep';\n\nimport { dialogFunction, CustomNotification } from 'common/components';\n\nimport TextRender from '../components/qa-grid-cell/TextRender';\nimport TextRenderSnapshot from '../components/qa-grid-cell/TextRenderSnapshot';\n\nimport {\n createTextEditorRenderer,\n createNumericEditorRenderer,\n} from 'pages/qa-spec/utils/gridColumnUtils';\nimport { getAllRows } from 'pages/qa-spec/utils';\nimport { apiHandler } from 'utils/api';\nimport { sleep } from 'utils/delay';\n\nimport * as qaSpecServices from 'services/qaSpec';\n\nimport { useQaSpecGrid } from './useQaSpecGrid';\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\nimport { useGetQaSpecComponentQuery } from '../query';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/qa-spec';\n\nimport { COMPONENTS_ERROR } from 'pages/qa-spec/constant';\n\nconst FIELD_COMPONENTS_PART_OF = 'componentsPartOf';\nconst FIELD_COMPONENT = 'component';\n\nexport const useQaSpecComponents = (props) => {\n const intl = useIntl();\n const productClaimsRef = useRef();\n const gridInst = useRef();\n\n const { formInst, productId, isGridEditing } = props;\n\n const [saveLoading, setSaveLoading] = useState(false);\n\n const useSnapshot = useCheckSnapshotForRetailer();\n\n const { componentData, handleRefetchQaSpecComponent, isLoading, isFetching } =\n useGetQaSpecComponentQuery({\n productId,\n enabled: Number(productId) && !isGridEditing,\n });\n\n const fetchDataLoading = isLoading && isFetching;\n\n const {\n addGridRow,\n deleteSelectedGridRow,\n selectGridRow,\n setSelectedRow,\n rowData,\n selectedRow,\n } = useQaSpecGrid({\n gridInst,\n gridData: componentData?.components,\n isGridEditing,\n });\n\n const makeColumnDefs = useCallback(({ useSnapshot = false } = {}) => {\n const cellRenderer = useSnapshot\n ? {\n TextRender: 'TextRenderSnapshot',\n CountryEditorRender: 'CountryEditorRenderSnapshot',\n }\n : {\n TextRender: 'TextRender',\n CountryEditorRender: 'CountryEditorRender',\n };\n\n return [\n {\n field: 'error',\n displayName: ' ',\n minWidth: 50,\n maxWidth: 50,\n cellRenderer: 'StatusRender',\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n minWidth: 150,\n headerName: 'Component',\n field: FIELD_COMPONENT,\n type: 'editableColumn',\n cellEditorSelector: createTextEditorRenderer(50),\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n headerName: 'Part Of',\n minWidth: 120,\n field: FIELD_COMPONENTS_PART_OF,\n type: 'editableColumn',\n cellEditorSelector: (params) => {\n const options = getOptionsComponentsPartOf({\n gridInst,\n params,\n });\n\n return {\n component: 'SelectionEditor',\n params: {\n values: options.map((optionItem) => ({\n value: optionItem?.value,\n displayName:\n optionItem?.displayName === null\n ? ''\n : optionItem?.displayName,\n })),\n mapValue: (value) => {\n if (value === 'null' || value === undefined) {\n return null;\n } else {\n return value;\n }\n },\n },\n popup: true,\n };\n },\n cellRenderer: (params) => {\n const { context, rowIndex, column } = params;\n\n const options = getOptionsComponentsPartOf({\n gridInst,\n params,\n });\n\n const value =\n options?.find((option) => option?.value === params?.value)\n ?.displayName ?? '';\n\n const cellSnapshotValue =\n context?.snapshotGridValues?.[rowIndex]?.[column.colId] ?? 'N/A';\n\n const rawCellValue =\n params?.value?.split('.').slice(0, -1).join('.') ?? 'N/A';\n\n const isHighlightChange =\n !isEqual(`${cellSnapshotValue}`, `${rawCellValue}`) && useSnapshot;\n\n return useSnapshot ? (\n \n ) : (\n \n );\n },\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n minWidth: 200,\n headerName: 'CAS / INCI / HS Code',\n field: 'caS_INCI_HSCode',\n type: 'editableColumn',\n cellEditorSelector: createTextEditorRenderer(50),\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n minWidth: 120,\n headerName: 'Function',\n field: 'componentsFunction',\n type: 'editableColumn',\n cellEditorSelector: createTextEditorRenderer(50),\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n minWidth: 150,\n headerName: 'Manufacturer',\n field: 'manufacturer',\n type: 'editableColumn',\n cellEditorSelector: createTextEditorRenderer(50),\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n headerName: 'Country of Origin',\n minWidth: 180,\n field: 'componentsCountryOfOrigin',\n type: 'editableColumn',\n cellRenderer: cellRenderer['CountryEditorRender'],\n cellEditorSelector: () => {\n return {\n component: 'CountryEditor',\n popup: true,\n };\n },\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n headerName: 'Quantity in %',\n minWidth: 150,\n field: 'quantityInPercent',\n type: 'editableColumn',\n cellEditorSelector: createTextEditorRenderer(100),\n cellRenderer: cellRenderer['TextRender'],\n },\n {\n allowFilter: true,\n allowSort: true,\n minWidth: 150,\n dataType: 'text',\n headerName: 'Total Weight',\n field: 'totalWeight',\n type: 'editableColumn',\n cellEditorSelector: createNumericEditorRenderer({\n min: 0,\n }),\n cellRenderer: cellRenderer['TextRender'],\n },\n ];\n }, []);\n\n const columnDefs = useMemo(() => {\n return makeColumnDefs({ useSnapshot });\n }, [makeColumnDefs, useSnapshot]);\n\n const onSave = async (toggleEditMode) => {\n gridInst.current.api.stopEditing();\n\n await sleep(100);\n\n callApiUpdateQaSpecComponents(toggleEditMode);\n\n //* clear selected row\n selectGridRow(null);\n };\n\n const onCancel = () => {\n gridInst.current.api.stopEditing();\n\n const transformRowData = transformQaComponentGrid(rowData);\n\n gridInst.current.api.setRowData(cloneDeep(transformRowData));\n\n setSelectedRow(null);\n formInst.setFieldsValue({ productClaims: productClaimsRef.current });\n };\n\n const onUpdateComponentsSuccess = (toggleEditMode) => () => {\n //* reload data\n handleRefetchQaSpecComponent();\n\n toggleEditMode();\n };\n\n const initData = () => {\n initFormValues(componentData);\n\n //* store productClams for reset value when canceling\n productClaimsRef.current = componentData?.productClaims;\n };\n\n const selectRow = () => {\n selectGridRow();\n };\n\n const deleteRow = () => {\n dialogFunction({\n type: 'warn',\n content: 'Are you sure you want to delete the selected item?',\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: onDeleteData,\n });\n };\n\n const onDeleteData = () => {\n const selectedRow = gridInst.current.api.getSelectedNodes()?.[0];\n const allRowData = getAllRows(gridInst);\n\n const newRowData = getRowDataAfterDeletingRow({\n rowData: allRowData,\n deletingRow: selectedRow,\n });\n\n gridInst.current.api.applyTransaction({\n update: newRowData,\n });\n\n deleteSelectedGridRow();\n };\n\n const onSaveFinally = () => {\n setSaveLoading(false);\n };\n\n const onCellEditingStopped = (params) => {\n updateRowError(params);\n };\n\n const validateEmptyComponent = (error, data) => {\n if (!data.component) error.push(COMPONENTS_ERROR.EMPTY);\n };\n\n const validateExistedComponent = (error, data) => {\n const allRowsData = getAllRows(gridInst);\n const parentRows = allRowsData.filter((row) => !row.componentsPartOf); // don't validate child row\n\n const isExisted = parentRows.some((row) => {\n return row.uuid !== data.uuid && row.component === data.component;\n });\n\n if (isExisted) error.push(COMPONENTS_ERROR.EXISTED);\n };\n\n const validateGridError = () => {\n const allRowsData = getAllRows(gridInst);\n\n const hasError = allRowsData.some((row) => row.error?.length > 0);\n\n return hasError;\n };\n\n const updateRowError = (params = {}) => {\n const {\n column: { colId },\n } = params;\n\n const allRowsData = getAllRows(gridInst);\n let newRowsData = allRowsData;\n\n if (colId === FIELD_COMPONENT) {\n // update children of row\n newRowsData = getRowDataAfterChangingComponentField({\n rowData: newRowsData,\n changingRow: params?.data,\n });\n } else if (colId === FIELD_COMPONENTS_PART_OF) {\n newRowsData = getRowDataAfterChangingPartsOfField({\n rowData: newRowsData,\n changingRow: params?.data,\n });\n }\n\n // validate error\n newRowsData = newRowsData.map((row) => {\n const error = [];\n\n validateEmptyComponent(error, row);\n\n // don't need to check on parent row\n if (!row?.componentsPartOf) {\n validateExistedComponent(error, row);\n }\n\n return { ...row, error: error };\n });\n\n gridInst.current.api.applyTransaction({\n update: newRowsData,\n });\n };\n\n const addRow = async () => {\n gridInst.current.api.stopEditing();\n await sleep();\n\n addGridRow({\n component: null,\n componentsPartOf: null,\n componentsPartOfId: null,\n caS_INCI_HSCode: null,\n componentsFunction: null,\n manufacturer: null,\n componentsCountryOfOrigin: null,\n quantityInPercent: null,\n totalWeight: null,\n error: [COMPONENTS_ERROR.EMPTY],\n });\n };\n\n const initFormValues = (data) => {\n formInst.setFieldsValue({\n productClaims: data?.productClaims,\n });\n };\n\n const callApiUpdateQaSpecComponents = (toggleEditMode) => {\n const allRowData = getAllRows(gridInst);\n\n const hasGridError = validateGridError();\n\n if (hasGridError) {\n CustomNotification.error(`Please resolve Ingredient grid's errors`);\n return;\n }\n\n const formValues = formInst.getFieldsValue();\n\n const params = {\n productId,\n components: allRowData.map((row) => {\n if (row?.componentsPartOf) {\n // componentsPartOf = 'componentValueOfParent.componentsPartOfIdOfParent' -> Improve displayname for the BlueProperties module\n const componentsPartOf = row?.componentsPartOf?.split('.')?.[0];\n return {\n ...row,\n id: row?.uuid,\n componentsPartOf,\n };\n }\n return {\n ...row,\n id: row?.uuid,\n };\n }),\n productClaims: formValues.productClaims,\n };\n\n setSaveLoading(true);\n\n const successMessage = intl.formatMessage(\n Messages.qaSpecUpdateComponentsSuccess\n );\n const errorMessage = intl.formatMessage(\n Messages.qaSpecUpdateComponentsError\n );\n\n apiHandler({\n service: qaSpecServices.saveQaSpecComponents,\n params,\n successMessage,\n errorMessage,\n successCallback: onUpdateComponentsSuccess(toggleEditMode),\n onFinally: onSaveFinally,\n });\n };\n\n useEffect(() => {\n initData();\n }, [JSON.stringify(componentData)]);\n\n return {\n gridInst,\n rowData,\n columnDefs,\n isLoading: fetchDataLoading || saveLoading,\n selectedRow,\n selectRow,\n addRow,\n deleteRow,\n onSave,\n onCancel,\n onCellEditingStopped,\n };\n};\n\nexport const getRowDataAfterChangingComponentField = ({\n rowData = [],\n changingRow,\n}) => {\n let result = [];\n\n rowData.forEach((row) => {\n if (row?.componentsPartOf) {\n const [, parentUuid] = row.componentsPartOf.split('.');\n\n if (parentUuid === changingRow?.uuid) {\n const newRow = {\n ...row,\n componentsPartOf: changingRow?.component\n ? transformValueComponentsPartOf(changingRow)\n : null,\n };\n result.push(newRow);\n } else {\n result.push(row);\n }\n } else {\n result.push(row);\n }\n });\n\n return result;\n};\n\nexport const transformQaComponentGrid = (rowData) => {\n return rowData.map((row) => {\n if (row?.componentsPartOf) {\n return {\n ...row,\n componentsPartOf: `${row.componentsPartOf}.${row.componentsPartOfId}`,\n };\n }\n return row;\n });\n};\n\nexport const getRowDataAfterChangingPartsOfField = ({\n rowData,\n changingRow,\n}) => {\n let result = [];\n\n rowData.forEach((row) => {\n if (row.uuid === changingRow.uuid) {\n const parentUuid = row?.componentsPartOf?.split('.')?.[1];\n const newRow = {\n ...row,\n componentsPartOfId: changingRow?.componentsPartOf ? parentUuid : null,\n };\n result.push(newRow);\n } else {\n result.push(row);\n }\n });\n\n return result;\n};\n\nexport const transformValueComponentsPartOf = (row) =>\n `${row?.component}.${row?.uuid}`;\n\nexport const getOptionsComponentsPartOf = ({ gridInst, params }) => {\n const allRowData = getAllRows(gridInst);\n\n const options = allRowData\n ?.map((itemData, index) => ({\n uuid: itemData?.uuid,\n value: transformValueComponentsPartOf(itemData),\n component: itemData?.component,\n displayName: `${itemData?.component} (row ${index + 1})`,\n }))\n .filter(\n (optionItem) =>\n optionItem?.component && optionItem?.uuid !== params?.data?.uuid\n );\n\n return options;\n};\n\nexport const getRowDataAfterDeletingRow = ({ rowData, deletingRow }) => {\n let result = [];\n\n rowData.forEach((row) => {\n if (row?.componentsPartOf) {\n const [, parentUuid] = row.componentsPartOf.split('.');\n\n if (parentUuid === deletingRow?.data?.uuid) {\n const newRow = {\n ...row,\n componentsPartOf: null,\n };\n result.push(newRow);\n }\n } else {\n result.push(row);\n }\n });\n\n return result;\n};\n","import { useQuery } from '@tanstack/react-query';\nimport { getQaSpecComponentsSnapshot } from 'services/qaSpec';\n\nconst qaSpecComponentKeys = {\n snapshot: (productId) => [\n 'pim',\n 'snapshot',\n parseInt(productId),\n 'qa-spec-components',\n ],\n};\n\nexport const useQueryQaSpecComponentSnapshot = ({\n productId,\n ...options\n} = {}) => {\n return useQuery({\n queryKey: qaSpecComponentKeys.snapshot(productId),\n queryFn: async () => {\n const response = await getQaSpecComponentsSnapshot({ productId });\n const { isSuccess, data, message } = response || {};\n if (isSuccess) {\n return data;\n }\n return Promise.reject(message || 'Server Error');\n },\n ...options,\n });\n};\n","import React, { useState, useMemo } from 'react';\nimport PropTypes from 'prop-types';\nimport { Row, Col, Space, Input } from 'antd';\n\nimport classnames from 'classnames';\nimport _ from 'lodash';\n\nimport {\n Form,\n FormAddButton,\n FormDeleteButton,\n WithLoading,\n} from 'common/components';\nimport { QaGridEdit, EditContainer } from 'pages/qa-spec/components';\nimport {\n EditTabSectionWrapper,\n EDIT_SECTION,\n} from 'pages/qa-spec/components/edit-tab-checker';\n\nimport { useTabExpand } from 'hooks/useTabExpandProduct';\nimport {\n transformQaComponentGrid,\n useQaSpecComponents,\n} from 'pages/qa-spec/hooks/useQaSpecComponents';\n\nimport 'ag-grid-enterprise/dist/styles/ag-grid.css';\nimport 'ag-grid-enterprise/dist/styles/ag-theme-alpine.css';\nimport {\n SnapshotInputWrapper,\n SnapshotFormItemWrapper,\n FormLabel,\n} from 'pages/qa-spec/components/form';\nimport { useGetSnapshotFormItemWrapperProps } from 'pages/qa-spec/components/form/hooks';\n\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\n\nimport { useQueryQaSpecComponentSnapshot } from './queries';\n\nconst QaSpecComponent = (props) => {\n const [form] = Form.useForm();\n\n const { productId } = props;\n\n const [isGridEditing, setIsGridEditing] = useState(false);\n\n const { tableStyle } = useTabExpand();\n\n const {\n gridInst,\n rowData,\n columnDefs,\n selectedRow,\n selectRow,\n addRow,\n deleteRow,\n onSave,\n onCancel,\n onCellEditingStopped,\n } = useQaSpecComponents({\n productId,\n isGridEditing,\n formInst: form,\n });\n\n const useSnapshot = useCheckSnapshotForRetailer();\n const { data: componentSnapshotData } = useQueryQaSpecComponentSnapshot({\n productId,\n enabled: Boolean(productId && useSnapshot),\n });\n\n // transform for display the partOf field in the grid\n const transformRowData = useMemo(\n () => transformQaComponentGrid(rowData),\n [rowData]\n );\n\n const onClickAddBtn = () => {\n addRow();\n };\n\n const onClickDeleteBtn = () => {\n deleteRow();\n };\n\n const formItemLayout = {\n labelCol: {\n span: 24,\n },\n wrapperCol: {\n span: 24,\n },\n };\n\n const rowClassRules = useMemo(\n () => ({\n 'ag-row--error': (params) => {\n return !!params?.data?.error?.length > 0;\n },\n }),\n []\n );\n\n const { getSnapshotFormItemWrapperProps } =\n useGetSnapshotFormItemWrapperProps({\n snapshotValues: componentSnapshotData,\n });\n\n const onEdit = (isEditing) => {\n setIsGridEditing(isEditing);\n };\n\n return (\n ,\n ,\n ]}\n onEditChange={onEdit}\n >\n {(isEdit) => {\n return (\n \n \n \n \n \n \n \n {columnDefs && columnDefs.length > 0 && (\n \n {\n return data?.['uuid'];\n }}\n selectedRow={selectedRow}\n onRowSelected={selectRow}\n rowSelection='single'\n rowClassRules={rowClassRules}\n onCellEditingStopped={onCellEditingStopped}\n snapshotGridValues={\n componentSnapshotData?.components\n }\n />\n \n )}\n \n \n \n \n \n {(inputWrapperProps) => (\n }\n name='productClaims'\n >\n \n \n \n \n )}\n \n \n \n \n \n \n );\n }}\n \n );\n};\n\nQaSpecComponent.propTypes = {\n productItemModules: PropTypes.object,\n};\nexport default QaSpecComponent;\n","import { Typography } from 'antd';\nimport classNames from 'classnames';\nconst { Text } = Typography;\n\nconst DrugFactHeading = ({\n heading,\n styles,\n headingDescription = null,\n className,\n ...otherProps\n}) => {\n return (\n \n {heading} {headingDescription ? `(${headingDescription})` : null}\n \n );\n};\n\nexport default DrugFactHeading;\n","import classNames from 'classnames';\nimport { Typography } from 'antd';\nconst { Text } = Typography;\n\nconst DrugFactText = ({ className, styles, children, ...otherProps }) => {\n return (\n \n {children}\n \n );\n};\n\nexport default DrugFactText;\n","import { useQuery } from '@tanstack/react-query';\nimport { useQueryClient } from '@tanstack/react-query';\n\nimport { getSnapshotQaSpecFreshMeat } from 'services/product';\n\nconst getQueryKeyQaFreshMeat = (productId) => {\n return ['pim', 'snapshot', parseInt(productId), 'qa-fresh-meat'];\n};\n\nexport const useGetSnapshotQaFreshMeat = ({\n enabled,\n productId,\n ...restProps\n}) => {\n const queryClient = useQueryClient();\n\n const getSnapshotQaFreshMeatData = async () => {\n const response = await getSnapshotQaSpecFreshMeat({ productId });\n const { isSuccess, data } = response;\n if (!isSuccess) return null;\n\n const { productId: id, ...restValue } = data;\n return restValue;\n };\n\n const query = useQuery({\n queryKey: getQueryKeyQaFreshMeat(productId),\n queryFn: getSnapshotQaFreshMeatData,\n enabled,\n ...restProps,\n });\n\n const invalidateSnapshotQaSpecFreshMeat = () => {\n queryClient.invalidateQueries({\n queryKey: getQueryKeyQaFreshMeat(productId),\n });\n };\n\n return { ...query, invalidateSnapshotQaSpecFreshMeat };\n};\n","import React, { useEffect, useState, useMemo } from 'react';\nimport { Row, Col, Typography } from 'antd';\n\nimport { EditContainer } from 'pages/qa-spec/components';\nimport { Form, WithLoading, SectionWrapper } from 'common/components';\nimport {\n EditTabSectionWrapper,\n EDIT_SECTION,\n} from 'pages/qa-spec/components/edit-tab-checker';\n\nimport { useParams } from 'react-router-dom';\n\nimport { BasicFormItemList } from 'common/components/form/basic-form';\n\nimport { useGetQaFreshMeatTabData, useSaveQaFreshMeatTab } from './queries';\nimport { getKeyProductSpec } from 'pages/qa-spec/hooks/useProductSpecInfo';\n\nimport { useGetEnumOptions } from 'pages/qa-spec/hooks';\n\nimport { FRESH_MEAT_LIMIT_CHARACTERS } from 'pages/qa-spec/constant';\nimport sortByKey from 'utils/sortByKey';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useGetSnapshotQaFreshMeat } from './hook';\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\n\nimport {\n getFormattedValue,\n renderPopoverContent,\n} from 'pages/qa-spec/utils/index';\n\nconst QaFreshMeat = (props) => {\n const { isTabActive } = props;\n\n const { id: productId } = useParams();\n const queryClient = useQueryClient();\n\n const isToggleSnapshot = useCheckSnapshotForRetailer();\n\n const editHook = useState(false);\n const [isEdit] = editHook;\n\n const freshMeatEnumOptions = useGetEnumOptions({\n optionMapping: useMemo(\n () => (option) => ({\n value: option.enumDisplayName,\n displayName: option.enumDisplayName,\n }),\n []\n ),\n })?.freshMeat;\n\n const {\n data,\n refetch: fetchQaFreshMeatData,\n isLoading: loading,\n } = useGetQaFreshMeatTabData({ productId }, { enabled: false, retry: false });\n\n useEffect(() => {\n if (isTabActive && !isEdit) {\n fetchQaFreshMeatData();\n }\n }, [isTabActive, isEdit, fetchQaFreshMeatData]);\n\n const handleSaveQaFreshMeatTab = useSaveQaFreshMeatTab();\n const { isLoading: saveLoading } = handleSaveQaFreshMeatTab;\n\n const { data: snapshotData, isLoading: isLoadingSnapshotFreshMeat } =\n useGetSnapshotQaFreshMeat({\n enabled: !!productId && isToggleSnapshot,\n productId,\n });\n\n useEffect(() => {\n if (data) {\n formInst.setFieldsValue(data);\n }\n }, [JSON.stringify(data)]);\n\n const [formInst] = Form.useForm();\n\n const handleSave = async (toggleEditMode) => {\n const formValue = formInst.getFieldsValue();\n handleSaveQaFreshMeatTab.mutate(\n {\n productId,\n qaFreshMeatFormData: formValue,\n },\n {\n onSuccess: () => {\n toggleEditMode();\n queryClient.invalidateQueries({\n queryKey: getKeyProductSpec(productId),\n });\n },\n }\n );\n };\n\n const handleCancel = () => {\n formInst.setFieldsValue(data);\n };\n\n const enumType = {\n irradiated: freshMeatEnumOptions.irradiated,\n freeRange: freshMeatEnumOptions.freeRange,\n usdaGrading: freshMeatEnumOptions.usdaGrading,\n dryAged: freshMeatEnumOptions.dryAged,\n coldSmoked: freshMeatEnumOptions.coldSmoked,\n };\n\n const formDefineLeft = [\n {\n name: 'breed',\n label: 'Breed',\n snapshotData: snapshotData?.['breed']?.trim() ?? '',\n supplierModifiedData: data?.['breed']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Breed',\n snapshotData?.['breed']?.trim() ?? '',\n data?.['breed']?.trim() ?? ''\n ),\n },\n {\n name: 'feed',\n label: 'Feed',\n snapshotData: snapshotData?.['feed']?.trim() ?? '',\n supplierModifiedData: data?.['feed']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Feed',\n snapshotData?.['feed']?.trim() ?? '',\n data?.['feed']?.trim() ?? ''\n ),\n },\n {\n name: 'typeOfCutOrTrimSpec',\n label: 'Type of Cut or Trim Spec',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: FRESH_MEAT_LIMIT_CHARACTERS.typeOfCutOrTrimSpec,\n showCount: true,\n },\n snapshotData: snapshotData?.['typeOfCutOrTrimSpec'] ?? '',\n supplierModifiedData: data?.['typeOfCutOrTrimSpec'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Type of Cut or Trim Spec',\n snapshotData?.['typeOfCutOrTrimSpec'] ?? '',\n data?.['typeOfCutOrTrimSpec'] ?? ''\n ),\n },\n {\n name: 'productRangeClassification',\n label: 'Product Range Classification',\n snapshotData: snapshotData?.['productRangeClassification']?.trim() ?? '',\n supplierModifiedData: data?.['productRangeClassification']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Product Range Classification',\n snapshotData?.['productRangeClassification']?.trim() ?? '',\n data?.['productRangeClassification']?.trim() ?? ''\n ),\n },\n {\n name: 'irradiated',\n label: 'Irradiated',\n type: 'select',\n selectProps: {\n options: freshMeatEnumOptions.irradiated,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['irradiated'],\n 'irradiated',\n enumType\n ),\n snapshotData: snapshotData?.['irradiated'],\n supplierModifiedData: data?.['irradiated'],\n renderPopoverContent: renderPopoverContent(\n 'Fortification',\n snapshotData?.['irradiated'],\n data?.['irradiated'],\n getFormattedValue(snapshotData?.['irradiated'], 'irradiated', enumType)\n ),\n },\n {\n name: 'fortification',\n label: 'Fortification',\n type: 'select',\n selectProps: {\n options: freshMeatEnumOptions.fortification,\n inputProps: {\n allowClear: true,\n },\n },\n snapshotData: snapshotData?.['fortification'],\n supplierModifiedData: data?.['fortification'],\n renderPopoverContent: renderPopoverContent(\n 'Fortification',\n snapshotData?.['fortification'],\n data?.['fortification']\n ),\n },\n {\n name: 'freeRange',\n label: 'Free Range',\n type: 'select',\n selectProps: {\n options: freshMeatEnumOptions.freeRange,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['freeRange'],\n 'freeRange',\n enumType\n ),\n snapshotData: snapshotData?.['freeRange'],\n supplierModifiedData: data?.['freeRange'],\n renderPopoverContent: renderPopoverContent(\n 'Free Range',\n snapshotData?.['freeRange'],\n data?.['freeRange'],\n getFormattedValue(snapshotData?.['freeRange'], 'freeRange', enumType)\n ),\n },\n ];\n\n const formDefineRightTop = [\n [\n { rowConfig: { gutter: [15, 15] } },\n {\n name: 'usdaGrading',\n label: 'USDA / AAFC Grading',\n type: 'select',\n selectProps: {\n options: sortByKey(\n freshMeatEnumOptions.usdaGrading,\n 'enumDisplayName'\n ),\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['usdaGrading'],\n 'usdaGrading',\n enumType\n ),\n snapshotData: snapshotData?.['usdaGrading'],\n supplierModifiedData: data?.['usdaGrading'],\n renderPopoverContent: renderPopoverContent(\n 'USDA / AAFC Grading',\n snapshotData?.['usdaGrading'],\n data?.['usdaGrading'],\n getFormattedValue(\n snapshotData?.['usdaGrading'],\n 'usdaGrading',\n enumType\n )\n ),\n colProps: { xs: 12 },\n },\n {\n name: 'piecesPerPound',\n label: 'Pieces per Pound',\n snapshotData: snapshotData?.['piecesPerPound']?.trim() ?? '',\n supplierModifiedData: data?.['piecesPerPound']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Pieces per Pound',\n snapshotData?.['piecesPerPound']?.trim() ?? '',\n data?.['piecesPerPound']?.trim() ?? ''\n ),\n colProps: { xs: 12 },\n },\n ],\n [\n {\n rowConfig: {\n gutter: [15, 15],\n },\n },\n {\n name: 'dryAged',\n label: 'Dry Aged',\n colProps: { xs: 12 },\n type: 'select',\n selectProps: {\n options: freshMeatEnumOptions.dryAged,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['dryAged'],\n 'dryAged',\n enumType\n ),\n snapshotData: snapshotData?.['dryAged'],\n supplierModifiedData: data?.['dryAged'],\n renderPopoverContent: renderPopoverContent(\n 'Dry Aged',\n snapshotData?.['dryAged'],\n data?.['dryAged'],\n getFormattedValue(snapshotData?.['dryAged'], 'dryAged', enumType)\n ),\n },\n {\n name: 'coldSmoked',\n label: 'Cold Smoked',\n colProps: { xs: 12 },\n type: 'select',\n selectProps: {\n options: freshMeatEnumOptions.coldSmoked,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['coldSmoked'],\n 'coldSmoked',\n enumType\n ),\n snapshotData: snapshotData?.['coldSmoked'],\n supplierModifiedData: data?.['coldSmoked'],\n renderPopoverContent: renderPopoverContent(\n 'Cold Smoked',\n snapshotData?.['coldSmoked'],\n data?.['coldSmoked'],\n getFormattedValue(\n snapshotData?.['coldSmoked'],\n 'coldSmoked',\n enumType\n )\n ),\n },\n ],\n ];\n\n const formDefineRightBottom = [\n {\n name: 'totalMeatProteinMinPercentage',\n label: 'Total Meat Protein Equivalent Min Percentage',\n snapshotData:\n snapshotData?.['totalMeatProteinMinPercentage']?.trim() ?? '',\n supplierModifiedData:\n data?.['totalMeatProteinMinPercentage']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Total Meat Protein Equivalent Min Percentage',\n snapshotData?.['totalMeatProteinMinPercentage']?.trim() ?? '',\n data?.['totalMeatProteinMinPercentage']?.trim() ?? ''\n ),\n },\n {\n name: 'actualTotalMeatContentMinPercentage',\n label: 'Actual Total Meat Content Min Percentage',\n snapshotData:\n snapshotData?.['actualTotalMeatContentMinPercentage']?.trim() ?? '',\n supplierModifiedData:\n data?.['actualTotalMeatContentMinPercentage']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Actual Total Meat Content Min Percentage',\n snapshotData?.['actualTotalMeatContentMinPercentage']?.trim() ?? '',\n data?.['actualTotalMeatContentMinPercentage']?.trim() ?? ''\n ),\n },\n {\n name: 'actualLeanMeatMinPercentage',\n label: 'Actual Lean Mean Min Percentage',\n snapshotData: snapshotData?.['actualLeanMeatMinPercentage']?.trim() ?? '',\n supplierModifiedData: data?.['actualLeanMeatMinPercentage']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Actual Lean Mean Min Percentage',\n snapshotData?.['actualLeanMeatMinPercentage']?.trim() ?? '',\n data?.['actualLeanMeatMinPercentage']?.trim() ?? ''\n ),\n },\n {\n name: 'fatMaxPercentage',\n label:\n 'Fat maximum percentage: total fat percentage on nutritional analyses',\n snapshotData: snapshotData?.['fatMaxPercentage']?.trim() ?? '',\n supplierModifiedData: data?.['fatMaxPercentage']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Fat maximum percentage: total fat percentage on nutritional analyses',\n snapshotData?.['fatMaxPercentage']?.trim() ?? '',\n data?.['fatMaxPercentage']?.trim() ?? ''\n ),\n },\n {\n name: 'addedRindsMaxPercentage',\n label:\n 'Added rinds maximum percentage: added rind shall not exceed value',\n snapshotData: snapshotData?.['addedRindsMaxPercentage']?.trim() ?? '',\n supplierModifiedData: data?.['addedRindsMaxPercentage']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Added rinds maximum percentage: added rind shall not exceed value',\n snapshotData?.['addedRindsMaxPercentage']?.trim() ?? '',\n data?.['addedRindsMaxPercentage']?.trim() ?? ''\n ),\n },\n {\n name: 'addedGelatineMaxPercentage',\n label: 'Added gelatin maximum percentage',\n snapshotData: snapshotData?.['addedGelatineMaxPercentage']?.trim() ?? '',\n supplierModifiedData: data?.['addedGelatineMaxPercentage']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Added gelatin maximum percentage',\n snapshotData?.['addedGelatineMaxPercentage']?.trim() ?? '',\n data?.['addedGelatineMaxPercentage']?.trim() ?? ''\n ),\n },\n ];\n\n return (\n \n \n \n {(isEdit) => {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n }}\n \n \n \n );\n};\n\nconst labelFn = (labelText) => {\n return {labelText && labelText};\n};\n\nexport default QaFreshMeat;\n","import React, { useState, useCallback, useEffect } from 'react';\nimport reactCSS from 'reactcss';\n\nimport { Typography, Button, Col, Row, Checkbox } from 'antd';\nimport { EditOutlined } from '@ant-design/icons';\nimport { FormCancelButton, FormSaveButton } from 'common/components';\nimport { EditTabSectionWrapper } from 'pages/qa-spec/components/edit-tab-checker';\nimport { useCheckAllowEdit } from 'pages/qa-spec/hooks';\n\nimport classNames from 'classnames';\n\nimport './WithQaGridHeader.less';\nimport { useCheckQaSpecLocked } from 'pages/qa-spec/hooks/useCheckQaSpecLocked';\n\nconst { Title } = Typography;\n\nconst styles = reactCSS({\n default: {\n buttonCol: {\n display: 'flex',\n alignItems: 'flex-end',\n },\n },\n});\n\nconst WithQaGridHeader = (props) => {\n const {\n title,\n children,\n show = true,\n buttons,\n extraButtons,\n allowEdit = true,\n handleCancel,\n showSaveBtn = true,\n showCancelBtn = true,\n showEditBtn = true,\n forceEdit,\n handleSave,\n showHeader = true,\n isShowAnalysisNotExecuted = false,\n analysisNotExecuted,\n type,\n productId,\n onEditChange,\n } = props;\n\n const [isEdit, setIsEdit] = useState(false);\n const [isAnalysis, setIsAnalysis] = useState(analysisNotExecuted);\n\n const toggleEditMode = useCallback(() => {\n setIsEdit((prev) => !prev);\n }, []);\n\n const onSave = () => {\n handleSave && handleSave(toggleEditMode, isAnalysis);\n };\n\n useEffect(() => {\n isShowAnalysisNotExecuted && setIsAnalysis(analysisNotExecuted);\n }, [analysisNotExecuted, isShowAnalysisNotExecuted]);\n\n const { isQASpecLocked } = useCheckQaSpecLocked();\n\n const onCancel = () => {\n isShowAnalysisNotExecuted && setIsAnalysis(analysisNotExecuted);\n toggleEditMode();\n handleCancel && handleCancel();\n };\n\n const hasPermissionEdit = useCheckAllowEdit(productId);\n\n const handleChange = (e) => {\n setIsAnalysis(e.target.checked);\n };\n\n useEffect(() => {\n setIsEdit(forceEdit);\n }, [forceEdit]);\n\n useEffect(() => {\n onEditChange && onEditChange(isEdit);\n }, [isEdit]);\n\n return (\n <>\n \n {showHeader && (\n \n \n {title && (\n \n {title}\n \n )}\n \n {isShowAnalysisNotExecuted && (\n \n \n \n Analysis Not Executed\n \n
\n \n )}\n\n \n {!isQASpecLocked ? (\n <>\n \n {showSaveBtn && isEdit && (\n \n \n \n )}\n \n \n {showEditBtn &&\n show &&\n !isEdit &&\n allowEdit &&\n hasPermissionEdit && (\n }\n style={{ border: 'none' }}\n onClick={toggleEditMode}\n />\n )}\n {showCancelBtn && isEdit && (\n \n \n \n )}\n \n {extraButtons?.map((buttonItem, idx) => (\n \n {buttonItem(isEdit)}\n \n ))}\n\n {isEdit && (\n <>\n {buttons?.map((buttonItem, idx) =>\n buttonItem ? (\n \n {buttonItem(isEdit)}\n \n ) : null\n )}\n \n )}\n \n ) : null}\n \n )}\n \n \n {typeof children === 'function' ? children(isEdit) : children}\n \n \n \n \n );\n};\n\nexport default WithQaGridHeader;\n","import { Badge } from 'antd';\n\nimport {\n QaSpecIngredient,\n QaSpecDocsAndCertificates,\n QaSpecProduct,\n QaSpecManufacturingProcess,\n QaFormula,\n QaAllergen,\n QaSpecComponent,\n QaSpecNutritionData,\n QaSpecContacts,\n QaFreshSeafood,\n QaFreshMeat,\n QaPackaging,\n QaClaims,\n QaFreshProduce,\n QaFreshDeli,\n QaSpecProductContain,\n // QaPetNonFood,\n QaPetFood,\n} from 'pages/qa-spec/components';\n\nimport { useQaTabChecker } from 'pages/qa-spec/components/edit-tab-checker';\n\nconst EditItemCount = ({ tabKey, children }) => {\n const { editItemCountByTab } = useQaTabChecker();\n\n return (\n \n {children && children}\n \n );\n};\n\nconst qaPackagingRender = ({ type, productFull }) => ({\n key: 'labeling',\n icon: (\n \n \n \n ),\n des: 'Labeling',\n content: (isTabActive) => (\n \n ),\n visible: type !== 'Pet',\n});\n\nconst qaFreshMeatRender = {\n key: 'fresh-meat',\n icon: (\n \n \n \n ),\n des: 'Fresh - Meat',\n content: ,\n};\n\nconst qaClaimsRender = (type) => ({\n key: 'claims',\n icon: (\n \n \n \n ),\n des: 'Claims',\n content: (isTabActive) => ,\n visible: type !== 'Pet',\n});\n\nexport const getTabListByQaType = ({\n type,\n refetchProductItems,\n productLoading,\n productId,\n productFull,\n productEnums,\n productItemModules,\n ownerId,\n}) => {\n return [\n {\n key: 'product-specification',\n icon: (\n \n \n \n ),\n des: 'Product Specification',\n content: (isTabActive) => (\n \n ),\n visible: true,\n },\n {\n key: 'fresh-seafood',\n icon: (\n \n \n \n ),\n des: 'Fresh - Seafood',\n content: (isTabActive) => ,\n visible: type === 'Fresh - Seafood',\n },\n {\n key: 'fresh-meat',\n icon: (\n \n \n \n ),\n des: 'Fresh - Meat',\n content: (isTabActive) => ,\n visible: type === 'Fresh - Meat',\n },\n {\n key: 'fresh-produce',\n icon: (\n \n \n \n ),\n des: 'Fresh - Produce',\n content: (isTabActive) => ,\n visible: type === 'Fresh - Produce',\n },\n\n {\n key: 'fresh-deli',\n icon: (\n \n \n \n ),\n des: 'Fresh - Deli',\n content: (isTabActive) => ,\n visible: type === 'Fresh - Deli',\n },\n {\n key: 'ingredients',\n icon: (\n \n \n \n ),\n des: 'Ingredients',\n content: (isTabActive) => (\n <>{isTabActive && }\n ),\n visible: type !== 'HBC / OTC' && type !== 'Non-Food',\n },\n {\n key: 'allergens',\n icon: (\n \n \n \n ),\n des: 'Allergens',\n content: (isTabActive) => (\n <>\n {isTabActive && (\n \n )}\n \n ),\n visible: true,\n },\n {\n key: 'components',\n icon: (\n \n \n \n ),\n des: 'Components',\n content: (isTabActive) => ,\n visible: type === 'HBC / OTC' || type === 'Non-Food' || type === 'Pet',\n },\n {\n key: 'facts-panel',\n icon: (\n \n \n \n ),\n des: 'Facts Panel',\n content: (isTabActive) => ,\n visible: type !== 'Non-Food',\n },\n qaClaimsRender(type),\n {\n key: 'pet-food',\n icon: (\n \n \n \n ),\n des: 'Pet Food',\n content: (isTabActive) => ,\n visible: type === 'Pet',\n },\n // {\n // key: 'pet-non-food',\n // icon: (\n // \n // \n // \n // ),\n // des: 'Pet Non-Food',\n // content: (activeTab) => {\n // if (activeTab === 'pet-non-food')\n // return ;\n // },\n // visible: type === 'Pet',\n // },\n {\n key: 'formula',\n icon: (\n \n \n \n ),\n des: 'Formula',\n content: (activeTab) => {\n return ;\n },\n visible: true,\n },\n {\n key: 'manufacturing-process',\n icon: (\n \n \n \n ),\n des: 'Manufacturing Process',\n content: (isTabActive) => (\n \n ),\n visible: true,\n },\n qaPackagingRender({ type, productFull }),\n {\n key: 'contacts',\n icon: (\n \n \n \n ),\n des: 'Contacts',\n content: (isTabActive) => ,\n visible: true,\n },\n {\n key: 'documents-certificates',\n icon: (\n \n \n \n ),\n des: 'Documents/ Certificates',\n content: (isTabActive) => (\n <>\n {isTabActive && }\n \n ),\n visible: true,\n },\n {\n key: 'product-contains',\n icon: (\n \n \n \n ),\n des: 'Product Contains',\n content: (activeTab) => ,\n visible: checkIsDollarProduct(ownerId),\n },\n ];\n};\n\nexport const checkIsDollarProduct = (ownerId) => {\n return ownerId === +process.env.REACT_APP_DOLLAR_GENERAL_ID;\n};\n","import { useQuery } from '@tanstack/react-query';\nimport { useSelector } from 'react-redux';\n\nimport userSelectors from '@redux/user/selectors';\n\nimport { useGetQaSpecDataHeader } from 'pages/qa-spec/query';\nimport { useGetProductFullView } from 'hooks';\nimport useCheckAssignProductToSupplier from 'pages/qa-spec/hooks/useCheckAssignProductToSupplier';\n\nimport { checkIsDollarProduct } from 'pages/qa-spec/views/qa-spec-detail/utils';\n\nimport * as qasSpecServices from 'services/qas-require-field';\nexport const requiredFieldsMap = {\n 'eCommerce.smartLabelTemplate': 'qaSpecification.smartLabelTemplate',\n //* product spec tab\n targetMarket: 'qaSpecification.qaSpecProductSpecification.targetMarket',\n 'placeOfItemActivity.placeOfProductActivity.countryOfOrigin.countryCode':\n 'qaSpecification.qaSpecProductSpecification.countryOfOrigin',\n 'tdcProperties.codeDateExample':\n 'qaSpecification.qaSpecProductSpecification.codeDateExample',\n 'tdcProperties.unit_MinimumShelfLife':\n 'qaSpecification.qaSpecProductSpecification.minimumShelfLife',\n 'tdcProperties.case_TemperatureRangeHigh':\n 'qaSpecification.qaSpecProductSpecification.caseTemperatureRangeHigh',\n 'tdcProperties.case_TemperatureRangeLow':\n 'qaSpecification.qaSpecProductSpecification.caseTemperatureRangeLow',\n 'tdcProperties.case_ShippingTemperatureRangeHigh':\n 'qaSpecification.qaSpecProductSpecification.caseShippingTemperatureHigh',\n 'tdcProperties.case_ShippingTemperatureRangeLow':\n 'qaSpecification.qaSpecProductSpecification.caseShippingTemperatureLow',\n //* labeling tab\n 'consumerInstructions.consumerInstructions.consumerUsageInstructions.value':\n 'qaSpecification.labeling.usage',\n //* ingredient tab\n 'foodAndBeverageIngredient.ingredientStatement.value':\n 'qaSpecification.qaSpecIngredients.ingredientStatement',\n};\n\nexport const getGetQaSpecRequiredFieldsKeys = (params, userId) => {\n return ['get-qa-spec-required-fields', params, userId];\n};\n\nexport const useGetQaSpecRequiredFields = (props) => {\n const { params, fieldPath, ...options } = props;\n\n const userInfo = useSelector(userSelectors.makeSelectUserInfo());\n\n const isDollarProduct = checkIsDollarProduct(params?.ownerId);\n\n const getGetQaSpecRequiredFields = async ({ queryKey }) => {\n const params = queryKey[1];\n\n const response = await qasSpecServices.getQaSpecRequiredFieldForProduct(\n params\n );\n\n if (!response.isSuccess || !response?.data?.requiredFields) return;\n\n //* map data\n const requiredFields = response.data.requiredFields\n .filter((field) => {\n //* filter out product contain field when product does not belong to dollar general\n\n //* if product belongs to dollar general, accept all fields\n if (isDollarProduct) return true;\n\n //* if not, accept fields that is not product contain fields\n const isProductContainField = field.includes(\n 'qaSpecification.qaSpecProductContains'\n );\n\n return !isProductContainField;\n })\n .map((field) => {\n //* some fields in Product Spec tab have difference fieldName with required fields, format them to standard field full path for logic flow\n const formattedFields = requiredFieldsMap[field];\n\n let finalField = formattedFields ? formattedFields : field;\n\n return finalField;\n });\n\n return requiredFields;\n };\n\n return useQuery({\n queryKey: getGetQaSpecRequiredFieldsKeys(params, { userId: userInfo?.id }),\n queryFn: getGetQaSpecRequiredFields,\n ...options,\n });\n};\n\nexport const useGetQaSpecRequiredFieldsInQaSpecFullView = (props) => {\n const { productId } = props;\n\n const { productFull } = useGetProductFullView({\n productId,\n });\n\n const { qaSpecDataHeader, defaultType } = useGetQaSpecDataHeader({\n id: productId,\n isEnabled: !!productId,\n });\n\n const productType = qaSpecDataHeader?.type || defaultType;\n\n const { checkAssignProductToSupplier } = useCheckAssignProductToSupplier();\n const isProductAssignedByRetailer = checkAssignProductToSupplier();\n\n return useGetQaSpecRequiredFields({\n params: {\n ownerId: productFull?.ownerId,\n productType,\n },\n enabled:\n !!isProductAssignedByRetailer &&\n !!productFull &&\n !!productType &&\n !!productFull?.ownerId,\n });\n};\n","import { useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useQuery } from '@tanstack/react-query';\nimport { useQueryClient } from '@tanstack/react-query';\n\nimport { useGetEnumOptions } from 'pages/qa-spec/hooks';\nimport { Button } from 'antd';\nimport { PACKAGING_LIMIT_CHARACTERS } from 'pages/qa-spec/constant';\nimport CertificateFormList from './CertificateFormList';\nimport { UploadOutlined } from '@ant-design/icons';\nimport { Form } from 'common/components';\nimport { BasicFormItem } from 'common/components/form/basic-form';\nimport { sortBy } from 'lodash';\nimport useCheckAssignProductToSupplier from 'pages/qa-spec/hooks/useCheckAssignProductToSupplier';\nimport SnapshotFormItem from 'pages/qa-spec/components/qa-spec-tab/SnapshotFormItem';\nimport { getSnapshotQaSpecPackaging } from 'services/product';\n\nimport { getFormattedValue } from 'pages/qa-spec/utils/index';\nimport { useCheckSnapshotForRetailer } from 'pages/qa-spec/hooks';\nimport { renderPopoverContent } from 'pages/qa-spec/utils';\n\nimport { parsePackagingData } from './utils';\nimport { useGetQaSpecRequiredFieldsInQaSpecFullView } from 'pages/qa-spec/hooks/useGetQaSpecRequiredFields';\n\nconst makeSecondaryLanguageOption = (option) => {\n return {\n value: option?.enumCode,\n displayName: `${\n option.enumDescription\n } - (${option.enumCode.toUpperCase()})`,\n };\n};\n\nexport const useGetQaPackagingFormDefine = ({\n handleToggleUploadDocumentModal,\n setUploadModalTitle,\n snapshotData,\n supplierModifiedData,\n productFull,\n}) => {\n const { checkAssignProductToSupplier } = useCheckAssignProductToSupplier();\n const isProductAssignedToSupplier = checkAssignProductToSupplier();\n\n const packagingEnumOptions = useGetEnumOptions({\n optionMapping: useMemo(\n () => (option) => ({\n ...option,\n value: option.enumDisplayName,\n displayName: option.enumDisplayName,\n }),\n []\n ),\n })?.packaging;\n\n const { id: productId } = useParams();\n\n const isToggleSnapshot = useCheckSnapshotForRetailer();\n\n const { isLoading } = useGetSnapshotQaPackaging({\n enabled: !!productId && isToggleSnapshot,\n productId,\n });\n\n const enumType = {\n uom: packagingEnumOptions.uom,\n frontOfPackIcons: packagingEnumOptions.frontOfPackIcons,\n recyclable: packagingEnumOptions.recyclabel,\n qrCode: packagingEnumOptions.qrCode,\n bilingual: packagingEnumOptions.bilingual,\n hasFoodGradePlasticsCertifier:\n packagingEnumOptions.hasFoodGradePlasticsCertifier,\n recycledMaterial: packagingEnumOptions.recycledMaterial,\n soyInk: packagingEnumOptions.soyInk,\n secondaryLanguage: packagingEnumOptions.secondaryLanguage,\n vegetableBasedInk: packagingEnumOptions.vegetableBasedInk,\n hasFoodGradePlasticsCertifier:\n packagingEnumOptions.hasFoodGradePlasticsCertifier,\n };\n\n const getSecondaryLanguageFormatted = (snapshotData, name) => {\n if (!snapshotData?.length) return 'N/A';\n const arrList = snapshotData.reduce((accumulator, currentValue) => {\n const currentEnum = enumType[name]?.find(\n (item) => currentValue === item.enumCode\n );\n\n accumulator.push(\n `${\n currentEnum?.enumDescription\n } - (${currentEnum?.enumCode?.toUpperCase()})`\n );\n\n return accumulator;\n }, []);\n return arrList.join(', ');\n };\n\n const { data: requiredFields } = useGetQaSpecRequiredFieldsInQaSpecFullView({\n productId,\n });\n\n const checkFieldRequired = (fieldName) => {\n const isAWGOwnerRequired =\n fieldName === 'productContainsBioengineeredIngredients' &&\n productFull?.ownerId === +process.env.REACT_APP_AWG_ID;\n\n if (isAWGOwnerRequired) return true;\n\n if (!requiredFields) return false;\n\n if (!isProductAssignedToSupplier) return false;\n\n return requiredFields.includes(`qaSpecification.labeling.${fieldName}`);\n };\n\n const qaPackagingFormDefine = useMemo(() => {\n const formProductDefine = [\n {\n name: 'productName',\n label: 'Product Name:',\n layout: 'horizontal',\n labelCol: { flex: '135px' },\n supplierModifiedData:\n supplierModifiedData?.['productName']?.trim() ?? '',\n snapshotData: snapshotData?.['productName']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Product Name',\n snapshotData?.['productName']?.trim() ?? '',\n supplierModifiedData?.['productName']?.trim() ?? ''\n ),\n },\n {\n name: 'upc12',\n label: 'UPC12:',\n inputProps: {\n style: { width: '100%' },\n min: '0',\n onKeyPress: (event) => {\n if (!/[0-9]/.test(event.key)) {\n event.preventDefault();\n }\n },\n },\n layout: 'horizontal',\n labelCol: { flex: '135px' },\n supplierModifiedData: supplierModifiedData?.['upc12']?.trim() ?? '',\n snapshotData: snapshotData?.['upc12']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'UPC12',\n snapshotData?.['upc12']?.trim() ?? '',\n supplierModifiedData?.['upc12']?.trim() ?? ''\n ),\n },\n {\n name: 'truncatedUpc',\n label: 'Truncated UPC:',\n type: 'numeric',\n layout: 'horizontal',\n labelCol: { flex: '135px' },\n inputProps: {\n style: { width: '100%' },\n min: '0',\n onKeyPress: (event) => {\n if (!/[0-9]/.test(event.key)) {\n event.preventDefault();\n }\n },\n },\n supplierModifiedData: supplierModifiedData?.['truncatedUpc'],\n snapshotData: snapshotData?.['truncatedUpc'],\n renderPopoverContent: renderPopoverContent(\n 'Truncated UPC',\n snapshotData?.['truncatedUpc'],\n supplierModifiedData?.['truncatedUpc']\n ),\n },\n {\n name: 'secondaryDescriptor',\n label: 'Secondary Descriptor:',\n layout: 'horizontal',\n labelCol: { flex: '135px' },\n supplierModifiedData:\n supplierModifiedData?.['secondaryDescriptor']?.trim() ?? '',\n snapshotData: snapshotData?.['secondaryDescriptor']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Secondary Descriptor',\n snapshotData?.['secondaryDescriptor']?.trim() ?? '',\n supplierModifiedData?.['secondaryDescriptor']?.trim() ?? ''\n ),\n },\n {\n name: 'tertiaryDescriptor',\n label: 'Tertiary Descriptor:',\n layout: 'horizontal',\n labelCol: { flex: '135px' },\n supplierModifiedData:\n supplierModifiedData?.['tertiaryDescriptor']?.trim() ?? '',\n snapshotData: snapshotData?.['tertiaryDescriptor']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Tertiary Descriptor',\n snapshotData?.['tertiaryDescriptor']?.trim() ?? '',\n supplierModifiedData?.['tertiaryDescriptor']?.trim() ?? ''\n ),\n },\n [\n { rowConfig: { gutter: [15, 15] } },\n {\n name: 'size',\n label: 'Size:',\n type: 'numeric',\n layout: 'horizontal',\n labelCol: { flex: '135px' },\n colProps: {\n xs: 12,\n },\n inputProps: {\n style: { width: '100%' },\n min: 0,\n },\n style: { flexWrap: 'nowrap' },\n supplierModifiedData: supplierModifiedData?.['size'],\n snapshotData: snapshotData?.['size'],\n renderPopoverContent: renderPopoverContent(\n 'Size',\n snapshotData?.['size'],\n supplierModifiedData?.['size']\n ),\n },\n {\n name: 'uom',\n label: 'UOM:',\n type: 'select',\n selectProps: {\n options: sortBy(packagingEnumOptions.uom, ['displayName']),\n inputProps: {\n allowClear: true,\n showSearch: true,\n },\n },\n layout: 'horizontal',\n labelCol: { flex: '40px' },\n colProps: {\n xs: 12,\n },\n formattedValue: getFormattedValue(\n snapshotData?.['uom'],\n 'uom',\n enumType\n ),\n supplierModifiedData: supplierModifiedData?.['uom'],\n snapshotData: snapshotData?.['uom'],\n renderPopoverContent: renderPopoverContent(\n 'UOM',\n snapshotData?.['uom'],\n supplierModifiedData?.['uom'],\n getFormattedValue(snapshotData?.['uom'], 'uom', enumType),\n null\n ),\n },\n ],\n ];\n\n const formLeftBottomDefine = [\n {\n name: 'ingredientStatement',\n label: 'Ingredient Statement',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.ingredientStatement,\n showCount: true,\n },\n supplierModifiedData:\n supplierModifiedData?.['ingredientStatement'] ?? '',\n snapshotData: snapshotData?.['ingredientStatement'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Ingredient Statement',\n snapshotData?.['ingredientStatement'] ?? '',\n supplierModifiedData?.['ingredientStatement'] ?? ''\n ),\n },\n {\n name: 'allergenStatement',\n label: 'Allergen Statement',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.allergenStatement,\n showCount: true,\n },\n supplierModifiedData: supplierModifiedData?.['allergenStatement'] ?? '',\n snapshotData: snapshotData?.['allergenStatement'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Allergen Statement',\n snapshotData?.['allergenStatement'] ?? '',\n supplierModifiedData?.['allergenStatement'] ?? ''\n ),\n },\n {\n name: 'storageInstructions',\n label: 'Storage Instructions',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.storageInstructions,\n showCount: true,\n },\n supplierModifiedData:\n supplierModifiedData?.['storageInstructions'] ?? '',\n snapshotData: snapshotData?.['storageInstructions'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Storage Instructions',\n snapshotData?.['storageInstructions'] ?? '',\n supplierModifiedData?.['storageInstructions'] ?? ''\n ),\n },\n {\n name: 'handlingInstructions',\n label: 'Handling Instructions',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.handlingInstructions,\n showCount: true,\n },\n supplierModifiedData:\n supplierModifiedData?.['handlingInstructions'] ?? '',\n snapshotData: snapshotData?.['handlingInstructions'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Handling Instructions',\n snapshotData?.['handlingInstructions'] ?? '',\n supplierModifiedData?.['handlingInstructions'] ?? ''\n ),\n },\n {\n name: 'thawingInstructions',\n label: 'Thawing Instructions',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.thawingInstructions,\n showCount: true,\n },\n supplierModifiedData:\n supplierModifiedData?.['thawingInstructions'] ?? '',\n snapshotData: snapshotData?.['thawingInstructions'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Thawing Instructions',\n snapshotData?.['thawingInstructions'] ?? '',\n supplierModifiedData?.['thawingInstructions'] ?? ''\n ),\n },\n {\n name: 'productContainsBioengineeredIngredients',\n label: 'Product Contains Bioengineered Ingredients',\n type: 'select',\n rules: [\n {\n required: checkFieldRequired(\n 'productContainsBioengineeredIngredients'\n ),\n message: 'Product Contains Bioengineered Ingredients is required',\n },\n ],\n selectProps: {\n options: packagingEnumOptions.productContainsBioengineeredIngredients,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['productContainsBioengineeredIngredients'],\n 'productContainsBioengineeredIngredients',\n enumType\n ),\n supplierModifiedData:\n supplierModifiedData?.['productContainsBioengineeredIngredients'],\n snapshotData: snapshotData?.['productContainsBioengineeredIngredients'],\n renderPopoverContent: renderPopoverContent(\n 'Product Contains Bioengineered Ingredients',\n snapshotData?.['productContainsBioengineeredIngredients'],\n supplierModifiedData?.['productContainsBioengineeredIngredients'],\n getFormattedValue(\n snapshotData?.['productContainsBioengineeredIngredients'],\n 'productContainsBioengineeredIngredients',\n enumType\n ),\n null\n ),\n },\n {\n name: 'bioengineeredStatement',\n label: 'Bioengineered Ingredients Statement',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.bioengineeredStatement,\n showCount: true,\n },\n supplierModifiedData:\n supplierModifiedData?.['bioengineeredStatement'] ?? '',\n snapshotData: snapshotData?.['bioengineeredStatement'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Bioengineered Ingredients Statement',\n snapshotData?.['bioengineeredStatement'] ?? '',\n supplierModifiedData?.['bioengineeredStatement'] ?? ''\n ),\n },\n {\n name: 'warningStatement',\n label: 'Warning / Caution Statement',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.warningStatement,\n showCount: true,\n },\n supplierModifiedData: supplierModifiedData?.['warningStatement'] ?? '',\n snapshotData: snapshotData?.['warningStatement'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Warning / Caution Statement',\n snapshotData?.['warningStatement'] ?? '',\n supplierModifiedData?.['warningStatement'] ?? ''\n ),\n },\n [\n { rowConfig: { gutter: [15, 15] } },\n {\n name: 'frontOfPackIcons',\n label: 'Front of Pack Icons',\n type: 'select',\n selectProps: {\n options: packagingEnumOptions.frontOfPackIcons,\n inputProps: {\n allowClear: true,\n },\n },\n colProps: { xs: 12 },\n formattedValue: getFormattedValue(\n snapshotData?.['frontOfPackIcons'],\n 'frontOfPackIcons',\n enumType\n ),\n supplierModifiedData: supplierModifiedData?.['frontOfPackIcons'],\n snapshotData: snapshotData?.['frontOfPackIcons'],\n renderPopoverContent: renderPopoverContent(\n 'Front of Pack Icons',\n snapshotData?.['frontOfPackIcons'],\n supplierModifiedData?.['frontOfPackIcons'],\n getFormattedValue(\n snapshotData?.['frontOfPackIcons'],\n 'frontOfPackIcons',\n enumType\n ),\n null\n ),\n },\n {\n noStyle: true,\n shouldUpdate: (prevValues, currentValues) =>\n prevValues?.['frontOfPackIcons'] !==\n currentValues?.['frontOfPackIcons'],\n renderInput:\n ({ allowEdit }) =>\n ({ getFieldValue }) => {\n const frontOfPackIconsValue = getFieldValue('frontOfPackIcons');\n\n return (\n \n }\n disabled={\n frontOfPackIconsValue === 'No' ||\n !frontOfPackIconsValue ||\n !allowEdit\n }\n onClick={() => {\n handleToggleUploadDocumentModal();\n setUploadModalTitle(\n 'Upload Front of Pack Icons Document'\n );\n }}\n >\n Upload\n \n \n );\n },\n },\n ],\n [\n { rowConfig: { gutter: [15, 15] } },\n {\n name: 'recyclable',\n label: 'Recyclable',\n type: 'select',\n selectProps: {\n options: packagingEnumOptions.recyclabel,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['recyclable'],\n 'recyclable',\n enumType\n ),\n supplierModifiedData: supplierModifiedData?.['recyclable'],\n snapshotData: snapshotData?.['recyclable'],\n renderPopoverContent: renderPopoverContent(\n 'Recyclable',\n snapshotData?.['recyclable'],\n supplierModifiedData?.['recyclable'],\n getFormattedValue(\n snapshotData?.['recyclable'],\n 'recyclable',\n enumType\n ),\n null\n ),\n colProps: { xs: 12 },\n },\n {\n noStyle: true,\n shouldUpdate: (prevValues, currentValues) =>\n prevValues?.['recyclable'] !== currentValues?.['recyclable'],\n renderInput:\n ({ allowEdit }) =>\n ({ getFieldValue }) => {\n const recyclableValue = getFieldValue('recyclable');\n\n const disabled = recyclableValue === 'No' || !recyclableValue;\n\n return (\n \n \n \n );\n },\n colProps: { xs: 12 },\n },\n ],\n [\n { rowConfig: { gutter: [15, 15] } },\n {\n name: 'totalRecyclableContentPercentage',\n label: 'Total Recycled Content Percentage',\n type: 'numeric',\n colProps: { xs: 12 },\n inputProps: { style: { width: '100%' } },\n supplierModifiedData:\n supplierModifiedData?.['totalRecyclableContentPercentage'],\n snapshotData: snapshotData?.['totalRecyclableContentPercentage'],\n renderPopoverContent: renderPopoverContent(\n 'Total Recycled Content Percentage',\n snapshotData?.['totalRecyclableContentPercentage'],\n supplierModifiedData?.['totalRecyclableContentPercentage']\n ),\n },\n {\n name: 'postConsumerRecycledContentPercentage',\n label: 'Post Consumer Recycled Content Percentage',\n type: 'numeric',\n colProps: { xs: 12 },\n inputProps: { style: { width: '100%' } },\n supplierModifiedData:\n supplierModifiedData?.['postConsumerRecycledContentPercentage'],\n snapshotData: snapshotData?.['postConsumerRecycledContentPercentage'],\n renderPopoverContent: renderPopoverContent(\n 'Post Consumer Recycled Content Percentage',\n snapshotData?.['postConsumerRecycledContentPercentage'],\n supplierModifiedData?.['postConsumerRecycledContentPercentage']\n ),\n },\n ],\n {\n name: 'packagingType',\n label: 'Packaging Type',\n type: 'select',\n selectProps: {\n options: sortBy(packagingEnumOptions.packagingType, ['displayName']),\n inputProps: {\n allowClear: true,\n showSearch: true,\n },\n },\n supplierModifiedData: supplierModifiedData?.['packagingType'],\n snapshotData: snapshotData?.['packagingType'],\n renderPopoverContent: renderPopoverContent(\n 'Packaging Type',\n snapshotData?.['packagingType'],\n supplierModifiedData?.['packagingType']\n ),\n },\n {\n name: 'packagingMaterial',\n label: 'Packaging Material',\n type: 'select',\n selectProps: {\n options: sortBy(packagingEnumOptions.packagingMaterial, [\n 'displayName',\n ]),\n inputProps: {\n allowClear: true,\n showSearch: true,\n },\n },\n supplierModifiedData: supplierModifiedData?.['packagingMaterial'],\n snapshotData: snapshotData?.['packagingMaterial'],\n renderPopoverContent: renderPopoverContent(\n 'Packaging Material',\n snapshotData?.['packagingMaterial'],\n supplierModifiedData?.['packagingMaterial']\n ),\n },\n [\n { rowConfig: { gutter: [15, 15] } },\n {\n name: 'qrCode',\n label: 'QR Code',\n type: 'select',\n selectProps: {\n options: packagingEnumOptions.qrCode,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['qrCode'],\n 'qrCode',\n enumType\n ),\n supplierModifiedData: supplierModifiedData?.['qrCode'],\n snapshotData: snapshotData?.['qrCode'],\n renderPopoverContent: renderPopoverContent(\n 'QR Code',\n snapshotData?.['qrCode'],\n supplierModifiedData?.['qrCode'],\n getFormattedValue(snapshotData?.['qrCode'], 'qrCode', enumType),\n null\n ),\n colProps: { xs: 12 },\n },\n {\n noStyle: true,\n shouldUpdate: (prevValues, currentValues) =>\n prevValues?.['qrCode'] !== currentValues?.['qrCode'],\n renderInput:\n ({ allowEdit }) =>\n ({ getFieldValue }) => {\n const qrCodeValue = getFieldValue('qrCode');\n\n return (\n \n }\n disabled={\n qrCodeValue === 'No' || !qrCodeValue || !allowEdit\n }\n onClick={() => {\n handleToggleUploadDocumentModal();\n setUploadModalTitle('Upload QR Code Document');\n }}\n >\n Upload\n \n \n );\n },\n },\n {\n name: 'bilingual',\n label: 'Additional Languages on Label',\n type: 'select',\n selectProps: {\n options: packagingEnumOptions.bilingual,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['bilingual'],\n 'bilingual',\n enumType\n ),\n supplierModifiedData: supplierModifiedData?.['bilingual'],\n snapshotData: snapshotData?.['bilingual'],\n renderPopoverContent: renderPopoverContent(\n 'Additional Languages on Label',\n snapshotData?.['bilingual'],\n supplierModifiedData?.['bilingual'],\n getFormattedValue(\n snapshotData?.['bilingual'],\n 'bilingual',\n enumType\n ),\n null\n ),\n colProps: { xs: 12 },\n },\n {\n noStyle: true,\n shouldUpdate: (prevValues, currentValues) =>\n prevValues?.['bilingual'] !== currentValues?.['bilingual'],\n renderInput:\n ({ allowEdit }) =>\n ({ getFieldValue }) => {\n const bilingualValue = getFieldValue('bilingual');\n\n const disabled = bilingualValue === 'No' || !bilingualValue;\n\n return (\n \n \n makeSecondaryLanguageOption(option)\n ),\n ['displayName']\n ),\n }}\n allowEdit={allowEdit}\n />\n \n );\n },\n colProps: { xs: 12 },\n },\n ],\n ];\n\n const formProductClaimFirstSectionDefine = [\n {\n name: 'claim1',\n label: 'Claim 1:',\n layout: 'horizontal',\n supplierModifiedData: supplierModifiedData?.['claim1']?.trim() ?? '',\n snapshotData: snapshotData?.['claim1']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Claim 1',\n snapshotData?.['claim1']?.trim() ?? '',\n supplierModifiedData?.['claim1']?.trim() ?? ''\n ),\n },\n {\n name: 'claim2',\n label: 'Claim 2:',\n layout: 'horizontal',\n supplierModifiedData: supplierModifiedData?.['claim2']?.trim() ?? '',\n snapshotData: snapshotData?.['claim2']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Claim 2',\n snapshotData?.['claim2']?.trim() ?? '',\n supplierModifiedData?.['claim2']?.trim() ?? ''\n ),\n },\n {\n name: 'claim3',\n label: 'Claim 3:',\n layout: 'horizontal',\n supplierModifiedData: supplierModifiedData?.['claim3']?.trim() ?? '',\n snapshotData: snapshotData?.['claim3']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Claim 3',\n snapshotData?.['claim3']?.trim() ?? '',\n supplierModifiedData?.['claim3']?.trim() ?? ''\n ),\n },\n {\n name: 'claim4',\n label: 'Claim 4:',\n layout: 'horizontal',\n supplierModifiedData: supplierModifiedData?.['claim4']?.trim() ?? '',\n snapshotData: snapshotData?.['claim4']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Claim 4',\n snapshotData?.['claim4']?.trim() ?? '',\n supplierModifiedData?.['claim4']?.trim() ?? ''\n ),\n },\n {\n name: 'claim5',\n label: 'Claim 5:',\n layout: 'horizontal',\n supplierModifiedData: supplierModifiedData?.['claim5']?.trim() ?? '',\n snapshotData: snapshotData?.['claim5']?.trim() ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Claim 5',\n snapshotData?.['claim5']?.trim() ?? '',\n supplierModifiedData?.['claim5']?.trim() ?? ''\n ),\n },\n ];\n\n const formRightSecondSection = [\n {\n name: 'romanceCopy',\n label: 'Romance Copy',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.romanceCopy,\n showCount: true,\n },\n supplierModifiedData: supplierModifiedData?.['romanceCopy'] ?? '',\n snapshotData: snapshotData?.['romanceCopy'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Romance Copy',\n snapshotData?.['romanceCopy'] ?? '',\n supplierModifiedData?.['romanceCopy'] ?? ''\n ),\n },\n {\n name: 'usage',\n label: 'Usage',\n type: 'textarea',\n rules: [\n {\n required: checkFieldRequired('usage'),\n message: 'Usage is required',\n },\n ],\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.usage,\n showCount: true,\n },\n supplierModifiedData: supplierModifiedData?.['usage'] ?? '',\n snapshotData: snapshotData?.['usage'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Usage',\n snapshotData?.['usage'] ?? '',\n supplierModifiedData?.['usage'] ?? ''\n ),\n },\n {\n name: 'cookingInstructions',\n label: 'Cooking Instructions/ Directions',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.cookingInstructions,\n showCount: true,\n },\n supplierModifiedData:\n supplierModifiedData?.['cookingInstructions'] ?? '',\n snapshotData: snapshotData?.['cookingInstructions'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Cooking Instructions/ Directions',\n snapshotData?.['cookingInstructions'] ?? '',\n supplierModifiedData?.['cookingInstructions'] ?? ''\n ),\n },\n {\n name: 'recipe',\n label: 'Recipe',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.recipe,\n showCount: true,\n },\n supplierModifiedData: supplierModifiedData?.['recipe'] ?? '',\n snapshotData: snapshotData?.['recipe'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Recipe',\n snapshotData?.['recipe'] ?? '',\n supplierModifiedData?.['recipe'] ?? ''\n ),\n },\n ];\n\n const formDietaryThirdSectionDefine = [\n [\n { rowConfig: { gutter: [15, 15], style: { marginBottom: 10 } } },\n {\n name: 'kosherYN',\n label: 'Kosher:',\n type: 'checkbox',\n valuePropName: 'checked',\n supplierModifiedData: supplierModifiedData?.['kosherYN'] ?? false,\n snapshotData: snapshotData?.['kosherYN'] ?? false,\n renderPopoverContent: renderPopoverContent(\n 'Kosher',\n snapshotData?.['kosherYN'] ?? false,\n supplierModifiedData?.['kosherYN'] ?? false,\n null,\n 'checkbox'\n ),\n colProps: {\n xs: 8,\n },\n layout: 'horizontal',\n labelCol: {\n flex: '79px',\n },\n },\n {\n colProps: {\n xs: 16,\n },\n noStyle: true,\n shouldUpdate: () => true,\n renderInput:\n ({ allowEdit }) =>\n ({ getFieldValue }) => {\n const enabled = getFieldValue('kosherYN');\n const seletecterCertifiers = getSelectedCertifiers({\n getFieldValue,\n });\n\n return (\n ({\n disabled: seletecterCertifiers?.includes(option.value),\n }),\n inputProps: {\n allowClear: true,\n showSearch: true,\n },\n }}\n snapshotData={snapshotData}\n supplierModifiedData={supplierModifiedData}\n isLoadingSnapshot={isLoading}\n />\n );\n },\n },\n ],\n [\n { rowConfig: { gutter: [15, 15], style: { marginBottom: 10 } } },\n {\n name: 'organicYN',\n label: 'Organic:',\n type: 'checkbox',\n layout: 'horizontal',\n valuePropName: 'checked',\n supplierModifiedData: supplierModifiedData?.['organicYN'] ?? false,\n snapshotData: snapshotData?.['organicYN'] ?? false,\n renderPopoverContent: renderPopoverContent(\n 'Organic',\n snapshotData?.['organicYN'] ?? false,\n supplierModifiedData?.['organicYN'] ?? false,\n null,\n 'checkbox'\n ),\n colProps: {\n xs: 8,\n },\n labelCol: {\n flex: '79px',\n },\n },\n {\n colProps: {\n xs: 16,\n },\n noStyle: true,\n shouldUpdate: () => true,\n renderInput:\n ({ allowEdit }) =>\n ({ getFieldValue }) => {\n const enabled = getFieldValue('organicYN');\n\n return (\n \n );\n },\n },\n ],\n [\n { rowConfig: { gutter: [15, 15], style: { marginBottom: 10 } } },\n {\n name: 'halalYN',\n label: 'Halal:',\n type: 'checkbox',\n valuePropName: 'checked',\n supplierModifiedData: supplierModifiedData?.['halalYN'] ?? false,\n snapshotData: snapshotData?.['halalYN'] ?? false,\n renderPopoverContent: renderPopoverContent(\n 'Halal',\n snapshotData?.['halalYN'] ?? false,\n supplierModifiedData?.['halalYN'] ?? false,\n null,\n 'checkbox'\n ),\n colProps: {\n xs: 8,\n },\n layout: 'horizontal',\n labelCol: {\n flex: '79px',\n },\n },\n {\n colProps: {\n xs: 16,\n },\n noStyle: true,\n shouldUpdate: () => true,\n renderInput:\n ({ allowEdit, inputProps }) =>\n ({ getFieldValue }) => {\n const enabled = getFieldValue('halalYN');\n const seletecterCertifiers = getSelectedCertifiers({\n getFieldValue,\n });\n\n return (\n ({\n disabled: seletecterCertifiers?.includes(option.value),\n }),\n inputProps: {\n allowClear: true,\n showSearch: true,\n },\n }}\n snapshotData={snapshotData}\n supplierModifiedData={supplierModifiedData}\n isLoadingSnapshot={isLoading}\n />\n );\n },\n },\n ],\n [\n { rowConfig: { gutter: [15, 15], style: { marginBottom: 10 } } },\n {\n name: 'nonGMOYN',\n label: 'Non-GMO:',\n type: 'checkbox',\n valuePropName: 'checked',\n supplierModifiedData: supplierModifiedData?.['nonGMOYN'] ?? false,\n snapshotData: snapshotData?.['nonGMOYN'] ?? false,\n renderPopoverContent: renderPopoverContent(\n 'Non-GMO',\n snapshotData?.['nonGMOYN'] ?? false,\n supplierModifiedData?.['nonGMOYN'] ?? false,\n null,\n 'checkbox'\n ),\n colProps: {\n xs: 8,\n },\n layout: 'horizontal',\n labelCol: {\n flex: '79px',\n },\n },\n {\n colProps: {\n xs: 16,\n },\n noStyle: true,\n shouldUpdate: () => true,\n renderInput:\n ({ allowEdit, inputProps }) =>\n ({ getFieldValue }) => {\n const enabled = getFieldValue('nonGMOYN');\n const seletecterCertifiers = getSelectedCertifiers({\n getFieldValue,\n });\n\n return (\n ({\n disabled: seletecterCertifiers?.includes(option.value),\n }),\n inputProps: {\n allowClear: true,\n showSearch: true,\n },\n }}\n snapshotData={snapshotData}\n supplierModifiedData={supplierModifiedData}\n isLoadingSnapshot={isLoading}\n />\n );\n },\n },\n ],\n [\n { rowConfig: { gutter: [15, 15], style: { marginBottom: 10 } } },\n {\n name: 'isoyn',\n label: 'ISO:',\n type: 'checkbox',\n layout: 'horizontal',\n valuePropName: 'checked',\n supplierModifiedData: supplierModifiedData?.['isoyn'] ?? false,\n snapshotData: snapshotData?.['isoyn'] ?? false,\n renderPopoverContent: renderPopoverContent(\n 'ISO',\n snapshotData?.['isoyn'] ?? false,\n supplierModifiedData?.['isoyn'] ?? false,\n null,\n 'checkbox'\n ),\n colProps: {\n xs: 8,\n },\n labelCol: {\n flex: '79px',\n },\n },\n {\n colProps: {\n xs: 16,\n },\n noStyle: true,\n shouldUpdate: () => true,\n renderInput:\n ({ allowEdit }) =>\n ({ getFieldValue }) => {\n const enabled = getFieldValue('isoyn');\n\n return (\n \n );\n },\n },\n ],\n [\n { rowConfig: { gutter: [15, 15], style: { marginBottom: 10 } } },\n {\n name: 'brcyn',\n label: 'BRC:',\n type: 'checkbox',\n layout: 'horizontal',\n valuePropName: 'checked',\n supplierModifiedData: supplierModifiedData?.['brcyn'] ?? false,\n snapshotData: snapshotData?.['brcyn'] ?? false,\n renderPopoverContent: renderPopoverContent(\n 'BRC',\n snapshotData?.['brcyn'] ?? false,\n supplierModifiedData?.['brcyn'] ?? false,\n null,\n 'checkbox'\n ),\n colProps: {\n xs: 8,\n },\n labelCol: {\n flex: '79px',\n },\n },\n {\n colProps: {\n xs: 16,\n },\n noStyle: true,\n shouldUpdate: () => true,\n renderInput:\n ({ allowEdit }) =>\n ({ getFieldValue }) => {\n const enabled = getFieldValue('brcyn');\n\n return (\n \n );\n },\n },\n ],\n [\n { rowConfig: { gutter: [15, 15], style: { marginBottom: 10 } } },\n {\n name: 'ifsyn',\n label: 'IFS:',\n type: 'checkbox',\n layout: 'horizontal',\n valuePropName: 'checked',\n supplierModifiedData: supplierModifiedData?.['ifsyn'] ?? false,\n snapshotData: snapshotData?.['ifsyn'] ?? false,\n renderPopoverContent: renderPopoverContent(\n 'IFS',\n snapshotData?.['ifsyn'] ?? false,\n supplierModifiedData?.['ifsyn'] ?? false,\n null,\n 'checkbox'\n ),\n colProps: {\n xs: 8,\n },\n labelCol: {\n flex: '79px',\n },\n },\n {\n colProps: {\n xs: 16,\n },\n noStyle: true,\n shouldUpdate: () => true,\n renderInput:\n ({ allowEdit }) =>\n ({ getFieldValue }) => {\n const enabled = getFieldValue('ifsyn');\n\n return (\n \n );\n },\n },\n ],\n ];\n\n const formRightFourthSectionDefine = [\n {\n name: 'otherCertifications',\n label: 'Other Certifications',\n type: 'textarea',\n inputProps: {\n autoSize: { minRows: 3, maxRows: 3 },\n maxLength: PACKAGING_LIMIT_CHARACTERS.otherCertifications,\n showCount: true,\n },\n supplierModifiedData:\n supplierModifiedData?.['otherCertifications'] ?? '',\n snapshotData: snapshotData?.['otherCertifications'] ?? '',\n renderPopoverContent: renderPopoverContent(\n 'Other Certifications',\n snapshotData?.['otherCertifications'] ?? '',\n supplierModifiedData?.['otherCertifications'] ?? ''\n ),\n },\n {\n name: 'hasFoodGradePlasticsCertifier',\n label: 'Contains Food Grade Plastics',\n type: 'select',\n selectProps: {\n options: packagingEnumOptions.hasFoodGradePlasticsCertifier,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['hasFoodGradePlasticsCertifier'],\n 'hasFoodGradePlasticsCertifier',\n enumType\n ),\n supplierModifiedData:\n supplierModifiedData?.['hasFoodGradePlasticsCertifier'],\n snapshotData: snapshotData?.['hasFoodGradePlasticsCertifier'],\n renderPopoverContent: renderPopoverContent(\n 'Contains Food Grade Plastics',\n snapshotData?.['hasFoodGradePlasticsCertifier'],\n supplierModifiedData?.['hasFoodGradePlasticsCertifier'],\n getFormattedValue(\n snapshotData?.['hasFoodGradePlasticsCertifier'],\n 'hasFoodGradePlasticsCertifier',\n enumType\n ),\n null\n ),\n },\n {\n name: 'recycledMaterial',\n label: 'Made With Recycled Material',\n type: 'select',\n selectProps: {\n options: packagingEnumOptions.recycledMaterial,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['recycledMaterial'],\n 'recycledMaterial',\n enumType\n ),\n supplierModifiedData: supplierModifiedData?.['recycledMaterial'],\n snapshotData: snapshotData?.['recycledMaterial'],\n renderPopoverContent: renderPopoverContent(\n 'Made With Recycled Material',\n snapshotData?.['recycledMaterial'],\n supplierModifiedData?.['recycledMaterial'],\n getFormattedValue(\n snapshotData?.['recycledMaterial'],\n 'recycledMaterial',\n enumType\n ),\n null\n ),\n },\n {\n name: 'soyInk',\n label: 'Soy Ink',\n type: 'select',\n selectProps: {\n options: packagingEnumOptions.soyInk,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['soyInk'],\n 'soyInk',\n enumType\n ),\n supplierModifiedData: supplierModifiedData?.['soyInk'],\n snapshotData: snapshotData?.['soyInk'],\n renderPopoverContent: renderPopoverContent(\n 'Soy Ink',\n snapshotData?.['soyInk'],\n supplierModifiedData?.['soyInk'],\n getFormattedValue(snapshotData?.['soyInk'], 'soyInk', enumType),\n null\n ),\n },\n {\n name: 'vegetableBasedInk',\n label: 'Vegetable Based Ink ',\n type: 'select',\n selectProps: {\n options: packagingEnumOptions.vegetableBasedInk,\n inputProps: {\n allowClear: true,\n },\n },\n formattedValue: getFormattedValue(\n snapshotData?.['vegetableBasedInk'],\n 'vegetableBasedInk',\n enumType\n ),\n supplierModifiedData: supplierModifiedData?.['vegetableBasedInk'],\n snapshotData: snapshotData?.['vegetableBasedInk'],\n renderPopoverContent: renderPopoverContent(\n 'Vegetable Based Ink',\n snapshotData?.['vegetableBasedInk'],\n supplierModifiedData?.['vegetableBasedInk'],\n getFormattedValue(\n snapshotData?.['vegetableBasedInk'],\n 'vegetableBasedInk',\n enumType\n )\n ),\n },\n ];\n\n return {\n formProductDefine,\n formProductClaimFirstSectionDefine,\n formRightSecondSection,\n formLeftBottomDefine,\n formDietaryThirdSectionDefine,\n formRightFourthSectionDefine,\n };\n }, [\n packagingEnumOptions,\n setUploadModalTitle,\n supplierModifiedData,\n snapshotData,\n enumType,\n getSecondaryLanguageFormatted,\n handleToggleUploadDocumentModal,\n isProductAssignedToSupplier,\n isLoading,\n ]);\n\n return qaPackagingFormDefine;\n};\n\nconst getSelectedCertifiers = ({ getFieldValue }) => {\n return [\n ...(getFieldValue('kosherCertifier') ?? []),\n ...(getFieldValue('organicCertifier') ?? []),\n ...(getFieldValue('halalCertifier') ?? []),\n ...(getFieldValue('nonGMOCertifier') ?? []),\n ];\n};\n\nconst getQueryKeyQaPackaging = (productId) => {\n return ['pim', 'snapshot', parseInt(productId), 'qa-packaging'];\n};\n\nexport const useGetSnapshotQaPackaging = ({\n enabled,\n productId,\n ...restProps\n}) => {\n const queryClient = useQueryClient();\n\n const getSnapshotQaPackagingData = async () => {\n const response = await getSnapshotQaSpecPackaging({ productId });\n const { isSuccess, data } = response;\n if (!isSuccess) return null;\n\n return parsePackagingData(data);\n };\n\n const query = useQuery({\n queryKey: getQueryKeyQaPackaging(productId),\n queryFn: getSnapshotQaPackagingData,\n enabled,\n ...restProps,\n });\n\n const invalidateSnapshotQaSpecPackaging = () => {\n queryClient.invalidateQueries({\n queryKey: getQueryKeyQaPackaging(productId),\n });\n };\n\n return { ...query, invalidateSnapshotQaSpecPackaging };\n};\n","import React, { useState, useEffect } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport { Row, Col, Typography } from 'antd';\n\nimport {\n StyledModal,\n SectionWrapper,\n BasicFormItemList,\n FullWidthSpace,\n WithLoading,\n Form,\n CustomNotification,\n} from 'common/components';\nimport AddAssetPimModal from 'pages/product-full-view/components/modal/add-asset-pim-modal';\n\nimport { useGetQaPackagingFormDefine } from 'pages/qa-spec/components/qa-packaging/hooks';\nimport {\n useGetQaPackagingTabData,\n useSaveQaPackagingTab,\n} from 'pages/qa-spec/components/qa-packaging/queries';\nimport { useCheckPermissionOR } from 'hooks/useCheckPermissions';\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\nimport {\n getCertificateParams,\n parsePackagingData,\n} from 'pages/qa-spec/components/qa-packaging/utils';\nimport useUpdateIXONEShield from 'common/components/product-add/useUpdateIXONEShield';\nimport {\n IXONECertificationWrapper,\n TYPE_VIEW,\n} from 'common/components/product-add/IXONECertificationWrapper';\nimport { useGetProductVersionList } from 'pages/product-history/hook';\n\nconst ProductPackagingModal = (props) => {\n const [formInst] = Form.useForm();\n const { productId, id } = useParams();\n const checkPermission = useCheckPermissionOR();\n const hasQaSpecPackingEditPermission = checkPermission([\n [ABILITY_ACTION.EDIT, ABILITY_SUBJECT.QA_SPECIFICATION],\n ]);\n\n const { visible, closeModal, isQASpecLocked, productFull } = props;\n\n const [uploadModalTitle, setUploadModalTitle] = useState('');\n const [uploadDocumentModalVisible, setUploadDocumentModalVisible] =\n useState(false);\n\n const checkEdit = hasQaSpecPackingEditPermission && !isQASpecLocked;\n\n const _productId = productId || id;\n\n const { handleUpdateIXONEShield } = useUpdateIXONEShield();\n\n const { data, isLoading: loading } = useGetQaPackagingTabData(\n { productId: _productId },\n { enabled: !!visible, retry: false }\n );\n\n const { handleRefetchProductVersioning } = useGetProductVersionList({\n enabled: false,\n });\n\n const {\n formProductDefine,\n formLeftBottomDefine,\n formProductClaimFirstSectionDefine,\n formRightSecondSection,\n formDietaryThirdSectionDefine,\n formRightFourthSectionDefine,\n } = useGetQaPackagingFormDefine({\n handleToggleUploadDocumentModal: () => {\n handleToggleUploadDocumentModal();\n },\n setUploadModalTitle,\n productFull,\n });\n const handleSaveQaPackagingTab = useSaveQaPackagingTab();\n const { isLoading: saveLoading } = handleSaveQaPackagingTab;\n\n const handleToggleUploadDocumentModal = () => {\n setUploadDocumentModalVisible((prev) => !prev);\n };\n\n const handleSave = async (ixoneIgnore) => {\n formInst\n .validateFields()\n .then(async (values) => {\n const certificateParams = getCertificateParams(values);\n\n const formData = { ...values, ...certificateParams };\n\n handleSaveQaPackagingTab.mutate(\n {\n productId: _productId,\n formData: formData,\n },\n {\n onSuccess: async () => {\n await handleUpdateIXONEShield(ixoneIgnore);\n handleRefetchProductVersioning();\n closeModal && closeModal();\n },\n }\n );\n })\n .catch((e) => {\n if (e?.errorFields?.length > 0) {\n CustomNotification.error('Please resolve errors.');\n }\n });\n };\n const onCancel = () => {\n const parsedData = parsePackagingData(data);\n formInst.setFieldsValue(parsedData);\n closeModal && closeModal();\n };\n\n const onFormChange = (changedValues, allValues) => {\n if (\n changedValues.hasOwnProperty('recyclable') &&\n (changedValues?.recyclable === 'No' || !changedValues?.recyclable)\n ) {\n formInst.setFieldsValue({ recyclableTypes: [] });\n }\n if (\n changedValues.hasOwnProperty('bilingual') &&\n (changedValues?.bilingual === 'No' || !changedValues?.bilingual)\n ) {\n formInst.setFieldsValue({ secondaryLanguage: [] });\n }\n };\n\n const parsedData = parsePackagingData(data);\n\n useEffect(() => {\n formInst.setFieldsValue(parsedData);\n }, [JSON.stringify(data)]);\n\n return (\n {\n handleSave(ixoneIgnore);\n }}\n showModal\n type={TYPE_VIEW.EDIT_PRODUCT}\n onCancel={onCancel}\n >\n {(handleConfirmIXONE) => (\n {\n handleConfirmIXONE({\n originalData: parsedData,\n changedFields: await formInst.validateFields(),\n });\n }}\n >\n \n
\n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n\n \n\n \n \n \n\n \n \n \n \n {uploadDocumentModalVisible && (\n \n )}\n \n
\n
\n \n )}\n \n );\n};\n\nconst labelFn = (labelText) => {\n return {labelText && labelText};\n};\n\nexport default ProductPackagingModal;\n","import React, { useState } from 'react';\n\nimport { LockOutlined } from '@ant-design/icons';\n\nimport { RibbonButton } from 'common/components';\nimport ProductPackagingModal from '../../modal/product-packaging/ProductPackagingModal';\n\nimport Messages from 'i18n/messages/home';\nimport { useCheckQaSpecLocked } from 'pages/qa-spec/hooks/useCheckQaSpecLocked';\n\nconst ProductPackaging = ({ productFull }) => {\n const [modalVisible, setModalVisible] = useState(false);\n\n const closeModal = () => {\n setModalVisible(false);\n };\n\n const onClick = () => {\n setModalVisible(true);\n };\n\n const { isQASpecLocked } = useCheckQaSpecLocked();\n\n return (\n <>\n \n ) : (\n \n )\n }\n label={Messages.productPackaging}\n onClick={onClick}\n />\n \n \n );\n};\n\nexport default ProductPackaging;\n","import React, { useEffect, useRef, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { useIntl } from 'react-intl';\n\nimport { useParams } from 'react-router-dom';\n\nimport { Form } from 'antd';\nimport { produce } from 'immer';\nimport _ from 'lodash';\n\nimport {\n CustomNotification,\n StyledModal,\n WithLoading,\n} from 'common/components';\nimport AddProductHierarchy from './AddProductHierarchy';\nimport HierarchyLevelList from './HierarchyLevelList';\n\nimport * as productActions from 'pages/product-full-view/controllers/actions';\nimport * as productSelectors from 'pages/product-full-view/controllers/selectors';\n\nimport { useGetProductFullView, useProductHierarchies } from 'hooks';\nimport * as utils from 'utils/productHierarchy';\n\nimport * as productServices from 'services/product';\n\nimport {\n INIT_ADDING_HIERARCHY_LEVELS as DEFAULT_INIT_ADDING_HIERARCHY_LEVELS,\n HIERARCHY_LEVEL,\n} from 'static/Constants';\n\nimport Messages from 'i18n/messages/product';\n\nimport './AddHierarchyModal.less';\n\nconst AddHierarchyModal = (props) => {\n const dispatch = useDispatch();\n const intl = useIntl();\n const hierarchyProductListRef = useRef([]);\n const [QttForm] = Form.useForm();\n\n const { visible, setVisible, selectedHierarchy, isEdit, isCopy, isAdd } =\n props;\n\n let { id: productId } = useParams();\n\n const [modalLoading, setModalLoading] = useState(false);\n const [selectedLevel, setSelectedLevel] = useState(null);\n const [selectedProduct, setSelectedProduct] = useState(null);\n\n const [hierarchyLevelList, setHierarchyLevelList] = useState(\n _.cloneDeep(DEFAULT_INIT_ADDING_HIERARCHY_LEVELS)\n );\n\n const { productFull: currentProduct } = useGetProductFullView({ productId });\n const currentHierarchyShortDetails = useSelector(\n productSelectors.makeSelectCurrentHierarchyShortDetails()\n );\n\n // const [hierarchyProductList, setHierarchyProductList] = useState([]);\n //* refactor hierarchyProductList from state to ref\n const hierarchyProductList = hierarchyProductListRef.current;\n const setHierarchyProductList = (newState) => {\n const data =\n typeof newState === 'function'\n ? newState(hierarchyProductList)\n : newState;\n\n hierarchyProductListRef.current = data;\n };\n\n const { saveHierarchiesMutation } = useProductHierarchies({\n productId: currentProduct?.productId,\n });\n\n const onCloseModal = () => {\n setVisible(false);\n };\n\n const onOkHandler = () => {\n if (selectedLevel) {\n selectProductForLevel();\n return;\n }\n\n callApi();\n };\n\n const selectProductForLevel = () => {\n if (!selectedLevel) return;\n appendSelectedProductToProductList();\n\n setHierarchyLevelList((prevState) => {\n const cloneState = _.cloneDeep(prevState);\n //* set product to level\n\n _.set(\n cloneState,\n `[${selectedLevel.index}].productItemId`,\n selectedProduct?.id\n );\n\n utils.setParentProductForThisLevel({\n levelList: cloneState,\n level: selectedLevel,\n addedProductId: selectedProduct?.id,\n });\n\n utils.setParentProductForChildrenLevel({\n levelList: cloneState,\n productList: hierarchyProductList,\n level: selectedLevel,\n addedProductId: selectedProduct?.id,\n });\n\n updateQuantityForm({ levelList: cloneState });\n\n return cloneState;\n });\n\n goBackToSelectLevelView();\n };\n\n const appendSelectedProductToProductList = () => {\n if (!selectedProduct) return;\n setHierarchyProductList((prevState) => {\n const productItem = _.cloneDeep(selectedProduct);\n\n _.set(productItem, 'productItemId', productItem.id);\n\n const newState = [...prevState, productItem];\n\n return newState;\n });\n };\n\n const updateQuantityForm = ({ levelList }) => {\n const hightestLevel = utils.getHighestLevel(levelList);\n const isHighestLevel = selectedLevel.packageLevel === hightestLevel;\n\n QttForm.setFieldsValue({\n [selectedLevel.index]: isHighestLevel ? 1 : null,\n });\n };\n\n const getApiParams = async () => {\n try {\n const quantities = await QttForm.validateFields();\n\n const clonedHierarchyLevelList = _.cloneDeep(hierarchyLevelList);\n const levelHasProductList = clonedHierarchyLevelList.filter((level) => {\n return level.productItemId;\n });\n\n const itemsParam = levelHasProductList.map((level) => {\n const { productItemId, parentProductItemId, packageLevel } = level;\n return {\n productItemId,\n parentProductItemId,\n packageLevel,\n quantity: quantities[level.index],\n };\n });\n\n return {\n hierarchyId: isEdit ? selectedHierarchy?.productHierarchyId : undefined,\n ownerId: currentProduct?.ownerId,\n items: itemsParam,\n };\n } catch (error) {\n console.log('error: ', error);\n return;\n }\n };\n\n const getApiMessages = () => {\n return {\n success: intl.formatMessage(\n Messages[\n isAdd\n ? 'addHierarchySuccess'\n : isEdit\n ? 'editHierarchySuccess'\n : 'copyHierarchySuccess'\n ]\n ),\n error: intl.formatMessage(\n Messages[\n isAdd\n ? 'addHierarchyError'\n : isEdit\n ? 'editHierarchyError'\n : 'copyHierarchyError'\n ]\n ),\n };\n };\n\n const callApi = async () => {\n const params = await getApiParams();\n const messages = getApiMessages();\n\n saveHierarchiesMutation.mutate(params, {\n onSuccess: (response) => {\n if (!response.isSuccess) {\n CustomNotification.error(response.message || messages.error);\n return;\n }\n\n setVisible(false);\n\n CustomNotification.success(messages.success);\n\n dispatch(productActions.updateSelectedHierarchy(null));\n dispatch(productActions.updateHierarchyEndpoint(null));\n\n //* reload hierarchies in drawer\n dispatch(\n productActions.getProductHierarchyShortDetails({\n hierarchyId: currentHierarchyShortDetails?.data?.hierarchyId,\n })\n );\n //* reload hierarchy dropdown in product header\n dispatch(\n productActions.getProductHierarchyShortDetail(\n currentProduct?.productId\n )\n );\n },\n onError: () => {\n CustomNotification.error(messages.error);\n },\n });\n };\n\n const goBackToSelectLevelView = () => {\n setSelectedLevel(null);\n setSelectedProduct(null);\n };\n\n const clearState = () => {\n setHierarchyProductList([]);\n setHierarchyLevelList(_.cloneDeep(DEFAULT_INIT_ADDING_HIERARCHY_LEVELS));\n setSelectedLevel(null);\n setSelectedProduct(null);\n QttForm.resetFields();\n };\n\n const updateHierarchyLevelListWithEqualLevel = (levelKey, levelPackage) => {\n setHierarchyLevelList((prevState) => {\n const newState = produce(prevState, (draft) => {\n const equalWithIndex = draft.findIndex((levelItem) =>\n levelItem?.equalWith?.includes(levelKey)\n );\n\n draft[equalWithIndex].key = levelKey;\n draft[equalWithIndex].packageLevel = levelPackage;\n });\n\n return newState;\n });\n };\n\n const setCurrentProductToHierarchyLevelList = (level) => {\n setHierarchyLevelList((prevState) => {\n const newState = produce(prevState, (draft) => {\n const index = draft.findIndex((levelItem) => levelItem.key === level);\n\n draft[index].productItemId = currentProduct?.productId;\n\n //* set parentProductId for first lower level\n if (index < 4)\n draft[index + 1].parentProductItemId = currentProduct?.productId;\n });\n\n return newState;\n });\n };\n\n const addCurrentProductToHierarchyProductList = () => {\n const productItem = {\n productItemId: currentProduct.productId,\n productName: currentProduct.productName,\n thumbnail: currentProduct.productPrimaryImage,\n packageLevel: currentProduct.packageLevel,\n };\n\n setHierarchyProductList((prevState) => {\n prevState.push(productItem);\n\n return prevState;\n });\n };\n\n const initCurrentProduct = () => {\n if (!visible) return;\n if (isEdit || isCopy) return;\n\n if (!currentProduct) return;\n\n const currentProductLevel = currentProduct.packageLevel;\n const level = Object.values(HIERARCHY_LEVEL).find(\n (LEVEL) => LEVEL.NAME === currentProductLevel\n )?.KEY;\n\n const levelIndex = hierarchyLevelList.findIndex(\n (levelItem) => levelItem.key === level\n );\n\n if (levelIndex === -1) {\n //* levelIndex === -1 when level is not exist in INIT_ADDING_HIERARCHY_LEVELS (such as Display Shipper, ...)\n //* replace equal level with this level\n updateHierarchyLevelListWithEqualLevel(level, currentProductLevel);\n }\n\n addCurrentProductToHierarchyProductList();\n setCurrentProductToHierarchyLevelList(level);\n };\n\n const initHierarchyData = async () => {\n if (isAdd) return;\n if (!selectedHierarchy) return;\n if (!visible) return;\n\n setModalLoading(true);\n const params = {\n hierarchyId: selectedHierarchy.productHierarchyId,\n };\n\n const { isSuccess, data } =\n await productServices.getProductHierarchyDetailsService(params);\n\n let productList;\n\n if (isSuccess && data?.productItems?.length)\n productList = data?.productItems.map((productItem) => {\n const { productId, ...rest } = productItem;\n return {\n productItemId: productId,\n ...rest,\n };\n });\n else productList = selectedHierarchy.productItemLinks;\n\n //* INIT HIERARCHY DATA FROM PRODUCT LIST\n //* offsetLevels is missing levels on top\n const offsetLevels = utils.getOffsetLevels(productList);\n\n //* map product list to hierarchy level\n const initLevelList = utils.getInitLevelList(productList);\n\n //* sort initLevelList to the right order\n const sortedLevelList = utils.sortLevelList(initLevelList);\n\n //* add missing hierarchy to middle and bottom of initLevelList\n const filledLevelList = utils.fillLevelList(sortedLevelList);\n\n //* concat with offset levels to get completed list\n const completeInitLevelList = [...offsetLevels, ...filledLevelList];\n\n const reIndexInitLevelList = utils.reIndexLevelList(completeInitLevelList);\n\n initHierarchyProductList(productList);\n initHierarchyLevelList({ levelList: reIndexInitLevelList });\n initQuantityForm({ levelList: reIndexInitLevelList });\n\n setModalLoading(false);\n };\n\n const initHierarchyLevelList = ({ levelList }) => {\n setHierarchyLevelList(levelList);\n };\n\n const initHierarchyProductList = (productList) => {\n if (!productList) return;\n\n const initProductList = utils.getInitialProductList({\n productList,\n currentProduct,\n });\n\n setHierarchyProductList(initProductList);\n };\n\n const initQuantityForm = ({ levelList }) => {\n const initialQuantityForm = utils.getInitialQuantity({ levelList });\n\n QttForm.setFieldsValue(initialQuantityForm);\n };\n\n const checkHighestLevelProduct = () => {\n const highestLevelProduct = utils.getHighestLevelProduct({\n levelList: hierarchyLevelList,\n });\n\n const currentHighestLevelProduct =\n utils.getSelectedHierarchyHighestLevelProduct({\n levelList: hierarchyLevelList,\n selectedHierarchy,\n });\n\n return highestLevelProduct === currentHighestLevelProduct;\n };\n\n const updateSubmitBtnDisabled = () => {\n if (!isCopy) return false;\n if (!selectedHierarchy) return false;\n\n if (selectedLevel) return false;\n\n let disabled = checkHighestLevelProduct();\n\n return disabled;\n };\n\n //* mount update\n useEffect(() => {\n clearState();\n initHierarchyData();\n initCurrentProduct();\n //eslint-disable-next-line\n }, [visible]);\n\n const submitDisabled = updateSubmitBtnDisabled();\n\n //* render\n const modalTitle = intl.formatMessage(\n Messages[\n isEdit\n ? 'editHierarchyTitle'\n : isCopy\n ? 'copyHierarchyTitle'\n : 'addHierarchyTitle'\n ]\n );\n const okText = intl.formatMessage(\n Messages[\n selectedLevel\n ? 'selectProductHierarchy'\n : isEdit || isCopy\n ? 'editHierarchy'\n : 'addHierarchy'\n ]\n );\n\n const modalProps = {\n title: modalTitle,\n visible,\n onCancel: onCloseModal,\n wrapClassName: 'add-hierarchy__modal',\n bodyStyle: {\n height: selectedLevel ? 405 : 300,\n position: 'relative',\n },\n width: 700,\n destroyOnClose: true,\n closeable: false,\n okText,\n onOk: onOkHandler,\n okButtonProps: {\n loading: saveHierarchiesMutation?.isLoading,\n disabled: submitDisabled,\n },\n };\n\n const addProductHierarchyProps = {\n closeModal: onCloseModal,\n goBackToSelectLevelView,\n selectedLevel,\n selectedProduct,\n setSelectedProduct,\n productId,\n };\n\n const hierarchyLevelListProps = {\n isCopy,\n form: QttForm,\n currentProduct,\n hierarchyLevelList,\n hierarchyProductList,\n selectedHierarchy,\n closeModal: onCloseModal,\n goBackToSelectLevelView,\n setHierarchyLevelList,\n setHierarchyProductList,\n setSelectedLevel,\n checkHighestLevelProduct,\n initQuantityForm,\n };\n\n return (\n \n {modalLoading ? (\n \n ) : selectedLevel ? (\n \n ) : (\n \n )}\n \n );\n};\n\nexport default AddHierarchyModal;\n","import React, { useState } from 'react';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport { FileAddOutlined } from '@ant-design/icons';\n\nimport AddHierarchyModal from '../../modal/product-hierarchy/AddHierarchyModal';\n\nimport Messages from 'i18n/messages/home';\n\nconst AddHierarchy = (props) => {\n const { sectionDisabled } = props;\n\n const [visible, setVisible] = useState(false);\n\n const onClickHandler = () => {\n setVisible(true);\n };\n\n const isDisabled = sectionDisabled;\n\n return (\n <>\n }\n label={Messages.addHierarchy}\n onClick={onClickHandler}\n disabled={isDisabled}\n />\n \n \n );\n};\n\nexport default AddHierarchy;\n","import React, { useState } from 'react';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport { EditOutlined } from '@ant-design/icons';\n\nimport AddHierarchyModal from '../../modal/product-hierarchy/AddHierarchyModal';\n\nimport Messages from 'i18n/messages/home';\n\nconst EditHierarchy = (props) => {\n const { selectedHierarchy, sectionDisabled } = props;\n\n const [visible, setVisible] = useState(false);\n\n const onClickHandler = () => {\n setVisible(true);\n };\n\n const isDisabled = !selectedHierarchy || sectionDisabled;\n\n return (\n <>\n }\n label={Messages.editHierarchy}\n onClick={onClickHandler}\n disabled={isDisabled}\n />\n \n \n );\n};\n\nexport default EditHierarchy;\n","import React, { useState } from 'react';\n\nimport { CopyOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport AddHierarchyModal from '../../modal/product-hierarchy/AddHierarchyModal';\n\nimport Messages from 'i18n/messages/home';\n\nconst CopyHierarchy = (props) => {\n const { selectedHierarchy, sectionDisabled } = props;\n\n const [visible, setVisible] = useState(false);\n\n const onClickHandler = () => {\n setVisible(true);\n };\n\n const isDisabled = !selectedHierarchy || sectionDisabled;\n\n return (\n <>\n }\n label={Messages.copyHierarchy}\n onClick={onClickHandler}\n disabled={isDisabled}\n />\n \n \n );\n};\n\nexport default CopyHierarchy;\n","import React from 'react';\n\nimport { useParams } from 'react-router-dom';\n\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { DeleteOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport { dialogFunction, CustomNotification } from 'common/components';\n\nimport * as productActions from 'pages/product-full-view/controllers/actions';\nimport * as productSelectors from 'pages/product-full-view/controllers/selectors';\n\nimport { useProductHierarchies, useProductFullView } from 'hooks';\n\nimport Messages from 'i18n/messages/home';\nimport { useIntl } from 'react-intl';\n\nconst DeleteHierarchy = (props) => {\n const intl = useIntl();\n const dispatch = useDispatch();\n\n const { id: productId } = useParams();\n\n const { selectedHierarchy, sectionDisabled } = props;\n\n const currentHierarchyShortDetails = useSelector(\n productSelectors.makeSelectCurrentHierarchyShortDetails()\n );\n\n const { productFull } = useProductFullView({ productId });\n const { deleteHierarchiesMutation } = useProductHierarchies({\n productId: productFull?.productId,\n });\n\n const loading = deleteHierarchiesMutation.isLoading;\n\n const showDeleteConfirmDialog = () => {\n dialogFunction({\n type: 'warn',\n okButtonProps: {\n loading: loading,\n },\n content: intl.formatMessage(Messages.deleteHierarchyMessage),\n onOk: callApiDeleteHierarchy,\n });\n };\n\n const callApiDeleteHierarchy = () => {\n const successMessage = intl.formatMessage(Messages.deleteHierarchySuccess);\n const errorMessage = intl.formatMessage(Messages.deleteHierarchyError);\n\n const params = {\n hierarchyId: selectedHierarchy?.productHierarchyId,\n };\n\n deleteHierarchiesMutation.mutate(params, {\n onSuccess: ({ isSuccess }) => {\n if (!isSuccess) CustomNotification.error(errorMessage);\n\n CustomNotification.success(successMessage);\n dispatch(productActions.updateSelectedHierarchy(null));\n dispatch(productActions.updateHierarchyEndpoint(null));\n //* reload hierarchies in drawer\n dispatch(\n productActions.getProductHierarchyShortDetails({\n hierarchyId: currentHierarchyShortDetails?.data?.hierarchyId,\n })\n );\n\n //* reload hierarchy dropdown in product header\n dispatch(\n productActions.getProductHierarchyShortDetail(productFull?.productId)\n );\n },\n onError: () => {\n CustomNotification.error(errorMessage);\n },\n });\n };\n\n const onClickHandler = () => {\n showDeleteConfirmDialog();\n };\n\n const isDisabled = !selectedHierarchy || sectionDisabled;\n\n return (\n <>\n }\n label={Messages.deleteHierarchy}\n onClick={onClickHandler}\n disabled={isDisabled}\n />\n \n );\n};\n\nexport default DeleteHierarchy;\n","import React from 'react';\n\nimport { useLocation } from 'react-router-dom';\n\nimport { useSelector } from 'react-redux';\n\nimport { Dropdown, Menu } from 'antd';\nimport { ClusterOutlined } from '@ant-design/icons';\n\nimport { RibbonButton } from 'common/components';\n\nimport AddHierarchy from '../../controls/product-full/AddHierarchy';\nimport EditHierarchy from '../../controls/product-full/EditHierarchy';\nimport CopyHierarchy from '../../controls/product-full/CopyHierarchy';\nimport DeleteHierarchy from '../../controls/product-full/DeleteHierarchy';\n\nimport { PRODUCT_VIEW } from 'static/Constants';\n\nimport messages from 'i18n/messages/home';\n\nimport * as productDetailSelectors from 'pages/product-full-view/controllers/selectors';\n\nimport {\n useCheckAllowEditProducts,\n useGetProductFullView,\n usePermissionEditProduct,\n} from 'hooks';\n\nimport './HierarchyActions.less';\n\nconst HierarchyActions = ({ productId }) => {\n const location = useLocation();\n\n const { productFull } = useGetProductFullView({ productId });\n\n const { checkAllowEditProductFull } = useCheckAllowEditProducts();\n\n const hasPermissionEditProduct = usePermissionEditProduct();\n\n const isAllowEditProduct = checkAllowEditProductFull(productFull);\n\n const isShowHierarchySections = hasPermissionEditProduct;\n\n const selectedHierarchy = useSelector(\n productDetailSelectors.makeSelectSelectedHierarchy()\n );\n\n const sectionDisabled = !isAllowEditProduct;\n\n const getActiveContent = () => {\n const regex = /\\/(?:product)\\/(.+)(?=\\/\\d+$)/;\n\n const results = location?.pathname?.match(regex);\n\n return results?.length ? results[1] : validateOverview();\n };\n\n const validateOverview = () => {\n const regex = /\\/product\\/\\d+$/;\n const isOverview = regex.test(location.pathname);\n return isOverview ? PRODUCT_VIEW.OVERVIEW : null;\n };\n\n const activeContent = getActiveContent();\n\n const isHierarchyContent = activeContent === PRODUCT_VIEW.HIERARCHY;\n\n const hierarchyEditable =\n isHierarchyContent && !productFull?.gdsnShield && isAllowEditProduct;\n\n const renderHierarchyActions = (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n\n return (\n <>\n {isShowHierarchySections && hierarchyEditable && (\n \n }\n label={messages.productHierarchyActions}\n />\n \n )}\n \n );\n};\n\nexport default HierarchyActions;\n","import React from 'react';\nimport { CopyOutlined } from '@ant-design/icons';\nimport messages from 'i18n/messages/home';\nimport { RibbonButton } from 'common/components';\nimport { useGlobalModal } from 'hooks';\n\nfunction ProductClone({ isDisabled }) {\n const { openModal, MODAL_NAMES } = useGlobalModal();\n\n return (\n <>\n }\n label={messages.productClone}\n onClick={() => openModal(MODAL_NAMES.COPY_PRODUCT_MODAL)}\n disabled={isDisabled}\n className='button-item-dropdown'\n />\n \n );\n}\n\nexport default ProductClone;\n","import React from 'react';\nimport { useHistory } from 'react-router-dom';\nimport { HistoryOutlined } from '@ant-design/icons';\nimport Messages from 'i18n/messages/home';\nimport useToggleActiveRibbon from './hook';\nimport { forwardTo } from 'utils/common/route';\nimport { RibbonButton } from 'common/components';\n\nconst SyndicationHistorySection = (props) => {\n const { disabled, productFull } = props;\n\n const history = useHistory();\n\n const checkActiveContent = () => {\n const path = history?.location?.pathname;\n const regex = /\\/product\\/\\d+\\/mapping$/;\n\n return regex.test(path);\n };\n\n const isPathActive = checkActiveContent();\n const isActive = useToggleActiveRibbon(isPathActive);\n\n const handleClickToSyndicationHistory = () => {\n forwardTo(`/product/syndication-history/${productFull?.productId}`);\n };\n\n return (\n }\n label={Messages.syndicationHistory}\n onClick={handleClickToSyndicationHistory}\n disabled={disabled}\n toggle={isActive}\n className='button-item-dropdown'\n />\n );\n};\n\nexport default SyndicationHistorySection;\n","import React, { useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { SyncOutlined } from '@ant-design/icons';\nimport { RibbonButton, CustomNotification } from 'common/components';\n\nimport * as productFullViewActions from 'pages/product-full-view/controllers/actions';\nimport * as productFullViewSelectors from 'pages/product-full-view/controllers/selectors';\n\nimport * as mappingServices from 'services/mapping';\n\nimport { sleep } from 'utils/delay';\nimport { useHandleReloadPage } from 'hooks/useReloadPage';\n\nconst MappingInitSyncSection = () => {\n const dispatch = useDispatch();\n\n const [loading, setLoading] = useState(false);\n\n const [__, setReloadPage] = useHandleReloadPage();\n\n const selectedMappingSupportMem = useSelector(\n productFullViewSelectors.makeSelectSelectedMappingSupportMem()\n );\n\n const mappingMetaInfo = useSelector(\n productFullViewSelectors.makeSelectMappingMetadata()\n );\n\n const productHierarchyInfo = useSelector(\n productFullViewSelectors.makeSelectCurrentHierarchy()\n );\n\n const mappingId = mappingMetaInfo?.data?.mappingId;\n const hierarchyId = productHierarchyInfo?.productHierarchyId;\n\n const handleClick = async () => {\n if (selectedMappingSupportMem.length === 0) {\n return;\n }\n\n try {\n setLoading(true);\n\n const respone = await mappingServices.initProductMapping({\n hierarchyId,\n mappingIds: [mappingId],\n memberIds: selectedMappingSupportMem,\n });\n\n setLoading(false);\n const { isSuccess } = respone;\n\n if (isSuccess) {\n CustomNotification.success('Successfully init product mapping');\n const params = {\n mappingId,\n hierarchyId,\n };\n\n await sleep(2000);\n dispatch(productFullViewActions.getMappingMetadata(params));\n dispatch(productFullViewActions.reloadMappingSupportMemGrid());\n setReloadPage();\n }\n } catch (e) {\n setLoading(false);\n CustomNotification.error('Fail to init product mapping!');\n }\n };\n\n return (\n }\n label='Init mapping'\n onClick={handleClick}\n loading={loading}\n disabled={selectedMappingSupportMem?.length <= 0 || !hierarchyId}\n className='button-item-dropdown'\n />\n );\n};\n\nexport default MappingInitSyncSection;\n","import React, { useState } from 'react';\n\nimport { useSelector } from 'react-redux';\n\nimport { useLocation } from 'react-router-dom';\n\nimport { Dropdown, Menu, Divider } from 'antd';\nimport {\n SubnodeOutlined,\n DownloadOutlined,\n EditOutlined,\n} from '@ant-design/icons';\n\nimport { PRODUCT_VIEW } from 'static/Constants';\n\nimport { RibbonButton, DownloadFormItem } from 'common/components';\nimport DownloadNifFormSection from 'pages/home/ribbon/components/sections/product/DownloadNifFormSection';\nimport AssignCategoryToProduct from 'pages/home/ribbon/components/sections/product/AssignCategoryToProduct';\n\nimport ProductClone from './ProductClone';\nimport SyndicationSectionHistory from './SyndicationHistorySection';\nimport MappingInitSyncSection from './MappingInitSyncSection';\nimport ProductSheets from './ProductSheets';\nimport BulkEditProduct from '../product/BulkEditProduct';\n\nimport HistoryEntity from 'pages/home/ribbon/form-manange/components/form-history-grid/HistoryEntity';\n\nimport GDSNPublication from 'common/components/product-publication-setup/GDSNPublication';\nimport PostToWalmart from 'common/components/product-publication-setup/PostToWalmart';\nimport CreateProductViaFormModal from 'common/components/product-add/CreateProductViaFormModal';\n\nimport WithdrawPublicationButton from '../product/WithdrawPublicationButton';\n\nimport { CanShow } from 'common/components/wrapper/show-condition';\n\nimport { useCheckPermissionAnd } from 'hooks/useCheckPermissions';\nimport {\n useCheckIsSuperAdmin,\n useCheckAllowEditProducts,\n usePermissionEditSharedProduct,\n useCheckMemberSupplier,\n useCheckIsSuperMember,\n useGlobalModal,\n} from 'hooks';\nimport { useCheckPermissions } from 'hooks/useCheckPermissions';\nimport { SECURE_CONFIG } from 'utils/SecureRoute';\nimport {\n ABILITY_ACTION,\n ABILITY_SUBJECT,\n PERMISSION_EDIT_PRODUCTS,\n PERMISSION_VIEW_NEW_ITEM_FORMS,\n} from 'static/Permission';\n\nimport { Can } from 'context/Can';\n\nimport messages from 'i18n/messages/home';\nimport messagesProduct from 'i18n/messages/product';\n\nimport * as ssoProductSelectors from 'pages/sso-product/controllers/selectors';\n\nimport { useCheckDisableWithdrawPublicationModal } from 'hooks';\n// import IXOneSection from '../../sections/product/IXOneSection';\n// import useCheckIXOneCapture from 'hooks/useCheckIXOneCapture';\n// import MakeProductActive from '../../sections/product/MakeProductActive';\nimport AssignCategoryToProductModal from '../product/AssignCategoryToProductModal';\nimport CopyProductPropertiesModal from '../../modal/bulk-edit-product/CopyProductPropertiesModal';\nimport ImportProductBulkEditModal from '../../modal/bulk-edit-product/ImportProductBulkEditModal';\nimport ExportProductPropertiesModal from '../../modal/bulk-edit-product/ExportProductPropertiesModal';\nimport PublicationSetupModal from 'common/components/product-publication-setup/PublicationSetupModal';\nimport PublicationValidationView from 'pages/branded-products/components/publication-validation-view/PublicationValidationView';\n\nconst sectionAfterProductSlashIdRegex = /[^\\/product\\/(0-9)][a-z]*/g;\n\nconst { SubMenu } = Menu;\n\nconst ProductFullAction = ({ productFull, productId }) => {\n const location = useLocation();\n\n const [requestParams, setRequestParams] = useState(null);\n\n const { checkModalVisible, MODAL_NAMES, openModal, closeModal } =\n useGlobalModal();\n\n const isAssignCategoryModalOpen = checkModalVisible(\n MODAL_NAMES.ASSIGN_CATEGORY_TO_PRODUCT\n );\n const isAddEditModalOpen = checkModalVisible(\n MODAL_NAMES.ADD_EDIT_PRODUCT_MODAL\n );\n const isCopyProductModalOpen = checkModalVisible(\n MODAL_NAMES.COPY_PRODUCT_MODAL\n );\n const isExportProductPropertyModalOpen = checkModalVisible(\n MODAL_NAMES.EXPORT_PROPERTY_MODAL\n );\n const isImportProductPropertyModalOpen = checkModalVisible(\n MODAL_NAMES.IMPORT_PROPERTY_MODAL\n );\n const isPublicationSetupModalOpen = checkModalVisible(\n MODAL_NAMES.PUBLICATION_SETUP_MODAL\n );\n\n const isPublicationValidateViewModalOpen = checkModalVisible(\n MODAL_NAMES.PUBLICATION_VALIDATE_VIEW_MODAL\n );\n\n const isBpSsoProductValidate = useSelector(\n ssoProductSelectors.selectIsBpSsoProductValidate()\n );\n\n const { checkAllowEditProductFull } = useCheckAllowEditProducts();\n const isValidPermissionAND = useCheckPermissionAnd();\n\n const activeSectionAfterProductId = location.pathname.match(\n sectionAfterProductSlashIdRegex\n )?.[0];\n\n const validateOverview = () => {\n const regex = /\\/product\\/\\d+$/;\n const isOverview = regex.test(location.pathname);\n return isOverview ? PRODUCT_VIEW.OVERVIEW : null;\n };\n\n const getActiveContent = () => {\n const regex = /\\/(?:product)\\/(.+)(?=\\/\\d+$)/;\n\n const results = location?.pathname?.match(regex);\n\n return results?.length\n ? results[1]\n : isBpSsoProductValidate\n ? PRODUCT_VIEW.OVERVIEW\n : validateOverview();\n };\n\n const activeContent = getActiveContent();\n\n const isActiveView = [\n PRODUCT_VIEW.DETAILVIEW,\n PRODUCT_VIEW.OVERVIEW,\n PRODUCT_VIEW.QA_SPEC,\n PRODUCT_VIEW.QA_EVALUATION_FORM,\n PRODUCT_VIEW.VERSIONS,\n ].includes(activeContent);\n\n const isAllowEditProduct = checkAllowEditProductFull(productFull);\n\n const allowSeeProductSyndication = isValidPermissionAND([\n SECURE_CONFIG.ACCESS_SYNDICATION.PASS,\n SECURE_CONFIG.ACCESS_GDSN.PASS,\n SECURE_CONFIG.PRODUCT.PASS,\n ]);\n\n const hasPermissionEditProducts = useCheckPermissions(\n PERMISSION_EDIT_PRODUCTS\n );\n\n const hasPermissionEditSharedProduct = usePermissionEditSharedProduct();\n const isSuperAdmin = useCheckIsSuperAdmin();\n const isMemberSupplierUser = useCheckMemberSupplier();\n const isSuperMember = useCheckIsSuperMember();\n\n const isAllowActionsPim =\n isSuperAdmin || hasPermissionEditProducts || hasPermissionEditSharedProduct;\n\n const isAllowToDownloadNifForm = useCheckPermissions(\n PERMISSION_VIEW_NEW_ITEM_FORMS\n );\n\n const isDisableWithdrawPublicationModal =\n useCheckDisableWithdrawPublicationModal(productFull);\n\n const handleCancel = () => {\n closeModal(MODAL_NAMES.PUBLICATION_SETUP_MODAL);\n setRequestParams([]);\n };\n\n const handleOk = (values) => {\n setRequestParams(values);\n openModal(MODAL_NAMES.PUBLICATION_VALIDATE_VIEW_MODAL);\n };\n\n const disabledDropdown =\n !isActiveView &&\n !isSuperAdmin &&\n !isSuperMember &&\n isMemberSupplierUser &&\n !isAllowActionsPim;\n\n // const isShowIXOneCapture = useCheckIXOneCapture();\n\n const menuOptions = (\n \n {/* {isShowIXOneCapture ? (\n <>\n \n \n \n \n \n ) : null} */}\n\n {/* \n \n */}\n\n {isActiveView && (\n <>\n \n }\n label={messages.productEdit}\n onClick={() => openModal(MODAL_NAMES.ADD_EDIT_PRODUCT_MODAL)}\n disabled={!isAllowEditProduct}\n className='button-item-dropdown'\n />\n \n \n \n \n \n )}\n\n \n \n \n \n\n {[PRODUCT_VIEW.SYNDICATION].includes(activeSectionAfterProductId) && (\n \n \n \n )}\n\n \n \n \n \n \n \n \n \n\n {isSuperAdmin && (\n \n \n \n )}\n\n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n }\n disabled={!isAllowActionsPim}\n label={messagesProduct.bulkEditProduct}\n />\n }\n >\n \n \n \n \n \n \n \n {/* \n \n */}\n \n );\n\n return (\n <>\n \n }\n label={messages.productActions}\n />\n \n\n {isAddEditModalOpen && (\n \n )}\n {isAssignCategoryModalOpen && (\n \n )}\n {isCopyProductModalOpen && (\n \n )}\n {isExportProductPropertyModalOpen && (\n \n )}\n {isImportProductPropertyModalOpen && (\n \n )}\n {isPublicationSetupModalOpen && (\n \n )}\n\n {isPublicationValidateViewModalOpen && (\n \n )}\n \n );\n};\n\nexport default ProductFullAction;\n","import React, { useEffect } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\n\nimport { ViewLayout, AdvanceStack, OtherLayout } from './components';\nimport { RibbonBar, RibbonDivider } from 'common/components';\nimport ManageSharingSection from './components/sections/shared/ManageSharingSection';\nimport DetailSection from './components/sections/home-grid/DetailSection';\nimport ProductHierarchy from './components/controls/product-full/ProductHierarchy';\nimport Subscription from './components/controls/product-full/Subscription';\nimport HistorySection from './components/sections/product/HistorySection';\nimport ProductDetailView from './components/controls/product-full/ProductDetailView';\nimport ActionsRibbonBar from 'common/components/contact-action/ActionsRibbonBar';\n// import QASpecAssignSupplier from './components/controls/product-full/QASpecAssignSupplier';\n// import QaEvaluationForm from './components/controls/product-full/QaEvaluationForm';\nimport ProductPackaging from './components/controls/product-full/ProductPackaging';\n\nimport HierarchyActions from './components/controls/product-full/HierarchyActions';\nimport ProductFullAction from './components/controls/product-full/ProductFullAction';\nimport * as actionsGlobal from '@redux/global/actions';\n\nimport { useCheckAllowEditProducts, useGetProductFullView } from 'hooks';\nimport { useOpenReportingResult } from 'hooks/useOpenReportingResult';\nimport { useCheckPermissionOR } from 'hooks/useCheckPermissions';\nimport { useFolderByLevel } from 'hooks/useFolderByLevel';\n// import { useInitialWorkflowQaSpec } from 'hooks/useInitialWorkflowQaSpec';\nimport useCheckIXOneCapture from 'hooks/useCheckIXOneCapture';\n\nconst ProductFullViewRibbon = ({\n qaEvaluationFormId,\n isFetchingEvaluationForm,\n isHaveAddOpenItem = true,\n productId,\n shouldShowPackaging = true,\n}) => {\n const dispatch = useDispatch();\n const { keepSetting, keepResultGridPagination } = useOpenReportingResult();\n const checkPermission = useCheckPermissionOR();\n\n const isShowIXOneCapture = useCheckIXOneCapture();\n\n const hasQaSpecPermission = checkPermission([\n [ABILITY_ACTION.VIEW, ABILITY_SUBJECT.QA_SPECIFICATION],\n ]);\n\n const hasQaSpecPackingPermission = checkPermission([\n [ABILITY_ACTION.VIEW, ABILITY_SUBJECT.QA_SPECIFICATION],\n [ABILITY_ACTION.EDIT, ABILITY_SUBJECT.QA_SPECIFICATION],\n ]);\n\n // const hasEvaluationFormPermission = checkPermission([\n // [ABILITY_ACTION.VIEW, ABILITY_SUBJECT.EVALUATION_FORM],\n // ]);\n\n const { productFull } = useGetProductFullView({ productId });\n\n const { checkAllowEditProductFull } = useCheckAllowEditProducts();\n const { shouldKeepFolderBreadcrumb, keepFolderBreadcrumb } =\n useFolderByLevel();\n\n const closeDetailCallback = () => {\n keepSetting();\n keepResultGridPagination();\n\n //* keep folder breadcrumb when close folder item detail\n shouldKeepFolderBreadcrumb && keepFolderBreadcrumb(true);\n };\n\n //* Reset not go back to members route.\n //* In case user go form member full view -> company's product.\n useEffect(() => {\n dispatch(actionsGlobal.resetProdAssetsToMember());\n }, [dispatch]);\n\n // const { checkInitialWorkflowQaSpecRibbon } = useInitialWorkflowQaSpec();\n // const isInitialWorkflowQaSpecRibbon = checkInitialWorkflowQaSpecRibbon();\n const isAllowEditProduct = checkAllowEditProductFull(productFull);\n\n return (\n \n \n \n \n \n \n\n \n\n \n {shouldShowPackaging && hasQaSpecPackingPermission ? (\n \n ) : null}\n \n {isAllowEditProduct ? : null}\n\n \n\n \n\n \n\n \n {!isAllowEditProduct && (\n <>\n \n \n \n )}\n\n {/* {hasQaSpecPermission && } */}\n\n {/* {isInitialWorkflowQaSpecRibbon && (\n <>\n \n \n \n )} */}\n\n {/* {hasEvaluationFormPermission && (\n <>\n \n \n \n )} */}\n {/* {isShowIXOneCapture ? (\n <>\n \n \n \n ) : null} */}\n\n \n {/* {isBpSsoProductValidate &&\n bpSsoProductData.productId == productFull?.productId && (\n <>\n \n \n \n \n )} */}\n \n \n );\n};\n\nexport default ProductFullViewRibbon;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Messages from 'i18n/messages/home';\n\nimport { CaretRightOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nconst RunQueryControl = (props) => {\n const { onClick, disabled } = props;\n\n const onClickBtn = () => {\n onClick && onClick();\n };\n\n return (\n }\n label={Messages.runQuery}\n onClick={onClickBtn}\n disabled={disabled}\n />\n );\n};\n\nRunQueryControl.propTypes = {\n confirmRunQuery: PropTypes.func,\n};\n\nexport default RunQueryControl;\n","import React, { useState } from 'react';\nimport { Dropdown, Menu, Typography } from 'antd';\nimport { DownloadOutlined } from '@ant-design/icons';\n\nimport Messages from 'i18n/messages/home';\nimport RunQueryControl from '../../controls/advanced-search/RunQueryControl';\n\nimport { Can } from 'context/Can';\nimport { RibbonButton, RibbonSection } from 'common/components';\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\nimport { ADVANCED_FILTER_MODE } from 'pages/reporting/utils/constants';\n\nconst REPORT_EXPORT_TYPE_ADVANCED = ['XLS', 'XLSX', 'JSON', 'XML'];\n\nconst REPORT_EXPORT_TYPE_FLAT = ['XLS', 'XLSX', 'CSV', 'JSON', 'XML'];\n\nconst QuerySection = (props) => {\n const { disableRun, modeData, onClickRibbonBtn, disabledExportQuery } = props;\n const [loading, setLoading] = useState();\n\n const onClickRunBtn = () => {\n onClickRibbonBtn('run');\n };\n\n const onClickExportBtn = (exportType) => {\n setLoading(true);\n onClickRibbonBtn('export', { setLoading, exportType });\n };\n\n const exportType =\n modeData === ADVANCED_FILTER_MODE.NESTED_DATA\n ? REPORT_EXPORT_TYPE_ADVANCED\n : REPORT_EXPORT_TYPE_FLAT;\n\n const menu = (\n \n {exportType.map((exportType) => {\n return (\n {\n onClickExportBtn(exportType);\n }}\n key={exportType}\n >\n \n {exportType}\n \n \n );\n })}\n \n );\n\n return (\n \n \n \n \n \n \n }\n label={Messages.exportQuery}\n disabled={disabledExportQuery}\n />\n \n \n \n );\n};\n\nexport default QuerySection;\n","import React from 'react';\n\nimport {\n TeamOutlined,\n GoldOutlined,\n ShoppingOutlined,\n} from '@ant-design/icons';\n\nimport { dialogFunction, RibbonSection } from 'common/components';\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nimport { LAYOUT_ADVANCED_SEARCH, REPORTING_VIEW_MODE } from 'static/Constants';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/home';\n\nimport './LayoutSection.less';\n\nimport { Can } from 'context/Can';\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\n\nconst LayoutSection = (props) => {\n const intl = useIntl();\n const { onClickRibbonBtn, modeView, type } = props;\n\n const handleChangeLayout = (type) => {\n if (props.type === type) {\n return;\n }\n\n let confirmMessage = intl.formatMessage(\n Messages.changeViewQueryConfirm[type]\n );\n\n dialogFunction({\n type: 'warn',\n content: confirmMessage,\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: (close) => handleConfirmChangeLayout(close, type),\n });\n };\n\n const handleConfirmChangeLayout = (close, type) => {\n onClickRibbonBtn('changeType', { type });\n return close();\n };\n\n const checkDisabledBtn = (btnType) => {\n return modeView === REPORTING_VIEW_MODE.VIEW && btnType !== type;\n };\n\n const layoutBtnCollection = [\n {\n type: LAYOUT_ADVANCED_SEARCH.MEMBER,\n icon: ,\n ability: 'MEMBER',\n },\n {\n type: LAYOUT_ADVANCED_SEARCH.ASSET,\n icon: ,\n ability: 'ASSET',\n },\n {\n type: LAYOUT_ADVANCED_SEARCH.PRODUCT,\n icon: ,\n ability: 'PRODUCT',\n },\n ];\n\n return (\n \n \n {layoutBtnCollection.map((layoutBtn) => {\n return (\n \n handleChangeLayout(layoutBtn.type)}\n toggle={props.type === layoutBtn.type}\n disabled={checkDisabledBtn(layoutBtn.type)}\n />\n \n );\n })}\n \n \n );\n};\n\nexport default LayoutSection;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Messages from 'i18n/messages/home';\n\nimport { SaveOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nconst SaveQueryControl = ({ onClick, disabled }) => {\n const onClickBtn = () => {\n onClick && onClick();\n };\n\n return (\n }\n label={Messages.saveQuery}\n onClick={onClickBtn}\n disabled={disabled}\n />\n );\n};\n\nSaveQueryControl.propTypes = {\n confirmSaveQuery: PropTypes.func,\n};\n\nexport default SaveQueryControl;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Messages from 'i18n/messages/home';\n\nimport { DeleteOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nconst CancelQueryControl = ({ onClick }) => {\n const onClickBtn = () => {\n onClick && onClick();\n };\n\n return (\n }\n label={Messages.cancelEditUser}\n onClick={onClickBtn}\n k\n />\n );\n};\n\nCancelQueryControl.propTypes = {\n confirmEdit: PropTypes.func,\n};\n\nexport default CancelQueryControl;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { FormOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nimport Messages from 'i18n/messages/home';\n\nconst EditQueryControl = ({ onClick }) => {\n const onClickBtn = () => {\n onClick && onClick();\n };\n\n return (\n }\n label={Messages.editUser}\n onClick={onClickBtn}\n />\n );\n};\n\nEditQueryControl.propTypes = {\n confirmEdit: PropTypes.func,\n};\n\nexport default EditQueryControl;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Messages from 'i18n/messages/home';\n\nimport { CopyOutlined } from '@ant-design/icons';\nimport RibbonButton from 'common/components/button/RibbonButton';\nconst CloneQueryControl = ({ onClick }) => {\n const onClickBtn = () => {\n onClick && onClick();\n };\n\n return (\n }\n label={Messages.reportingClone}\n onClick={onClickBtn}\n />\n );\n};\n\nCloneQueryControl.propTypes = {\n confirmEdit: PropTypes.func,\n};\n\nexport default CloneQueryControl;\n","import React from 'react';\n\nimport { RibbonSection } from 'common/components';\nimport SaveQueryControl from '../../controls/advanced-search/SaveQueryControl';\nimport CancelQueryControl from '../../controls/advanced-search/CancelQueryControl';\nimport EditQueryControl from '../../controls/advanced-search/EditQueryControl';\nimport CloneQueryControl from '../../controls/advanced-search/CloneQueryControl';\n\nimport { Can } from 'context/Can';\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\nimport { REPORTING_VIEW_MODE } from 'static/Constants';\n\nconst SaveSection = (props) => {\n const { onClickRibbonBtn, modeView, isOwner, disableSave } = props;\n\n const onClickSaveBtn = () => {\n onClickRibbonBtn('save');\n };\n\n const onClickCancelBtn = () => {\n onClickRibbonBtn('cancel');\n };\n\n const onClickCloneBtn = () => {\n onClickRibbonBtn('clone');\n };\n\n const onClickEditBtn = () => {\n onClickRibbonBtn('edit');\n };\n\n const renderEditMode = () => {\n return modeView === REPORTING_VIEW_MODE.EDIT ? (\n \n \n \n \n ) : null;\n };\n\n const renderViewMode = () => {\n return modeView === REPORTING_VIEW_MODE.VIEW ? (\n \n {isOwner ? (\n \n ) : (\n \n )}\n \n ) : null;\n };\n\n const renderCreateView = () => {\n return modeView === REPORTING_VIEW_MODE.CREATE ? (\n \n \n \n ) : null;\n };\n\n return (\n \n {renderViewMode()}\n {renderEditMode()}\n {renderCreateView()}\n \n );\n};\n\nexport default SaveSection;\n","import React from 'react';\n\nimport { FolderOpenOutlined } from '@ant-design/icons';\n\nimport { RibbonButton, RibbonSection, RibbonDivider } from 'common/components';\n\nimport Messages from 'i18n/messages/home';\n\nconst OpenResultControl = (props) => {\n const { type, selectedResult, onClickRibbonBtn } = props;\n\n const onClickOpenResult = () => {\n onClickRibbonBtn('openResult');\n };\n\n const disabled = !selectedResult;\n\n return type === 'product' ? (\n \n \n }\n label={Messages.openResult}\n onClick={onClickOpenResult}\n disabled={disabled}\n />\n \n ) : null;\n};\n\nexport default OpenResultControl;\n","import React from 'react';\n\nimport {\n QuerySection,\n LayoutSection,\n SaveSection,\n} from './components/sections/advanced-search';\nimport { OtherLayout } from './components';\nimport { RibbonBar, RibbonDivider } from 'common/components';\nimport ManageSharingSection from './components/sections/shared/ManageSharingSection';\nimport DetailSection from './components/sections/home-grid/DetailSection';\nimport { ViewLayout, AdvanceStack } from './components';\nimport OpenResultControl from './components/controls/advanced-search/OpenResultControl';\nimport { useFolderByLevel } from 'hooks/useFolderByLevel';\nimport OpenSchedule from './components/controls/advanced-search/OpenSchedule';\n\nconst ReportingFullViewRibbon = (props) => {\n const {\n type,\n disabledSaveQuery,\n disabledExportQuery,\n disableRun,\n onClickRibbonBtn,\n modeData,\n modeView,\n selectedResult,\n isOwner,\n } = props;\n\n const { shouldKeepFolderBreadcrumb, keepFolderBreadcrumb } =\n useFolderByLevel();\n\n const closeDetailCallback = () => {\n //* keep folder breadcrumb when close folder item detail\n shouldKeepFolderBreadcrumb && keepFolderBreadcrumb(true);\n };\n\n return (\n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n );\n};\n\nReportingFullViewRibbon.propTypes = {};\n\nexport default ReportingFullViewRibbon;\n","import * as types from './constants';\n\n/**\n * turn on edit mode in asset full view\n */\nexport const editAsset = () => {\n return {\n type: types.EDIT_ASSET,\n };\n};\n\n/**\n * turn off edit mode in asset full view\n */\nexport const cancelEditAsset = () => {\n return {\n type: types.CANCEL_EDIT_ASSET,\n };\n};\n\n/**\n * save dirty asset data in full view\n */\nexport const savingAsset = () => {\n return {\n type: types.SAVING_ASSET_FULL,\n };\n};\n\n/**\n * save dirty asset data in full view\n */\nexport const saveAsset = (payload) => {\n return {\n type: types.SAVE_ASSET_FULL,\n payload,\n };\n};\n\n/**\n * finish edit asset data in full view\n */\nexport const finishEditAsset = () => {\n return {\n type: types.FINISH_EDIT_ASSET,\n };\n};\n\nexport const finishEditAssetSuccess = () => {\n return {\n type: types.FINISH_EDIT_ASSET_SUCCESS,\n };\n};\n\nexport const finishEditAssetError = () => {\n return {\n type: types.FINISH_EDIT_ASSET_ERROR,\n };\n};\n\nexport const getAssetId = (assetId) => {\n return {\n type: types.GET_ASSET_ID,\n payload: {\n assetId,\n },\n };\n};\n\nexport const creatingAsset = () => {\n return {\n type: types.CREATING_ASSET,\n };\n};\n\nexport const cancelCreateAsset = () => {\n return {\n type: types.CANCEL_CREATE_ASSET,\n };\n};\n\nexport const cancelSavingAsset = () => {\n return {\n type: types.CANCEL_SAVING_ASSET,\n };\n};\n\nexport const enableModeLinkAsset = () => {\n return { type: types.ENABLE_MODE_LINK_ASSETS };\n};\n\nexport const disableModeLinkAsset = () => {\n return { type: types.DISABLE_MODE_LINK_ASSETS };\n};\n\n/**\n * Replace Preview\n */\nexport const toggleReplacePreview = () => {\n return {\n type: types.TOGGLE_REPLACE_PREVIEW,\n };\n};\n\n/**\n * Replace Preview\n */\nexport const cancelReplacePreview = () => {\n return {\n type: types.CANCEL_REPLACE_PREVIEW,\n };\n};\n\nexport const getUniqueId = (uniqueId) => {\n return {\n type: types.GET_UNIQUE_ID,\n payload: {\n uniqueId,\n },\n };\n};\n\nexport const clearUniqueId = () => {\n return {\n type: types.CLEAR_UNIQUE_ID,\n };\n};\n\nexport const getCanEdit = (canEdit) => {\n return {\n type: types.GET_CAN_EDIT,\n canEdit,\n };\n};\n","// Action Types\nexport const EDIT_ASSET = 'EDIT_ASSET';\nexport const CANCEL_EDIT_ASSET = 'CANCEL_EDIT_ASSET';\nexport const SAVING_ASSET_FULL = 'SAVING_ASSET_FULL';\nexport const SAVE_ASSET_FULL = 'SAVE_ASSET_FULL';\nexport const SAVE_ASSET_FULL_SUCCESS = 'SAVE_ASSET_FULL_SUCCESS';\nexport const SAVE_ASSET_FULL_ERROR = 'SAVE_ASSET_FULL_ERROR';\nexport const FINISH_EDIT_ASSET = 'FINISH_EDIT_ASSET';\nexport const FINISH_EDIT_ASSET_SUCCESS = 'FINISH_EDIT_ASSET_SUCCESS';\nexport const FINISH_EDIT_ASSET_ERROR = 'FINISH_EDIT_ASSET_ERROR';\nexport const GET_ASSET_ID = 'GET_ASSET_ID';\nexport const CREATING_ASSET = 'CREATING_ASSET';\nexport const CANCEL_CREATE_ASSET = 'CANCEL_CREATE_ASSET';\nexport const CANCEL_SAVING_ASSET = 'CANCEL_SAVING_ASSET';\n// Asset-grid\nexport const ENABLE_MODE_LINK_ASSETS = 'ENABLE_MODE_LINK_ASSETS';\nexport const DISABLE_MODE_LINK_ASSETS = 'DISABLE_MODE_LINK_ASSETS';\nexport const REPLACE_PREVIEW = 'REPLACE_PREVIEW';\nexport const TOGGLE_REPLACE_PREVIEW = 'TOGGLE_REPLACE_PREVIEW';\nexport const CANCEL_REPLACE_PREVIEW = 'CANCEL_REPLACE_PREVIEW';\nexport const GET_UNIQUE_ID = 'GET_UNIQUE_ID';\nexport const CLEAR_UNIQUE_ID = 'CLEAR_UNIQUE_ID';\nexport const GET_CAN_EDIT = 'GET_CAN_EDIT';\n","import produce from 'immer';\nimport * as types from './constants';\n\n// initial state\nexport const initialState = {\n edit: false,\n saving: false,\n loading: false,\n assetId: null,\n creating: false,\n updating: false,\n // asset-grid\n modeLinkAssets: false,\n replacePreview: false,\n uniqueId: null,\n canEdit: false,\n};\n\nconst ribbonAssetFullReducer = (state = initialState, action) =>\n produce(state, (draft) => {\n switch (action.type) {\n case types.EDIT_ASSET:\n draft.edit = true;\n draft.saving = false;\n break;\n case types.CANCEL_EDIT_ASSET:\n draft.edit = false;\n draft.saving = false;\n draft.creating = false;\n break;\n case types.SAVING_ASSET_FULL:\n draft.saving = true;\n break;\n case types.SAVE_ASSET_FULL:\n draft.loading = true;\n draft.saving = false;\n break;\n case types.SAVE_ASSET_FULL_SUCCESS:\n draft.loading = false;\n break;\n case types.SAVE_ASSET_FULL_ERROR:\n draft.loading = false;\n break;\n case types.FINISH_EDIT_ASSET:\n draft.updating = true;\n break;\n case types.FINISH_EDIT_ASSET_SUCCESS:\n draft.edit = false;\n draft.updating = false;\n draft.creating = false;\n draft.loading = false;\n break;\n case types.FINISH_EDIT_ASSET_ERROR:\n draft.loading = false;\n break;\n case types.GET_ASSET_ID:\n draft.assetId = parseInt(action.payload.assetId, 10);\n break;\n case types.CREATING_ASSET:\n draft.creating = true;\n break;\n case types.CANCEL_CREATE_ASSET:\n draft.creating = false;\n break;\n case types.CANCEL_SAVING_ASSET:\n draft.saving = false;\n break;\n case types.ENABLE_MODE_LINK_ASSETS:\n draft.modeLinkAssets = true;\n break;\n case types.DISABLE_MODE_LINK_ASSETS:\n draft.modeLinkAssets = false;\n break;\n case types.REPLACE_PREVIEW:\n draft.replacePreview = true;\n break;\n case types.TOGGLE_REPLACE_PREVIEW:\n draft.replacePreview = !state.replacePreview;\n break;\n case types.CANCEL_REPLACE_PREVIEW:\n draft.replacePreview = false;\n break;\n case types.GET_UNIQUE_ID:\n draft.uniqueId = action.payload.uniqueId;\n break;\n case types.CLEAR_UNIQUE_ID:\n draft.uniqueId = null;\n break;\n case types.GET_CAN_EDIT:\n draft.canEdit = action.canEdit;\n break;\n default:\n break;\n }\n });\n\nexport default ribbonAssetFullReducer;\n","import { createSelector } from 'reselect';\nimport { initialState } from './reducer';\n\n/**\n * take ribbon asset full state from redux\n * @param {object} state\n */\nconst assetFull = (state) => (state && state.asset) || initialState;\n\n/**\n * Select member edit mode\n */\nconst selectAssetEdit = () => createSelector(assetFull, (state) => state.edit);\n\n/**\n * Select member edit mode\n */\nconst selectAssetSaving = () =>\n createSelector(assetFull, (state) => state.saving);\n\n/**\n * Select asset id mode\n */\nconst selectAssetId = () => createSelector(assetFull, (state) => state.assetId);\n\nconst selectAssetCreating = () =>\n createSelector(assetFull, (state) => state.creating);\n\nconst selectAssetUpdating = () =>\n createSelector(assetFull, (state) => state.updating);\n\nconst selectModeLinkAssets = () =>\n createSelector(assetFull, ({ modeLinkAssets }) => modeLinkAssets);\n/**\n * Select replace preview\n */\nconst selectReplacePreview = () =>\n createSelector(assetFull, (state) => state.replacePreview);\n\nconst selectAssetUniqueId = () =>\n createSelector(assetFull, (state) => state.uniqueId);\n\nconst selectCanEditAsset = () =>\n createSelector(assetFull, (state) => state.canEdit);\n\nexport default {\n selectAssetEdit,\n selectAssetSaving,\n selectAssetId,\n selectAssetCreating,\n selectAssetUpdating,\n selectModeLinkAssets,\n selectReplacePreview,\n selectAssetUniqueId,\n selectCanEditAsset,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Card } from 'antd';\n\nimport './Control.less';\nconst Control = (props) => {\n const {\n children,\n cardClassName,\n cardBodyStyle,\n mode,\n textAlign,\n ...rest\n } = props;\n return (\n \n {children}\n \n );\n};\n\nControl.propTypes = {\n cardClassName: PropTypes.string,\n mode: PropTypes.oneOf(['', 'inline']),\n textAlign: PropTypes.oneOf(['left', 'right', 'center']),\n};\nControl.defaultProps = {\n textAlign: 'center',\n cardBodyStyle: {\n padding: '0px',\n margin: '0px 0px 8px 0px',\n },\n};\n\nexport default Control;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Messages from 'i18n/messages/home';\n\nimport { ClearOutlined } from '@ant-design/icons';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\nimport { dialogFunction } from 'common/components/index';\n\nconst ClearColumnsControl = ({ onClick }) => {\n const showConfirmMessage = () => {\n dialogFunction({\n type: 'warn',\n content: 'Are you sure to clear Data Columns?',\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: onConfirm,\n });\n };\n\n const onConfirm = () => {\n onClick && onClick();\n };\n\n return (\n }\n label={Messages.clearColumnsQuery}\n onClick={showConfirmMessage}\n />\n );\n};\n\nClearColumnsControl.propTypes = {\n clearColumnsQuery: PropTypes.func,\n};\n\nexport default ClearColumnsControl;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Messages from 'i18n/messages/home';\n\nimport { ClearOutlined } from '@ant-design/icons';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport { dialogFunction } from 'common/components/index';\n\nconst ClearQueryControl = ({ onClick }) => {\n const showConfirmMessage = () => {\n dialogFunction({\n type: 'warn',\n content: 'Are you sure to clear Query Conditions?',\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: onConfirm,\n });\n };\n\n const onConfirm = () => {\n onClick && onClick();\n };\n\n return (\n }\n label={Messages.clearQuery}\n onClick={showConfirmMessage}\n />\n );\n};\n\nClearQueryControl.propTypes = {\n clearQuery: PropTypes.func,\n};\n\nexport default ClearQueryControl;\n","import { useMutation, useQuery } from '@tanstack/react-query';\nimport {\n configDownloadSchedule,\n deleteDownloadSchedule,\n getDownloadScheduleDetail,\n} from 'services/reporting';\nimport { getFTPconfig, validateFTPConfig } from 'services/user';\nexport const getKeyFactPanels = (id) => {\n return ['reporting', 'get-download-schedule-detail', parseInt(id)];\n};\nexport const getKeyFTPConfig = (id) => {\n return ['reporting', 'get-ftp-config', parseInt(id)];\n};\nexport const useGetDownloadScheduleDetail = ({ id, enabled }) => {\n const { data, ...restQuery } = useQuery({\n queryKey: getKeyFactPanels(id),\n queryFn: async () => {\n const { data } = await getDownloadScheduleDetail({ reportId: +id });\n return data || {};\n },\n enabled: enabled,\n });\n return {\n downloadScheduleDetail: data || {},\n ...restQuery,\n };\n};\nexport const useGetFTPConfig = ({ id, ...resProps }) => {\n const { data, ...restQuery } = useQuery({\n queryKey: getKeyFTPConfig(id),\n queryFn: async () => {\n const { data } = await getFTPconfig();\n return data || {};\n },\n ...resProps,\n });\n return {\n FTPConfig: data || {},\n ...restQuery,\n };\n};\nexport const useMutationFTPConfig = () => {\n const validateFTP = useMutation({\n mutationFn: validateFTPConfig,\n });\n return {\n validateFTP,\n };\n};\nexport const useMutationDownloadSChedule = () => {\n const deleteSchedule = useMutation({\n mutationFn: deleteDownloadSchedule,\n });\n const configSchedule = useMutation({\n mutationFn: configDownloadSchedule,\n });\n return {\n deleteSchedule,\n configSchedule,\n };\n};\n","import React from 'react';\nimport { Row, Col, Form, Checkbox } from 'antd';\nimport { CheckboxGroup } from 'common/components/input';\nimport { DAY_LIST, WEEK_DAY, MONTH_LIST, ORDER_LIST } from 'static/Constants';\nimport { SCHEDULE_FORM_LAYOUT } from 'common/components/modal-download-folder/constants';\nconst GRID_GUTTER = 8;\nconst ReportingDownloadScheduleMonthSetting = () => {\n const form = Form.useFormInstance();\n const atDays = Form.useWatch('onDays', form);\n const specificScheduleOrdinalNumeral = Form.useWatch(\n 'specificOrdinalNumeral',\n form\n );\n const specificScheduleDaysOfWeek = Form.useWatch('specificDaysOfWeek', form);\n const onCheckAllChange = (e) => {\n form.setFieldsValue({\n specificDaysOfWeek: e.target.checked ? WEEK_DAY : [],\n });\n };\n const isDaysDisabled = !!specificScheduleOrdinalNumeral?.length;\n const isSpecificDisabled = !!atDays?.length;\n const isCheckboxAllDisabled =\n !!specificScheduleOrdinalNumeral?.length || !!atDays?.length;\n return (\n <>\n \n {option}}\n />\n \n \n {option}}\n />\n \n \n \n \n (\n {option}\n )}\n />\n \n \n \n 0 &&\n specificScheduleDaysOfWeek?.length < WEEK_DAY.length\n }\n disabled={isCheckboxAllDisabled}\n style={{ marginLeft: GRID_GUTTER, marginBottom: GRID_GUTTER }}\n onChange={onCheckAllChange}\n >\n All\n
\n \n (\n {option}\n )}\n />\n \n \n \n \n );\n};\nexport default ReportingDownloadScheduleMonthSetting;\n","import React from 'react';\nimport { Row, Col, Form, InputNumber, Checkbox } from 'antd';\nimport { CheckboxGroup } from 'common/components/input';\nimport { WEEK_DAY } from 'static/Constants';\nimport { SCHEDULE_FORM_LAYOUT } from 'common/components/modal-download-folder/constants';\nconst ReportingDownloadScheduleWeekSetting = () => {\n return (\n <>\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n (\n \n {option}\n \n )}\n >\n \n \n \n \n \n );\n};\nexport default ReportingDownloadScheduleWeekSetting;","import React from 'react';\nimport { Form, Row, Col, TimePicker, Select, Radio, Divider } from 'antd';\nimport WrapperSelect from 'common/components/select/WrapperSelect';\nimport ReportingDownloadScheduleMonthSetting from './ReportingDownloadScheduleMonthSetting';\nimport ReportingDownloadScheduleWeekSetting from './ReportingDownloadScheduleWeekSetting';\nimport { TIME_ZONES } from 'static/TimeZones';\nimport { SCHEDULE_FORM_LAYOUT } from 'common/components/modal-download-folder/constants';\nconst { Option } = Select;\nconst ReportingDownloadScheduleForm = () => {\n const form = Form.useFormInstance();\n const interval = Form.useWatch('intervalType', form);\n return (\n
\n \n \n \n trigger.parentElement}\n />\n \n \n \n \n \n option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0\n }\n >\n {TIME_ZONES.map((zone) => (\n \n ))}\n \n \n \n \n \n \n \n \n Daily\n \n \n Weekly\n \n \n Monthly\n \n \n \n \n \n {interval === 'Weekly' ? : null}\n {interval === 'Monthly' ? (\n \n ) : null}\n
\n );\n};\nexport default ReportingDownloadScheduleForm;\n","import {\n FormCancelButton,\n FormDeleteButton,\n FormSaveButton,\n dialogFunction,\n} from 'common/components';\nimport React from 'react';\nconst ReportingScheduleFooter = (props) => {\n const {\n setOpenSchedule,\n onDeleteScheduleButton,\n disableSubmitButton,\n onSubmit,\n loading,\n } = props;\n const handleDelete = () => {\n dialogFunction({\n type: 'warn',\n content: `Are you sure you want to delete the download schedule?`,\n okText: 'Delete',\n okButtonProps: {\n type: 'danger',\n },\n onOk: async () => await onDeleteScheduleButton(),\n });\n };\n return (\n \n \n
\n {\n setOpenSchedule && setOpenSchedule(false);\n }}\n />\n \n
\n \n );\n};\nexport default ReportingScheduleFooter;","import moment from 'moment';\nimport { Button, Col, Form, Input, Radio, Row, Select, Tooltip } from 'antd';\nimport { useParams } from 'react-router-dom';\nimport { useQueryClient } from '@tanstack/react-query';\nimport React, { useEffect, useState } from 'react';\nimport { InfoCircleOutlined, CloudSyncOutlined } from '@ant-design/icons';\nimport { useSelector } from 'react-redux';\nimport selectorUser from '@redux/user/selectors';\nimport {\n CustomNotification,\n StyledModal,\n TypePicker,\n WrapperSelect,\n} from 'common/components';\nimport {\n ADVANCED_FILTER_MODE,\n DELIVERY_METHOD,\n REPORT_EXPORT_TYPE_ADVANCED,\n REPORT_EXPORT_TYPE_FLAT,\n} from '../utils/constants';\nimport {\n getKeyFactPanels,\n useGetDownloadScheduleDetail,\n useMutationDownloadSChedule,\n useMutationFTPConfig,\n} from '../hook/useScheduleDownload';\nimport ReportingDownloadScheduleForm from './DownloadSchedule/ReportingDownloadScheduleForm';\nimport ReportingScheduleFooter from './DownloadSchedule/ReportingScheduleFooter';\nimport { formatRangeDateTime } from 'utils/formatDate';\nimport { validateMultipleEmails } from 'utils';\nexport const DEFAULT_SETTING = {\n runsPerWeek: 0,\n intervalType: 'Daily',\n easterOrUserLocal: 'America/Belize',\n deliveryMethod: 'email',\n};\nconst ReportingScheduleModal = (props) => {\n const [form] = Form.useForm();\n const [statusFTP, setStatusFTP] = useState({\n isValidated: false,\n isSuccess: true,\n message: '',\n });\n const queryClient = useQueryClient();\n const { openSchedule, setOpenSchedule, modeData, reportingId } = props;\n const userInfo = useSelector(selectorUser.makeSelectUserInfo());\n const { downloadScheduleDetail } = useGetDownloadScheduleDetail({\n id: reportingId,\n enabled: !!reportingId && reportingId !== 'create',\n });\n const { deleteSchedule, configSchedule } = useMutationDownloadSChedule();\n const { validateFTP } = useMutationFTPConfig();\n const deliveryMethod = Form.useWatch('deliveryMethod', form);\n const onSchedule = async () => {\n try {\n const formValues = await form.validateFields();\n if (!formValues) return;\n const test = formatRangeDateTime(formValues?.runAt);\n const newDate = new Date(\n test.getTime() - test.getTimezoneOffset() * 60000\n );\n const params = {\n ...formValues,\n reportId: +reportingId,\n runAt: newDate.toISOString(),\n userTimeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n };\n configSchedule.mutate(params, {\n onSuccess: (result) => {\n if (result?.isSuccess) {\n CustomNotification.success(\n 'Reporting download schedule configured successfully'\n );\n queryClient.invalidateQueries({\n queryKey: getKeyFactPanels(reportingId),\n });\n closeModal();\n } else {\n CustomNotification.error(result?.message);\n }\n },\n });\n } catch (error) {\n console.log('error: ', error);\n }\n };\n const onFormChange = (changedValues, allValue) => {\n let updatedValues = {};\n if (changedValues.specificScheduleOrdinalNumeral) {\n updatedValues.specificScheduleOrdinalNumeral = [\n changedValues?.specificScheduleOrdinalNumeral?.[\n changedValues?.specificScheduleOrdinalNumeral.length - 1\n ],\n ].filter(Boolean);\n updatedValues.specificScheduleDaysOfWeek = [];\n }\n if (changedValues.specificScheduleDaysOfWeek) {\n if (allValue.specificScheduleOrdinalNumeral.length)\n updatedValues.specificScheduleDaysOfWeek = [\n changedValues?.specificScheduleDaysOfWeek?.[\n changedValues?.specificScheduleDaysOfWeek.length - 1\n ],\n ].filter(Boolean);\n }\n if (changedValues?.interval)\n updatedValues = {\n ...updatedValues,\n runEvery: 0,\n onDate: [],\n atDays: [],\n atMonth: [],\n specificScheduleDaysOfWeek: [],\n specificScheduleOrdinalNumeral: [],\n };\n if (changedValues?.atDays?.length > 0)\n updatedValues.specificScheduleDaysOfWeek = [];\n form.setFieldsValue(updatedValues);\n };\n const initScheduleDownload = (scheduleSetup = {}) => {\n const updateValues = {\n ...scheduleSetup,\n runAt: scheduleSetup?.runAt\n ? moment(scheduleSetup?.runAt)\n : moment('00:00:00', 'HH:mm:ss'),\n emails: scheduleSetup?.emails || userInfo?.email,\n fileType: scheduleSetup?.fileType?.toUpperCase() || 'XLSX',\n easterOrUserLocal: scheduleSetup?.easterOrUserLocal || 'America/Detroit',\n onDays: scheduleSetup?.onDays || ['1'],\n };\n form.setFieldsValue(updateValues);\n };\n const handleDeleteSchedule = async () => {\n await deleteSchedule.mutateAsync(\n { reportId: +reportingId },\n {\n onSuccess: (result) => {\n if (result?.isSuccess) {\n CustomNotification.success(\n 'Delete reporting download schedule successfully'\n );\n queryClient.invalidateQueries({\n queryKey: getKeyFactPanels(reportingId),\n });\n closeModal();\n } else {\n CustomNotification.error(result?.message);\n }\n },\n }\n );\n };\n const closeModal = () => {\n form.resetFields();\n setOpenSchedule(false);\n };\n const handleValidateFTP = () => {\n validateFTP.mutate(\n {},\n {\n onSuccess: (result) => {\n if (result?.isSuccess) {\n setStatusFTP({ isValidated: true, isSuccess: true, message: '' });\n } else {\n setStatusFTP({\n isValidated: true,\n isSuccess: false,\n message: result?.message,\n });\n }\n },\n }\n );\n };\n useEffect(() => {\n if (openSchedule) initScheduleDownload(downloadScheduleDetail);\n }, [openSchedule, JSON.stringify(downloadScheduleDetail)]);\n const disableSubmitButton = !statusFTP?.isSuccess && deliveryMethod === 'ftp';\n const exportType =\n modeData === ADVANCED_FILTER_MODE.NESTED_DATA\n ? REPORT_EXPORT_TYPE_ADVANCED\n : REPORT_EXPORT_TYPE_FLAT;\n return (\n \n }\n >\n \n \n \n \n {\n if (e.target.value === 'ftp' && !statusFTP?.isValidated) {\n handleValidateFTP();\n }\n }}\n >\n {DELIVERY_METHOD?.map((option, index) => {\n const title = option?.toUpperCase();\n return (\n \n \n \n \n \n );\n })}\n \n \n \n \n {deliveryMethod === 'email' && (\n ,\n }}\n rules={[\n {\n required: true,\n message: 'This field is required',\n },\n {\n validator: (_, value) => {\n const validateEmail = validateMultipleEmails(value);\n if (validateEmail || !value) {\n return Promise.resolve();\n } else {\n return Promise.reject('Invalid email format');\n }\n },\n },\n ]}\n >\n \n \n )}\n {deliveryMethod === 'ftp' && (\n \n \n }\n type='primary'\n onClick={handleValidateFTP}\n >\n Test Connection\n \n \n {statusFTP?.isSuccess ? (\n \n \n FTP Successfully Connected.\n \n \n ) : (\n \n \n {statusFTP?.message}\n \n \n )}\n \n )}\n \n \n \n \n \n {\n return triggerNode;\n }}\n >\n {[\n exportType.map((type) => {\n return (\n \n {type?.toUpperCase()}\n \n );\n }),\n ]}\n \n \n \n \n \n \n \n );\n};\nexport default ReportingScheduleModal;\n","import React, { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { FieldTimeOutlined } from '@ant-design/icons';\nimport { RibbonButton, RibbonSection, RibbonDivider } from 'common/components';\nimport { useGetDownloadScheduleDetail } from 'pages/reporting/hook/useScheduleDownload';\nimport { isEmpty } from 'lodash';\nimport ReportingScheduleModal from 'pages/reporting/components/ReportingScheduleModal';\nconst OpenSchedule = (props) => {\n const { modeData, reportId, showScheduleDownload = true } = props;\n const { reportingId } = useParams();\n const [openSchedule, setOpenSchedule] = useState(false);\n const _id = reportId || reportingId;\n const { downloadScheduleDetail } = useGetDownloadScheduleDetail({\n id: _id,\n enabled: !!_id && _id !== 'create',\n });\n const onClickOpenResult = () => {\n setOpenSchedule(true);\n };\n const disabled = reportingId === 'create' || !showScheduleDownload;\n return (\n <>\n \n \n }\n label='Download Schedule'\n onClick={onClickOpenResult}\n toggle={!isEmpty(downloadScheduleDetail)}\n />\n \n \n \n );\n};\nexport default OpenSchedule;\n","import React, { useState, useEffect } from 'react';\n\nimport PropTypes from 'prop-types';\n\n// import { ReactComponent as IconDeletePreview } from 'common/components/button/svg-icons/ICO_76.svg';\nimport { CloseCircleOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport { dialogFunction } from 'common/components/index';\n\nimport * as constant from 'static/Constants';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\n\nimport { injectIntl } from 'react-intl';\nimport ribbonMessages from 'i18n/messages/home';\nimport previewMessages from 'i18n/messages/assetPreview';\n\nimport { useCheckAllowDeleteAssets } from 'hooks';\n\nimport * as digitalAssetsService from 'services/digitalAsset';\n\nconst DeletePreview = (props) => {\n const reloadPage = useDispatchReloadPage();\n const { sectionDisabled, currentSelectedAssets, typeView, isIframe, intl } =\n props;\n\n const [disabled, setDisabled] = useState(true);\n\n const { checkAllowDeleteAssetFull, checkAllowDeleteAssetGrid } =\n useCheckAllowDeleteAssets();\n\n const isAllowDeleteGrid = checkAllowDeleteAssetGrid();\n const isAllowDeleteFull = checkAllowDeleteAssetFull();\n\n const checkButtonDisabled = (currentSelected) => {\n // const ownSelectedAssets = currentSelected?.map((asset) => {\n // return asset?.isOwner; // before: asset.canEdit\n // });\n\n const isAllowDeletePreview = checkAllowDeletePreview(\n typeView,\n isAllowDeleteGrid,\n isAllowDeleteFull\n );\n\n // The condition for the activation of the button is\n const isActivate =\n isAllowDeletePreview &&\n // the preview section is not disabled\n !sectionDisabled &&\n // the asset is not iFrame\n !isIframe;\n\n if (isActivate) {\n setDisabled(false);\n } else {\n setDisabled(true);\n }\n };\n\n const showConfirmModal = () => {\n dialogFunction({\n type: 'warn',\n content: intl.formatMessage(previewMessages.deletePreviewConfirmMessage),\n onOk: callDeletePreviewApi,\n });\n };\n\n const showErrorMessage = () => {\n dialogFunction({\n type: 'error',\n content: intl.formatMessage(previewMessages.deletePreviewError),\n cancelButtonProps: {\n style: {\n display: 'none',\n },\n },\n });\n };\n\n const callDeletePreviewApi = () => {\n //generate request data\n const requestData = currentSelectedAssets.reduce((accumulator, asset) => {\n return { ...accumulator, [asset.id]: null };\n }, {});\n\n const data = {\n data: requestData,\n };\n\n digitalAssetsService\n .updateDigitalAssetThumb(data)\n .then((response) => {\n if (response.isSuccess) {\n makePageReload();\n } else {\n showErrorMessage();\n }\n })\n .catch((err) => {\n showErrorMessage();\n });\n };\n\n const makePageReload = () => {\n // only reload page\n if (typeView !== constant.RIBBON_TYPES.DETAILSVIEW) {\n // reload asset full view page\n reloadPage();\n }\n };\n\n useEffect(() => {\n checkButtonDisabled(currentSelectedAssets);\n //eslint-disable-next-line\n }, [currentSelectedAssets]);\n\n return (\n }\n label={ribbonMessages.deletePreview}\n disabled={disabled}\n onClick={showConfirmModal}\n />\n );\n};\n\nconst checkAllowDeletePreview = (\n typeView = '',\n isAllowDeleteGrid,\n isAllowDeleteFull\n) => {\n if (typeView?.toLowerCase() === 'grid') {\n return isAllowDeleteGrid;\n }\n\n return isAllowDeleteFull;\n};\n\nDeletePreview.propTypes = {\n currentSelectedAssets: PropTypes.array,\n sectionDisabled: PropTypes.bool,\n typeView: PropTypes.oneOf(['grid', 'full']),\n isIframe: PropTypes.bool,\n};\n\nDeletePreview.defaultProps = {\n typeView: 'full',\n};\n\nexport default injectIntl(DeletePreview);\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { Modal } from 'antd';\n// import { ReactComponent as IconGeneratePreview } from 'common/components/button/svg-icons/ICO_77.svg';\nimport { DeploymentUnitOutlined } from '@ant-design/icons';\nimport { cloneDeep } from 'lodash';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport { GeneratePreviewModal, GenerateConfirmModal } from '../../index';\n\nimport * as actionsAsset from 'pages/branded-assets/controllers/actions';\nimport * as assetsSelector from 'pages/branded-assets/controllers/selectors';\nimport * as digitalAssetsService from 'services/digitalAsset';\nimport * as ribbonSelector from '@redux/ribbon/selectors';\n\n// import * as assetFullViewSelector from 'pages/asset-full-view/controllers/selectors';\n\nimport * as constant from 'static/Constants';\nimport { dialogFunction } from 'common/components/index';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\n\nimport ribbonMessages from 'i18n/messages/home';\nimport assetPreviewMessages from 'i18n/messages/assetPreview';\nimport { injectIntl } from 'react-intl';\n\nimport { useCheckAllowEditAssets } from 'hooks';\n\nconst GeneratePreview = (props) => {\n const dispatch = useDispatch();\n const reloadPage = useDispatchReloadPage();\n // props\n const { intl, currentSelectedAssets, sectionDisabled, disabledPreview } =\n props;\n\n const cachedImages = useSelector(assetsSelector.makeSelectCachedImages());\n\n // const assetFullView = useSelector(\n // assetFullViewSelector.makeSelectAssetData()\n // );\n\n const typeView = useSelector(ribbonSelector.selectRibbonType());\n\n const view = useSelector(ribbonSelector.selectRibbon());\n\n const isFullView = view === constant.RIBBON_VIEW.ASSET_FULL_VIEW.NAME;\n\n const { checkAllowEditAssetFull, checkAllowEditAssetGrid } =\n useCheckAllowEditAssets();\n\n const isAllowEditFull = checkAllowEditAssetFull();\n const isAllowEditGrid = checkAllowEditAssetGrid();\n\n // state\n // button disabled\n const [disabled, setDisabled] = useState(true);\n\n // generate thumbnail modal\n const [visible, setVisible] = useState(false);\n // confirm modal\n const [showConfirmModal, setShowConfirmModal] = useState(false);\n\n // dialog loading\n const loadingHook = useState(false);\n const [, setLoading] = loadingHook;\n\n // this is generate thumbnail response data, and the last data submit to update asset preview thumb\n // when user upload new thumb, this data will update\n const rootDataHook = useState([]);\n const [rootData] = rootDataHook;\n\n const selectGenerateThumbHook = useState([]);\n const [selectedGeneratedThumb, setSelectedGeneratedThumb] =\n selectGenerateThumbHook;\n\n // function\n const showConfirmModalHandler = () => {\n setShowConfirmModal(true);\n };\n\n const hideConfirmModalHandler = () => {\n setShowConfirmModal(false);\n };\n\n const showPopup = () => {\n hideConfirmModalHandler();\n setVisible(true);\n setLoading(true);\n };\n\n const handleOk = () => {\n setLoading(true);\n // call api submit update asset thumbnail\n callApiUpdateAssetsThumb();\n };\n\n const handleCancel = () => {\n setVisible(false);\n // reset preview dialog state\n setLoading(false);\n setSelectedGeneratedThumb([]);\n };\n\n const createCachedImages = (cacheDataList) => {\n const newCachedImages = cloneDeep(cachedImages);\n\n cacheDataList &&\n cacheDataList.forEach((assetId) => {\n if (newCachedImages[assetId]) {\n newCachedImages[assetId]++;\n } else {\n newCachedImages[assetId] = 1;\n }\n });\n\n dispatch(actionsAsset.updateCacheImage(newCachedImages));\n };\n const onClickOkSuccessMessage = (close) => {\n makePageReload();\n close();\n };\n const makePageReload = () => {\n // only reload page\n if (typeView !== constant.RIBBON_TYPES.DETAILSVIEW) {\n // reload asset full view page\n reloadPage();\n }\n };\n\n const callApiUpdateAssetsThumb = () => {\n //generate request data\n const requestData = selectedGeneratedThumb.reduce((accumulator, id) => {\n const currentRootDataItem = rootData.find(({ assetId }) => {\n return assetId === id;\n });\n return { ...accumulator, [id]: currentRootDataItem.data };\n }, {});\n\n const data = {\n data: requestData,\n };\n\n digitalAssetsService\n .updateDigitalAssetThumb(data)\n .then((response) => {\n if (response.isSuccess) {\n // show message\n showSuccessMessage();\n\n // cached update image\n const cacheData = data?.data;\n const cacheDataList = cacheData && Object.keys(cacheData);\n createCachedImages(cacheDataList);\n } else {\n showErrorMessage(\n intl.formatMessage(assetPreviewMessages.generatePreviewError)\n );\n }\n })\n .catch((err) => {\n showErrorMessage(\n intl.formatMessage(assetPreviewMessages.generatePreviewError)\n );\n })\n .finally(() => {\n // hide loading\n setLoading(false);\n // close dialog\n setVisible(false);\n });\n };\n\n const backgroundGeneration = () => {\n hideConfirmModalHandler();\n const selectedAssetsId =\n currentSelectedAssets?.length &&\n currentSelectedAssets.map((asset) => {\n return asset.id;\n });\n\n const params = {\n assetIds: selectedAssetsId,\n };\n\n digitalAssetsService\n .generatePreviewBackground(params)\n .then((response) => {\n if (response.isSuccess) {\n // show success message\n showSuccessMessage();\n\n // cached update image\n createCachedImages(selectedAssetsId);\n } else {\n showErrorMessage(\n intl.formatMessage(assetPreviewMessages.generatePreviewError)\n );\n }\n })\n .catch((err) => {\n showErrorMessage(\n intl.formatMessage(assetPreviewMessages.generatePreviewError)\n );\n });\n };\n\n const showSuccessMessage = () => {\n dialogFunction({\n type: 'success',\n content: intl.formatMessage(assetPreviewMessages.generatePreviewSuccess),\n onOk: onClickOkSuccessMessage,\n cancelButtonProps: {\n style: {\n display: 'none',\n },\n },\n });\n };\n\n const showErrorMessage = (message) => {\n dialogFunction({\n type: 'error',\n content: message,\n cancelButtonProps: {\n style: {\n display: 'none',\n },\n },\n });\n };\n\n const checkButtonDisabled = (currentSelected) => {\n // const ownSelectedAssets = currentSelected?.map((asset) => {\n // return asset?.isOwner; // before: asset.canEdit\n // });\n\n const isAllowGeneratePreview = checkAllowGeneratePreview(\n isFullView,\n isAllowEditFull,\n isAllowEditGrid\n );\n\n // The condition for the activation of the button is\n const isActivate =\n isAllowGeneratePreview &&\n // the preview section is not disabled\n !sectionDisabled;\n\n if (isActivate) {\n setDisabled(false);\n } else {\n setDisabled(true);\n }\n };\n\n // component did update\n // update disabled when currentSelectedAssets change\n useEffect(() => {\n checkButtonDisabled(currentSelectedAssets);\n //eslint-disable-next-line\n }, [currentSelectedAssets]);\n\n // variables\n // modal configs\n const modalConfig = {\n visible,\n okText: intl.formatMessage(assetPreviewMessages.generatePreviewSubmit),\n okButtonProps: {\n disabled: !selectedGeneratedThumb.length,\n },\n onOk: handleOk,\n onCancel: handleCancel,\n destroyOnClose: true,\n closable: false,\n wrapClassName: 'generate-preview__modal',\n width: 'auto',\n style: {\n maxWidth: 'min(1052px, 85%)',\n width: 'auto',\n display: 'inline-block',\n },\n bodyStyle: {\n maxHeight: '80vh',\n minWidth: '695px',\n overflowY: 'auto',\n padding: '16px 10px',\n },\n };\n\n const confirmModalConfig = {\n visible: showConfirmModal,\n onYes: backgroundGeneration,\n onNo: showPopup,\n onCancel: hideConfirmModalHandler,\n };\n\n return (\n <>\n }\n label={ribbonMessages.generatePreview}\n onClick={showConfirmModalHandler}\n disabled={disabled || disabledPreview}\n />\n \n \n \n \n \n );\n};\n\nconst checkAllowGeneratePreview = (\n isFullView,\n isAllowEditFull,\n isAllowEditGrid\n) => {\n if (isFullView) {\n return isAllowEditFull;\n }\n\n return isAllowEditGrid;\n};\n\nGeneratePreview.propsTypes = {\n /**\n * selected assets to generate thumbnail\n */\n currentSelectedAssets: PropTypes.array,\n /**\n * preview section ribbon disabled condition\n */\n sectionDisabled: PropTypes.bool,\n};\n\nexport default injectIntl(GeneratePreview);\n","import React from 'react';\nimport { useSelector } from 'react-redux';\nimport Messages from 'i18n/messages/home';\n\n// import { ReactComponent as IconOpenAsset } from 'common/components/button/svg-icons/ICO_69.svg';\nimport { FolderOpenOutlined } from '@ant-design/icons';\n\nimport { forwardTo } from 'utils/common/route';\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport gridSelector from 'common/components/grid-view/controllers/selectors';\n\nconst OpenAsset = () => {\n const selectedAssetDetail = useSelector(\n gridSelector.makeSelectDetailCurrentITemsSelection()\n );\n const assetId =\n selectedAssetDetail && selectedAssetDetail?.length > 0\n ? selectedAssetDetail[0]?.id\n : undefined;\n\n return (\n }\n label={Messages.openAsset}\n onClick={() => forwardTo(`/asset/${assetId}`)}\n disabled={assetId === undefined || selectedAssetDetail.length !== 1}\n />\n );\n};\n\nexport default OpenAsset;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Messages from 'i18n/messages/home';\nimport { PushpinOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nconst AddOpenItemBtn = ({ clickActionCallback }) => {\n const onCheckDisableBtn = () => {\n const routes = [\n '/asset/create',\n '/asset/create-iframe',\n '/member-management-company',\n '/asset/versions',\n ];\n let currentRoute = window.location.pathname;\n let isDisable = false;\n routes.every((route) => {\n if (currentRoute.includes(route)) {\n isDisable = true;\n return false;\n } else return true;\n });\n return isDisable;\n };\n\n return (\n }\n label={Messages.addOpenItem}\n onClick={clickActionCallback}\n disabled={onCheckDisableBtn()}\n />\n );\n};\n\nAddOpenItemBtn.propTypes = {\n clickActionCallback: PropTypes.func,\n};\n\nexport default AddOpenItemBtn;\n","import * as React from \"react\";\nconst SvgCopy = props => ;\nexport { SvgCopy as ReactComponent };\nexport default \"data:image/svg+xml;base64,PHN2ZyBpZD0iQ2FwYV8xIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MTIgNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHdpZHRoPSI1MTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGc+PHBhdGggZD0ibTE0Ni45ODMgNDIyaDE3NC4xNjZ2MzBoLTE3NC4xNjZ6Ii8+PHBhdGggZD0ibTQ4MS45OSA5Mi4xNzd2LTYwaC0xODguODc0bC00MS4wMTQtMzIuMTc3aC0xNDguMjIzdjE2OC45NmgtMTAzLjg2OXYyOTcuNDE2YzAgMjQuNDg2IDE5LjYyNCA0NC45NDUgNDMuNzQ2IDQ1LjYwNi40MjYuMDEyIDMxOS4zNjUuMDE4IDMxOS4zNjUuMDE4IDI0LjgxMyAwIDQ1LTIwLjE4NyA0NS00NXYtMTIzLjk2Mmw1OC44NjkuMDAyYzI0LjgxMyAwIDQ1LTIwLjE4NyA0NS00NXYtMjA1Ljg2M3ptLTM0OC4xMTEtNjIuMTc3aDEwNy44NTlsNDEuMDE0IDMyLjE3N2gxNjkuMjM4djMwaC0yODguMTF2MjA1Ljg2M2MwIDQuMDg0LTEuNjEzIDcuOTAzLTQuNTQyIDEwLjc1My0yLjg2MiAyLjc4NC02LjYyNiA0LjI3Ni0xMC42MiA0LjIzNWgtLjQzOWMtNy45NTYtLjMxMy0xNC4zOTktNy4yNzktMTQuMzk5LTE1LjYxMnYtMjY3LjQxNnptLTczLjg2OSA0MzdjMCA0LjA4NC0xLjYxMyA3LjkwMy00LjU0MiAxMC43NTMtMi45MjYgMi44NDctNi43NzggNC4zNDQtMTAuODkxIDQuMjQxLTguMDMzLS4yMjEtMTQuNTY4LTcuMjI3LTE0LjU2OC0xNS42MTh2LTI2Ny40MTZoNzMuODY5djYyLjE3N2gtNDMuODY4em0zMTguMTExIDBjMCA4LjI3MS02LjcyOSAxNS0xNSAxNWgtMjc1LjY1M2MxLjY3Mi00Ljc0OSAyLjU0My05LjgwMyAyLjU0My0xNXYtMTc1Ljg2M2gxMy44Njl2Ni4yNzljMCAyNC40ODYgMTkuNjI0IDQ0Ljk0NSA0My43NDYgNDUuNjA2bDIzMC40OTYuMDE0djEyMy45NjR6bTEwMy44NjktMTY4Ljk2YzAgOC4yNzEtNi43MjkgMTUtMTUgMTVsLTI3NS42Ni0uMDFjMS42NzEtNC43NDcgMi41NDktOS43OTUgMi41NDktMTQuOTl2LTE3NS44NjNoMjg4LjExdjE3NS44NjN6Ii8+PHBhdGggZD0ibTI1MC44NTIgMjUzLjA0aDE3NC4xNjV2MzBoLTE3NC4xNjV6Ii8+PC9nPjwvc3ZnPg==\";","import React from 'react';\n\nimport { RibbonButton } from 'common/components';\nimport { ReactComponent as IconCopyFolder } from 'common/components/button/svg-icons/copy.svg';\n\nimport Messages from 'i18n/messages/home';\nimport { injectIntl } from 'react-intl';\n\nconst CopyFolder = ({ selectedFolders, disabled, onClick }) => {\n const isDisable = selectedFolders?.length === 0 || disabled;\n\n return (\n }\n label={Messages.copyFolder}\n disabled={isDisable}\n onClick={onClick}\n />\n );\n};\n\nexport default injectIntl(CopyFolder);\n","import React, { useState } from 'react';\n\nimport { Input, Checkbox, Typography } from 'antd';\nimport { Form, StyledModal, FolderSelector } from 'common/components';\n\nimport { apiHandler } from 'utils/api';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\nimport { useGridView } from 'hooks/useGridView';\n\nimport * as folderServices from 'services/folder';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/folder';\n\nconst { Title } = Typography;\n\nconst CopyFolderModal = (props) => {\n const [form] = Form.useForm();\n const intl = useIntl();\n\n const { visible, closeModal, selectedFolder, onCopy } = props;\n\n const [loading, setLoading] = useState(false);\n\n const reloadPage = useDispatchReloadPage();\n const { clearGridSelection } = useGridView();\n\n const onBreadcrumbChange = (currentBreadcrumbItem, breadcrumbList) => {\n const hierarchy =\n breadcrumbList\n .map((breadcrumbItem) => breadcrumbItem.id)\n .join('/')\n .replace('home', '') + '/';\n\n const folder = { id: currentBreadcrumbItem, hierarchy };\n\n form.setFieldsValue({ destinationFolder: folder });\n };\n\n const onSelectDestinationFolder = (folder) => {\n form.setFieldsValue({ destinationFolder: folder });\n };\n\n const onSubmit = () => {\n form.validateFields().then((values) => {\n let { newFolderName, destinationFolder, ...restValues } = values;\n\n const params = {\n ...restValues,\n newFolderName: newFolderName.trim(),\n folderId: selectedFolder?.id,\n destinationFolderId: destinationFolder?.id,\n };\n\n if (destinationFolder?.id === 'home') {\n delete params['destinationFolderId'];\n destinationFolder = undefined;\n }\n\n const successMessage = intl.formatMessage(Messages.copyFolderSuccess);\n const errorMessage = intl.formatMessage(Messages.copyFolderError);\n\n setLoading(true);\n\n apiHandler({\n service: folderServices.copyFolder,\n params,\n successMessage,\n errorMessage,\n successCallback: copySuccessCallback({ destinationFolder }),\n onFinally: copyFinally,\n });\n });\n };\n\n const cancelModal = () => {\n closeModal();\n resetState();\n };\n\n const copySuccessCallback =\n ({ destinationFolder }) =>\n () => {\n reloadPage();\n cancelModal();\n\n clearGridSelection();\n onCopy && onCopy({ destinationFolder });\n };\n\n const copyFinally = () => {\n setLoading(false);\n };\n\n const resetState = () => {\n form.resetFields();\n setLoading(false);\n };\n\n return (\n \n
\n \n \n \n \n \n {intl.formatMessage({\n id: 'Taco.folder.component.copyFormCheckbox',\n })}\n \n \n\n \n Select Destination Folder\n
\n \n
\n \n \n );\n};\n\nexport default CopyFolderModal;\n","import React from 'react';\nimport { Modal } from 'antd';\n\nconst ModalAction = (props) => {\n return ;\n};\n\nexport default ModalAction;\n","import React, { useState, useEffect } from 'react';\nimport { Button, Col, Input, Row } from 'antd';\n\nimport { CustomNotification, Form } from 'common/components';\nimport ModalAction from 'common/components/modal-action/ModalAction';\n\nimport * as folderServices from 'services/folder';\nimport { apiHandler } from 'utils/api';\n\nimport { injectIntl } from 'react-intl';\nimport Messages from 'i18n/messages/folder';\nimport { sleep } from 'utils/delay';\n\nconst CreateFolderModal = (props) => {\n const {\n intl,\n visibleHook,\n successCallback,\n handleReloadFolderList,\n currentFolderId,\n parentId,\n onReloadWhenSaveSuccess,\n additionalButton,\n skipNotification = false,\n } = props;\n const [visible, setVisible] = visibleHook;\n const [loading, setLoading] = useState(false);\n const [formInst] = Form.useForm();\n\n const closeModal = () => {\n !loading && setVisible(false);\n };\n\n const handleCreateFolder = async (value) => {\n formInst\n .validateFields()\n .then((values) => {\n const { name } = values;\n const trimmedName = name?.trim();\n if (name) {\n const params = {\n folderName: trimmedName,\n parentFolderId: parentId,\n };\n\n setLoading(true);\n apiHandler({\n service: folderServices.createFolder,\n params: params,\n successMessage: intl.formatMessage(Messages.createFolderSuccess),\n errorMessage: intl.formatMessage(Messages.createFolderError),\n successCallback: createFolderSuccessCallback,\n failCallback: createFolderFailureCallback,\n onFinally: createFolderFinally,\n skipNotification,\n });\n }\n })\n .catch((error) => {});\n };\n\n const createFolderSuccessCallback = async (responseData) => {\n await sleep(1000);\n\n !!successCallback && successCallback(responseData);\n !!onReloadWhenSaveSuccess &&\n onReloadWhenSaveSuccess(responseData.id, 'create');\n };\n\n const createFolderFailureCallback = (message) => {\n message && CustomNotification.error(message);\n };\n\n const createFolderFinally = async () => {\n if (handleReloadFolderList) {\n await sleep(3000);\n handleReloadFolderList(currentFolderId);\n }\n\n setVisible(false);\n setLoading(false);\n };\n\n useEffect(() => {\n if (!visible) {\n formInst.resetFields();\n }\n }, [visible, formInst]);\n\n return (\n \n
\n \n \n \n\n \n \n {additionalButton && additionalButton()}\n \n \n \n {intl.formatMessage(Messages.createModalCreateButton)}\n \n \n \n \n \n \n );\n};\n\nexport default injectIntl(CreateFolderModal);\n","import React from 'react';\n\nimport Slot from 'common/components/slot/Slot';\nimport GridStyleLayout from 'common/components/layout/GridStyleLayout';\n\nconst ManageScheduleDownloadLayout = (props) => {\n const { children } = props;\n\n const layoutAreas = [['toolbar'], ['grid']];\n\n return (\n \n \n {children}\n \n \n {children}\n \n \n );\n};\n\nexport default ManageScheduleDownloadLayout;\n","import { useMutation } from '@tanstack/react-query';\n\nimport * as folderServices from 'services/folder';\nimport { dialogFunctionAsync, CustomNotification } from 'common/components';\n\nimport { getManageScheduleDownloadKey } from './queries';\n\nexport const useDeleteScheduleDownload = (props) => {\n const { folderId } = props;\n\n const deleteScheduleDownload = useMutation({\n mutationKey: ['delete-schedule-download-folder'],\n mutationFn: async (params) => {\n try {\n return folderServices.removeFolderScheduleDownload(params);\n } catch (error) {\n console.error('error: ', error);\n }\n },\n meta: {\n invalidates: [getManageScheduleDownloadKey(folderId)],\n },\n });\n\n const showDeleteConfirm = () => {\n return dialogFunctionAsync({\n type: 'warn',\n content: 'Are you sure you want to delete schedule?',\n okText: 'Delete',\n cancelText: 'Cancel',\n okButtonProps: {\n danger: true,\n },\n });\n };\n\n const showDeleteMessage = (status, message) => {\n if (status === 'success') {\n CustomNotification.success('Delete Schedule successfully');\n } else {\n CustomNotification.error(message || 'Fail to delete Schedule');\n }\n };\n\n return { deleteScheduleDownload, showDeleteConfirm, showDeleteMessage };\n};\n","import { useMutation } from '@tanstack/react-query';\n\nimport * as folderServices from 'services/folder';\nimport { CustomNotification } from 'common/components';\n\nimport { getManageScheduleDownloadKey } from './queries';\n\nexport const useUpdateScheduleDownload = (props) => {\n const { folderId } = props;\n\n const updateScheduleDownload = useMutation({\n mutationKey: ['update-schedule-download-folder'],\n mutationFn: async (params) => {\n try {\n return folderServices.updateFolderScheduleDownload(params);\n } catch (error) {\n console.error('error: ', error);\n }\n },\n meta: {\n invalidates: [getManageScheduleDownloadKey(folderId)],\n },\n });\n\n return { updateScheduleDownload };\n};\n","import React, { useState } from 'react';\n\nimport { Row, Col, Space } from 'antd';\n\nimport {\n FormEditButton,\n FormDeleteButton,\n FormCancelButton,\n CustomNotification,\n} from 'common/components';\nimport DownloadFolderModal from 'common/components/modal-download-folder/DownloadFolderModal';\n\nimport { useGetScheduleDownloadDetailQuery } from 'hooks/folders/queries';\nimport {\n useDeleteScheduleDownload,\n useCancelScheduleDownload,\n useUpdateScheduleDownload,\n} from 'hooks/folders';\n\nconst ManageScheduleDownloadToolbar = (props = {}) => {\n const { selectedSchedule, setSelectedSchedule, folderId } = props || {};\n\n const [downloadModalVisible, setDownloadModalVisible] = useState(false);\n\n const { data: schedulerDetail } = useGetScheduleDownloadDetailQuery({\n scheduleId: selectedSchedule?.id,\n enabled: selectedSchedule?.id && downloadModalVisible,\n });\n\n const { downloadSetting, ...restSchedulerDetail } = schedulerDetail || {};\n\n const { updateScheduleDownload } = useUpdateScheduleDownload({ folderId });\n const { deleteScheduleDownload, showDeleteConfirm, showDeleteMessage } =\n useDeleteScheduleDownload({ folderId });\n const { cancelScheduleDownload, showCancelConfirm, showCancelMessage } =\n useCancelScheduleDownload({\n folderId,\n });\n\n const showDownloadModal = () => {\n setDownloadModalVisible(true);\n };\n\n const closeDownloadModal = () => {\n setDownloadModalVisible(false);\n };\n\n const updateScheduler = async (formParams) => {\n try {\n const params = { id: selectedSchedule?.id, ...formParams };\n const response = await updateScheduleDownload.mutateAsync(params);\n\n if (response?.isSuccess) {\n CustomNotification.success('Update Scheduler Successfully');\n\n return Promise.resolve({ isSuccess: true });\n } else CustomNotification.error('Fail to update scheduler');\n } catch (error) {\n CustomNotification.error('Fail to update scheduler');\n }\n };\n\n const onClickEditBtn = () => {\n showDownloadModal();\n };\n\n const onClickDeleteBtn = async () => {\n const confirmed = await showDeleteConfirm();\n\n if (!confirmed?.ok) return;\n\n try {\n const result = await deleteScheduleDownload.mutateAsync({\n id: selectedSchedule?.id,\n });\n\n if (result.isSuccess) {\n setSelectedSchedule(null);\n return showDeleteMessage('success');\n }\n\n showDeleteMessage('error', result?.message);\n } catch (error) {\n showDeleteMessage('error');\n }\n };\n\n const onClickCancelBtn = async () => {\n const confirmed = await showCancelConfirm();\n\n if (!confirmed?.ok) return;\n\n try {\n const result = await cancelScheduleDownload.mutateAsync({\n id: selectedSchedule?.id,\n });\n\n if (result.isSuccess) {\n setSelectedSchedule(null);\n return showCancelMessage('success');\n }\n\n showCancelMessage('error', result?.message);\n } catch (error) {\n showCancelMessage('error');\n }\n };\n\n const cancelButtonDisabled =\n !selectedSchedule ||\n selectedSchedule?.status?.toLowerCase() !== 'active' ||\n deleteScheduleDownload?.isLoading;\n\n const editButtonDisabled =\n !selectedSchedule ||\n selectedSchedule?.status?.toLowerCase() !== 'active' ||\n deleteScheduleDownload?.isLoading ||\n cancelScheduleDownload?.isLoading;\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nexport default ManageScheduleDownloadToolbar;\n","import moment from 'moment';\nimport { formatMDYWithParam } from 'utils/formatDate';\n\nimport { TIME_ZONES } from 'static/TimeZones';\n\nexport const getColumns = () => {\n const columns = [\n {\n field: 'created',\n headerName: 'Created at',\n flex: 1,\n valueFormatter: formatMDYWithParam,\n },\n {\n field: 'runAt',\n headerName: 'Run at',\n flex: 1,\n valueFormatter: (params) => moment(params.value).format('HH:mm:ss'),\n },\n {\n field: 'timezone',\n flex: 1,\n valueFormatter: ({ value }) =>\n TIME_ZONES.find((timezone) => timezone.utc[0] === value)?.text || value,\n },\n {\n field: 'interval',\n flex: 1,\n },\n { field: 'status' },\n ];\n\n return columns;\n};\n","import React, { useRef } from 'react';\n\nimport { AgGridClient } from 'common/components';\n\nimport * as utils from './utils';\n\nimport { useManageScheduleDownloadQuery } from 'hooks/folders/queries';\n\nconst containerStyle = {\n height: '100%',\n};\n\nconst ManageScheduleDownloadGrid = (props) => {\n const gridRef = useRef();\n const { folderId, setSelectedSchedule } = props;\n\n const { data } = useManageScheduleDownloadQuery({ folderId });\n\n const scheduleList = data?.schedules;\n\n const columns = utils.getColumns();\n\n const onSelectionChangedHandler = (e) => {\n const selectedRow = gridRef.current.api.getSelectedRows();\n setSelectedSchedule(selectedRow?.[0]);\n };\n\n return (\n \n );\n};\n\nexport default ManageScheduleDownloadGrid;\n","import React, { useState, useEffect } from 'react';\n\nimport { Modal } from 'antd';\nimport { useMedia } from 'react-media';\n\nimport { WithLoading } from 'common/components';\n\nimport ManageScheduleDownloadLayout from './ManageScheduleDownloadLayout';\nimport ManageScheduleDownloadToolbar from './ManageScheduleDownloadToolbar';\nimport ManageScheduleDownloadGrid from './ManageScheduleDownloadGrid';\n\nconst ManageScheduleDownloadModal = (props) => {\n const { visible, folderId, onCancel } = props;\n\n const [selectedSchedule, setSelectedSchedule] = useState(null);\n\n const isSmallScreen = useMedia({ query: '(max-width: 1440px)' });\n\n const resetState = () => {\n setSelectedSchedule(null);\n };\n\n useEffect(() => {\n resetState();\n }, [visible]);\n\n return (\n \n \n \n \n \n \n \n
\n );\n};\n\nexport default ManageScheduleDownloadModal;\n","import React, { useState } from 'react';\n\nimport { FieldTimeOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport ManageScheduleDownloadModal from 'common/components/modal-manage-schedule-download/ManageScheduleDownloadModal';\n\nimport Messages from 'i18n/messages/home';\n\nconst ManageScheduleDownload = (props) => {\n const { selectedFolder } = props;\n const [manageScheduleModalVisible, setManageScheduleModalVisible] =\n useState(false);\n\n const onClick = () => {\n setManageScheduleModalVisible(true);\n };\n\n const closeDownloadModalVisible = () => {\n setManageScheduleModalVisible(false);\n };\n\n const folderId = selectedFolder?.id;\n const disabled = !folderId || !selectedFolder?.hasSchedule;\n\n return (\n
\n }\n label={Messages.manageSchedule}\n onClick={onClick}\n disabled={disabled}\n />\n \n
\n );\n};\n\nexport default ManageScheduleDownload;\n","import React from 'react';\n\nimport { DoubleRightOutlined } from '@ant-design/icons';\nimport { RibbonButton } from 'common/components';\n\nimport Messages from 'i18n/messages/home';\nimport { injectIntl } from 'react-intl';\n\nconst MoveFolder = ({ selectedItems, disabled, onClick }) => {\n const isDisable = selectedItems?.length === 0 || disabled;\n\n return (\n }\n label={Messages.moveFolder}\n disabled={isDisable}\n onClick={onClick}\n />\n );\n};\n\nexport default injectIntl(MoveFolder);\n","import React, { useState, useCallback } from 'react';\n\nimport { Typography, Checkbox, Row, Col } from 'antd';\nimport { InfoCircleOutlined } from '@ant-design/icons';\n\nimport {\n StyledModal,\n FolderSelector,\n} from 'common/components';\n\nimport { apiHandler } from 'utils/api';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\nimport { useGridView } from 'hooks/useGridView';\n\nimport * as folderServices from 'services/folder';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/folder';\n\nconst { Title, Text } = Typography;\n\nconst MoveFolderModal = (props) => {\n const intl = useIntl();\n\n const {\n visible,\n closeModal,\n selectedItems,\n currentFolderId,\n onMove,\n shouldReloadPage = true,\n } = props;\n\n const [destinationFolder, setDestinationFolder] = useState(null);\n const [isMoveToRoot, setIsMoveToRoot] = useState(false);\n const [loading, setLoading] = useState(false);\n\n const reloadPage = useDispatchReloadPage();\n const { clearGridSelection } = useGridView();\n\n const disableItemHandler = useCallback(\n (destinationItem) => {\n //* loop through to check\n const disabled = selectedItems?.every((selectedItem) => {\n //* disable when destination is itself\n const isItself = selectedItem.id === destinationItem.id;\n //* or\n //* disable when destination is its child\n //* - destination hierarchy contain its id\n const isChild =\n destinationItem?.hierarchy?.indexOf(selectedItem.id + '') > -1;\n\n return isItself || isChild;\n });\n\n //* disabled when moving to root\n return disabled || isMoveToRoot;\n },\n [selectedItems, isMoveToRoot]\n );\n\n const onSelectDestinationFolder = (folder) => {\n setDestinationFolder(folder);\n };\n\n const onBreadcrumbChange = (folderId, breadcrumbList) => {\n const hierarchy =\n breadcrumbList\n .map((breadcrumbItem) => breadcrumbItem.id)\n .join('/')\n .replace('home', '') + '/';\n\n setDestinationFolder(folderId ? { id: folderId, hierarchy } : null);\n };\n\n const onChangeMoveToRoot = (e) => {\n setIsMoveToRoot(e.target.checked);\n };\n\n const onSubmit = async () => {\n const destination = !isMoveToRoot\n ? { destinationFolderId: destinationFolder?.id }\n : {};\n\n const params = {\n itemSelected: getMovedItemParams(),\n ...destination,\n isMoveRootFolder: isMoveToRoot,\n currentFolderId: currentFolderId !== 'home' ? currentFolderId : 0,\n };\n\n const successMessage = intl.formatMessage(Messages.moveFolderSuccess);\n const errorMessage = intl.formatMessage(Messages.moveFolderError);\n\n setLoading(true);\n\n apiHandler({\n service: folderServices.moveFolder,\n params,\n successMessage,\n errorMessage,\n successCallback: moveSuccessCallback(destinationFolder),\n onFinally: moveFinally,\n });\n };\n\n const cancelModal = () => {\n closeModal();\n resetState();\n };\n\n const getMovedItemParams = () => {\n return selectedItems?.reduce((accumulator, currentSelectedItem) => {\n const { id, type } = currentSelectedItem;\n const itemMoved = { id, type };\n\n //* moveToRoot allow moving folders only\n const shouldIgnoreItem = isMoveToRoot && type?.toLowerCase() !== 'folder';\n\n return shouldIgnoreItem ? accumulator : [...accumulator, itemMoved];\n }, []);\n };\n\n const moveSuccessCallback = (destinationFolder) => () => {\n if (shouldReloadPage) {\n reloadPage();\n clearGridSelection();\n }\n\n cancelModal();\n\n onMove && onMove({ destinationFolder });\n };\n\n const moveFinally = () => {\n setLoading(false);\n };\n\n const resetState = () => {\n setLoading(false);\n setDestinationFolder(false);\n setIsMoveToRoot(false);\n };\n\n const selectedFolders = selectedItems.filter(\n (item) => item?.type?.toLowerCase() === 'folder'\n );\n const disableMoveToRoot =\n selectedFolders.length === 0 ||\n selectedItems?.every((item) => item?.level === 1);\n\n const disableSubmitButton =\n (!isMoveToRoot && destinationFolder?.id === 'home') ||\n (!destinationFolder && !isMoveToRoot);\n\n return (\n \n \n \n \n {intl.formatMessage(Messages.moveToRoot)}\n
\n \n \n {isMoveToRoot ? (\n \n \n {intl.formatMessage(Messages.moveToRootWarningMessage)}\n \n ) : null}\n \n \n Select Destination Folder\n
\n \n
\n \n );\n};\n\nexport default MoveFolderModal;\n","import React from 'react';\nimport { useSelector } from 'react-redux';\n\nimport { FolderOpenOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nimport gridSelector from 'common/components/grid-view/controllers/selectors';\nimport * as folderSelectors from 'pages/folders/controllers/selectors';\n\nimport { forwardTo } from 'utils/common/route';\n\nimport Messages from 'i18n/messages/home';\n\nconst OpenFolder = () => {\n const selectedItems = useSelector(\n gridSelector.makeSelectDetailCurrentITemsSelection()\n );\n\n const selectedFolder =\n selectedItems.length === 1 &&\n selectedItems[0].type.toLowerCase() === 'folder'\n ? selectedItems[0]\n : null;\n\n const { folderBreadcrumb } = useSelector(\n folderSelectors.selectFolderListByLevel()\n );\n\n const onClickOpenFolderDetail = () => {\n forwardTo(`/folder/${folderId}`);\n };\n\n const getFolderId = () => {\n //* no select anything\n if (!selectedItems.length) {\n return currentFolder?.id === 'home' ? null : currentFolder?.id;\n }\n\n if (selectedFolder)\n //* select folder\n return selectedFolder.id;\n\n //* select another item type, prevent opening\n if (selectedItems.length > 0 && !selectedFolder) return null;\n };\n\n const currentFolder = folderBreadcrumb[folderBreadcrumb?.length - 1];\n const folderId = getFolderId();\n\n return (\n }\n label={Messages.openFolder}\n onClick={onClickOpenFolderDetail}\n disabled={!folderId}\n />\n );\n};\n\nexport default OpenFolder;\n","import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { FolderAddOutlined } from '@ant-design/icons';\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport * as actions from '@redux/global/actions';\n\nimport * as companySelectors from 'pages/company/controllers/selectors';\nimport * as assetFullViewSelector from 'pages/asset-full-view/controllers/selectors';\n\nimport Messages from 'i18n/messages/home';\n\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\nimport { useCheckPermissions } from 'hooks/useCheckPermissions';\nimport { useGlobalModal } from 'hooks';\n\nconst AddFolderControl = ({ selectedItemList }) => {\n const dispatch = useDispatch();\n\n const { MODAL_NAMES, openModal } = useGlobalModal();\n\n const companyInfo = useSelector(companySelectors.setlectCompanyInfo());\n const assetFullView = useSelector(\n assetFullViewSelector.makeSelectAssetData()\n );\n\n const isMemOrAssetDetailView = companyInfo?.id || assetFullView?.id;\n\n const addToFolderClick = () => {\n if (isMemOrAssetDetailView) {\n openModal(MODAL_NAMES.ADD_ITEMS_TO_FOLDER);\n } else dispatch(actions.toggleAddToFolder());\n };\n\n const allowViewFolder = useCheckPermissions([\n { action: ABILITY_ACTION.VIEW, subject: ABILITY_SUBJECT.FOLDER },\n ]);\n\n return (\n }\n label={Messages.addFolder}\n className='button-item-dropdown'\n disabled={\n !allowViewFolder ||\n disableButton(window.location.pathname) ||\n (selectedItemList && selectedItemList.length === 0)\n }\n onClick={addToFolderClick}\n />\n );\n};\n\nconst urlFolders = [\n '/folders',\n '/folders/shared',\n '/folders/owned',\n '/favorite/favorite-folders',\n];\n\nconst disableButton = (pathname) => {\n return urlFolders.includes(pathname);\n};\n\nAddFolderControl.propTypes = {};\n\nexport default AddFolderControl;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { StarOutlined } from '@ant-design/icons';\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport { useFavorite } from 'hooks/useFavorite';\n\nimport Messages from 'i18n/messages/home';\n\nconst FavoriteControl = (props) => {\n const { type, selectedItemList, isDisabled } = props;\n\n const { callToggleFavoriteApi } = useFavorite({\n entityList: selectedItemList,\n type,\n });\n\n //* functions\n const onClickHandler = async () => {\n callToggleFavoriteApi(true);\n };\n\n return (\n }\n label={Messages.addFavorite}\n className='button-item-dropdown'\n onClick={onClickHandler}\n disabled={isDisabled}\n />\n );\n};\n\nFavoriteControl.propTypes = {\n type: PropTypes.string,\n isDisabled: PropTypes.bool,\n};\n\nexport default FavoriteControl;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { StarFilled } from '@ant-design/icons';\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport { useFavorite } from 'hooks/useFavorite';\n\nimport Messages from 'i18n/messages/home';\n\nconst UnfavoriteControl = (props) => {\n const { type, selectedItemList, isFavoriteView } = props;\n\n const { callToggleFavoriteApi } = useFavorite({\n entityList: selectedItemList,\n type,\n isFavoriteView,\n });\n\n //* variables\n const isDisabled = selectedItemList?.length === 0;\n\n //* functions\n const onClickHandler = async () => {\n callToggleFavoriteApi(false);\n };\n\n return (\n }\n label={Messages.removeFavorite}\n className='button-item-dropdown'\n onClick={onClickHandler}\n disabled={isDisabled}\n />\n );\n};\n\nUnfavoriteControl.propTypes = {\n type: PropTypes.string,\n};\n\nexport default UnfavoriteControl;\n","import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { SisternodeOutlined } from '@ant-design/icons';\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport * as actions from '@redux/global/actions';\n\nimport Messages from 'i18n/messages/home';\n\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\n\nconst AddFolderToNewAPL = () => {\n const dispatch = useDispatch();\n\n const addToAPLClick = () => {\n dispatch(actions.toggleAddFolderToAPL());\n };\n\n const folderList = useSelector(\n selectorsGridView.makeSelectDetailCurrentITemsSelection()\n );\n\n const isFolderHaveProduct =\n folderList.filter((item) => item.productCount > 0).length === 0;\n\n return (\n }\n label={Messages.addAPL}\n className='button-item-dropdown'\n disabled={isFolderHaveProduct}\n onClick={addToAPLClick}\n />\n );\n};\n\nexport default AddFolderToNewAPL;\n","import React from 'react';\n\nimport { SisternodeOutlined } from '@ant-design/icons';\n\nimport Messages from 'i18n/messages/home';\n\nimport {\n ButtonSmallIcon,\n ContainerButton,\n ItemButton,\n} from 'common/components';\n\nimport { useGlobalModal } from 'hooks';\n\nimport './AddProductToNewApl.less';\n\nconst AddProductToNewApl = ({ selectedItemList }) => {\n const { MODAL_NAMES, openModal } = useGlobalModal();\n\n return (\n \n \n }\n label={Messages.addProductToNewApl}\n onClick={() => openModal(MODAL_NAMES.ADD_TO_APL)}\n className='button-item-dropdown'\n disabled={selectedItemList && selectedItemList.length === 0}\n />\n \n \n );\n};\n\nexport default AddProductToNewApl;\n","import React, { useState } from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { Input, notification, Spin } from 'antd';\nimport { AppstoreAddOutlined } from '@ant-design/icons';\nimport { useIntl } from 'react-intl';\n\nimport Messages from 'i18n/messages/home';\nimport messagesProduct from 'i18n/messages/product';\n\nimport {\n Form,\n StyledModal,\n ButtonSmallIcon,\n ContainerButton,\n ItemButton,\n} from 'common/components';\n\nimport { addSearchProductsToApl } from 'services/apl';\nimport { ROUTE } from 'static/Constants';\nimport { useGetQuery } from 'hooks/useQuery';\n\nimport './AddProductToNewApl.less';\nimport { handleCreateSearchContainer } from 'pages/reporting/utils';\n\nconst AddSearchProductToNewApl = ({\n disabledFilterSearch,\n searchCategoriesEffected,\n searchText,\n filterProducts,\n queryConditions,\n}) => {\n const [visibleModal, setVisibleModal] = useState(false);\n\n return (\n <>\n \n \n }\n label={Messages.addSearchProductToNewApl}\n onClick={() => setVisibleModal(true)}\n className='button-item-dropdown'\n disabled={disabledFilterSearch}\n />\n \n \n\n {visibleModal && (\n setVisibleModal(false)}\n searchCategoriesEffected={searchCategoriesEffected}\n searchText={searchText}\n filterProducts={filterProducts}\n queryConditions={queryConditions}\n />\n )}\n \n );\n};\n\nconst layoutForm = {\n labelCol: { span: 6 },\n wrapperCol: { span: 17 },\n};\nconst ModalFormCreateApl = ({\n visibleModal,\n turnOffModal,\n searchCategoriesEffected,\n searchText,\n filterProducts,\n queryConditions,\n}) => {\n const [formInstance] = Form.useForm();\n const intl = useIntl();\n\n const [loading, setLoading] = useState(false);\n\n const { pathname } = useLocation();\n const query = useGetQuery();\n const memberId = query.get('memberId');\n\n const isMemberProductView = ROUTE.MEMBER_PRODUCTS === pathname;\n const handleSubmitForm = () => {\n formInstance.validateFields().then(() => {\n setLoading(true);\n let params = formInstance.getFieldsValue();\n params.search = { searchText: searchText };\n let filters = [];\n let arrValue = [];\n\n //* Add filter by member for member product view\n if (isMemberProductView && memberId) {\n filters.push({\n fieldName: 'ownerId',\n value: parseInt(memberId),\n filterType: 'Equal',\n });\n }\n\n if (filterProducts.indexOf('subscription') > -1) {\n filters.push({\n fieldName: 'subscription',\n value: true,\n filterType: 'Equal',\n });\n }\n if (filterProducts.indexOf('syndication') > -1) {\n filters.push({\n fieldName: 'syndication',\n value: true,\n filterType: 'Equal',\n });\n }\n if (filterProducts.indexOf('owner') > -1) {\n filters.push({\n fieldName: 'isOwner',\n value: true,\n filterType: 'Equal',\n });\n }\n if (filterProducts.indexOf('pending') > -1) {\n filters.push({\n fieldName: 'status',\n value: 'Pending',\n filterType: 'Equal',\n });\n }\n if (\n filterProducts.indexOf('Pallet') > -1 ||\n filterProducts.indexOf('Master Case') > -1 ||\n filterProducts.indexOf('Case') > -1 ||\n filterProducts.indexOf('Inner Pack') > -1 ||\n filterProducts.indexOf('Unit') > -1\n ) {\n if (filterProducts.indexOf('Pallet') > -1) {\n arrValue.push('Pallet');\n }\n if (filterProducts.indexOf('Master Case') > -1) {\n arrValue.push('Master Case');\n }\n if (filterProducts.indexOf('Case') > -1) {\n arrValue.push('Case');\n }\n if (filterProducts.indexOf('Inner Pack') > -1) {\n arrValue.push('Inner Pack');\n }\n if (filterProducts.indexOf('Unit') > -1) {\n arrValue.push('Unit');\n }\n }\n params.filters = filters;\n\n const advancedSearch = handleCreateSearchContainer(queryConditions);\n\n params.advancedSearchContainer = advancedSearch;\n params.searchCategory = searchCategoriesEffected;\n\n addSearchProductsToApl(params)\n .then((resp) => {\n if (resp.isSuccess) {\n notification.success({\n message: intl.formatMessage(\n messagesProduct.addSearchProductToAplSuccess\n ),\n });\n\n turnOffModal();\n } else {\n notification.error({\n message: resp?.message,\n });\n }\n })\n .catch((error) => {\n notification.error({\n message: error,\n });\n })\n .finally(() => {\n setLoading(false);\n });\n });\n };\n\n const modalProps = {\n title: intl.formatMessage(messagesProduct.addSearchProductToAplLabel),\n accept: '.xlsx, .xls, .csv',\n destroyOnClose: true,\n visible: visibleModal,\n onCancel: turnOffModal,\n onOk: handleSubmitForm,\n okButtonProps: { loading: loading },\n cancelButtonProps: { disabled: loading },\n maskClosable: false,\n closable: !loading,\n };\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nexport default AddSearchProductToNewApl;\n","import React, { useMemo } from 'react';\nimport { Menu, Dropdown } from 'antd';\nimport { FileAddFilled } from '@ant-design/icons';\nimport Messages from 'i18n/messages/home';\n\nimport FavoriteControl from './FavoriteControl';\nimport UnfavoriteControl from './UnfavoriteControl';\nimport AddFolder from './AddFolder';\nimport AddFolderToNewAPL from './AddFolderToNewAPL';\nimport AddProductToNewApl from './AddProductToNewApl';\nimport AddSearchProductToNewApl from './AddSearchProductToNewApl';\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport userSelector from '@redux/user/selectors';\nimport { useSelector } from 'react-redux';\nimport * as selectors from 'pages/company-profile/controllers/selectors';\n\nimport { Can } from 'context/Can';\nimport { useCheckPermissions } from 'hooks/useCheckPermissions';\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\n\nimport { CanShow } from 'common/components/wrapper/show-condition';\n\nimport './Addition.less';\n\nconst Addition = ({\n type,\n selectedItemList,\n disabledFavorite,\n isDisabled,\n disabledFilterSearch,\n searchCategoriesEffected,\n searchText,\n filterProducts,\n queryConditions,\n isFavoriteView,\n}) => {\n let userInfo = useSelector(userSelector.makeSelectUserInfo());\n const memberInfo = useSelector(selectors.selectMemberProfile());\n\n const checkAllFavoriteItem = () => {\n // return true if all item is favorite\n return !selectedItemList?.some((item) => !item?.isFavorited);\n };\n\n const checkAllNotFavoriteItem = () => {\n // return true if all item is not favorite\n return !selectedItemList?.some((item) => item?.isFavorited);\n };\n\n const shouldShowRemoveFavorite =\n (!selectedItemList && memberInfo?.isFavorited) ||\n (selectedItemList?.length > 0 && checkAllFavoriteItem());\n\n const isAllItemInTheSameType = selectedItemList?.every(\n (item) => item?.type?.toLowerCase() === type?.toLowerCase()\n );\n\n const shouldDisabledAddToFavorite =\n (!selectedItemList && memberInfo?.isFavorited) ||\n selectedItemList?.length === 0 ||\n !checkAllNotFavoriteItem() ||\n disabledFavorite ||\n !isAllItemInTheSameType;\n\n const viewPermission = useMemo(() => getPermissionAddToFav(type), [type]);\n\n const hasPermissionAddToFavorite = useCheckPermissions(viewPermission);\n\n const menuOptions = (\n \n {hasPermissionAddToFavorite && (\n \n \n \n )}\n\n {hasPermissionAddToFavorite && shouldShowRemoveFavorite && (\n \n \n \n )}\n \n \n \n \n \n {type === 'folder' && (\n \n \n \n )}\n {type === 'product' && (\n \n \n \n \n \n )}\n {type === 'product' && (\n \n \n \n \n \n )}\n \n );\n\n return (\n \n }\n disabled={\n window.location.pathname === '/member-management-company' ||\n isDisabled\n }\n label={Messages.addTo}\n />\n \n );\n};\n\nconst getPermissionAddToFav = (type) => {\n if (type === 'product') {\n return [\n {\n action: ABILITY_ACTION.VIEW,\n subject: ABILITY_SUBJECT.PRODUCT,\n },\n ];\n }\n\n if (type === 'member') {\n return [\n {\n action: ABILITY_ACTION.VIEW,\n subject: ABILITY_SUBJECT.MEMBER,\n },\n ];\n }\n\n if (type === 'asset') {\n return [\n {\n action: ABILITY_ACTION.VIEW,\n subject: ABILITY_SUBJECT.ASSET,\n },\n ];\n }\n\n if (type === 'folder') {\n return [\n {\n action: ABILITY_ACTION.VIEW,\n subject: ABILITY_SUBJECT.FOLDER,\n },\n ];\n }\n\n if (type === 'reporting') {\n return [\n {\n action: ABILITY_ACTION.VIEW,\n subject: ABILITY_SUBJECT.REPORTING,\n },\n ];\n }\n\n return [];\n};\n\nexport default Addition;\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { FilterOutlined } from '@ant-design/icons';\n\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\nimport Messages from 'i18n/messages/home';\nimport ButtonSmallIcon from '../button/ButtonSmallIcon';\n\nconst OpenAdvanceFilter = ({ disabled }) => {\n const dispatch = useDispatch();\n\n const handleOpenAdvanceFilter = () => {\n dispatch(actionsGridView.updateIsOpenAdvanceSearch(true));\n };\n\n return (\n <>\n }\n label={Messages.advanceFilter}\n disabled={disabled}\n onClick={handleOpenAdvanceFilter}\n className='grid-config__button'\n />\n \n );\n};\n\nexport default OpenAdvanceFilter;\n","import React, { useEffect } from 'react';\nimport { Row, Col } from 'antd';\nimport { useSelector } from 'react-redux';\nimport { DragDropContext } from 'react-beautiful-dnd';\n\nimport QueryConditions from 'pages/reporting/components/QueryConditions';\nimport TitleSection from 'pages/reporting/components/TitleSection';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\nimport ClearQueryControl from 'pages/home/ribbon/components/controls/advanced-search/ClearQueryControl';\n\nimport { useGetDataQueryConditions } from 'hooks';\nimport HeaderEntityAttributes from '../reporting/entity-and-attributes/HeaderEntityAttributes';\nimport EntitiesAndAttributes from '../reporting/entity-and-attributes/EntitiesAndAttributes';\nimport dialogFunction from '../dialog-function/DialogFunction';\nimport {\n ADVANCED_FILTER_MODE,\n INITIAL_SEARCH_SET_CONDITION,\n} from 'pages/reporting/utils/constants';\n\nimport { isEmpty } from 'lodash';\n\nimport './NestedAdvanceSearch.less';\n\nconst NestedAdvanceSearch = (props) => {\n const pathName = window.location.pathname;\n const queryConditions = useGetDataQueryConditions(pathName);\n\n const visible = useSelector(\n selectorsGridView.makeSelectIsOpenAdvanceSearch()\n );\n\n const {\n state,\n entityType,\n onDragEnd,\n modeData,\n onDragStart,\n setModeData,\n toggleSelection,\n handleConjunction,\n addQueryCondition,\n fetchEntityAttribute,\n handleUpdateDataEntity,\n updateQueryCondition,\n handleUpdateSearchText,\n toggleSelectionInGroup,\n handleQueryDateBetween,\n handleUpdateSearchEntity,\n handleUpdateQueryCondition,\n handleRemoveQueryConditions,\n handleGetEntityAndAttributes,\n handleUpdateQueryConditionFile,\n } = props;\n\n const {\n searchText,\n dataSearch,\n propertiesData,\n dataQueryConditions,\n selectedPropertyIds,\n } = state;\n\n const showConfirmMessage = (refSearchText) => {\n dialogFunction({\n type: 'warn',\n content: (\n
\n

\n Are you sure you want to switch to \n {modeData === ADVANCED_FILTER_MODE.FLAT_DATA\n ? 'Advanced Mode'\n : 'Basic Mode'}\n ?\n

\n
\n ),\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: () => handleToggleMode(refSearchText),\n });\n };\n\n const handleToggleMode = (refSearchText) => {\n const _flat = ADVANCED_FILTER_MODE.FLAT_DATA;\n const _nested = ADVANCED_FILTER_MODE.NESTED_DATA;\n\n if (modeData === _flat) {\n updateDataChangedMode(_nested);\n } else {\n updateDataChangedMode(_flat);\n }\n\n handleUpdateSearchText('');\n refSearchText.current?.onClearSearchText();\n };\n\n const updateDataChangedMode = (mode) => {\n const entityProperties =\n window?.advancedSearch?.entityAttributes?.[entityType];\n\n setModeData(mode);\n handleUpdateDataEntity(entityProperties, mode);\n handleUpdateQueryCondition({\n ...dataQueryConditions,\n advancedFilterMode: mode,\n });\n };\n\n const initData = () => {\n const strickMode =\n queryConditions?.advancedFilterMode || ADVANCED_FILTER_MODE.FLAT_DATA;\n setModeData(strickMode);\n //suport init apl search set for ticket 8703\n if (isEmpty(queryConditions) && entityType?.toLowerCase() === 'product') {\n handleUpdateQueryCondition(INITIAL_SEARCH_SET_CONDITION);\n } else {\n handleUpdateQueryCondition(queryConditions);\n }\n };\n\n useEffect(() => {\n if (!visible) return;\n handleGetEntityAndAttributes(entityType);\n initData();\n }, [JSON.stringify(queryConditions), visible]);\n\n const hasQueryConditions = dataQueryConditions?.children?.length > 0;\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {hasQueryConditions && (\n {\n handleUpdateQueryCondition({});\n }}\n />\n )}\n \n \n \n \n \n \n \n );\n};\n\nexport default React.memo(NestedAdvanceSearch);\n","import React, { useState } from 'react';\nimport _ from 'lodash';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { StyledModal } from 'common/components';\n\nimport { useAdvanceFilter } from './hook/hook';\nimport WithLoading from '../wrapper/WithLoading';\nimport NestedAdvanceSearch from './NestedAdvanceSearch';\n\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\nimport { checkPathName } from './hook/utils';\nimport {\n updateQueryAdvance,\n updateQueryConditions,\n} from 'utils/queryCondition';\nimport { ADVANCED_FILTER_MODE } from 'pages/reporting/utils/constants';\n\nconst NestedAdvanceFilter = () => {\n const dispatch = useDispatch();\n\n const pathName = window.location.pathname;\n const entityType = checkPathName(pathName);\n\n const [modeData, setModeData] = useState(\n entityType === 'product'\n ? ADVANCED_FILTER_MODE.FLAT_DATA\n : ADVANCED_FILTER_MODE.NESTED_DATA\n );\n\n const isOpen = useSelector(selectorsGridView.makeSelectIsOpenAdvanceSearch());\n const { ...AdvancedSearchProps } = useAdvanceFilter({ modeData, entityType });\n\n const {\n state: { propertiesData, dataQueryConditions },\n handleUpdateQueryCondition,\n } = AdvancedSearchProps ?? {};\n\n const handleAdvanceFilters = () => {\n updateQueryConditions(dispatch, dataQueryConditions, pathName);\n updateQueryAdvance(dispatch, dataQueryConditions, pathName);\n dispatch(actionsGridView.updateIsOpenAdvanceSearch(false));\n dispatch(actionsGridView.myQueryDoubleClick(true));\n dispatch(actionsGridView.checkQueryCondition(true));\n dispatch(actionsGridView.updateIsOpenAdvanceSearch(false));\n };\n\n const handleCancel = () => {\n handleUpdateQueryCondition({});\n dispatch(actionsGridView.updateIsOpenAdvanceSearch(false));\n };\n const isLoading = propertiesData?.length > 0;\n const hasOverloadFile =\n dataQueryConditions?.children?.length > 0 &&\n !_.isEmpty(\n dataQueryConditions?.children?.find(\n (val) => val?.acceptableValueTemp?.length > 100000\n )\n );\n\n return (\n <>\n handleCancel()}\n width='80vw'\n bodyStyle={{ height: '80vh', padding: 0 }}\n okButtonProps={{ disabled: hasOverloadFile }}\n >\n \n \n \n \n \n );\n};\n\nexport default NestedAdvanceFilter;\n","import React from 'react';\n\nimport { Menu, Dropdown } from 'antd';\nimport { SettingOutlined } from '@ant-design/icons';\n\nimport SearchFolder from './SearchFolder';\nimport DeleteFolder from './DeleteFolder';\n\nimport Messages from 'i18n/messages/home';\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nimport { Can } from 'context/Can';\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\nimport OpenAdvanceFilter from 'common/components/nested-advance-Search/OpenAdvanceFilter';\nimport NestedAdvanceFilter from 'common/components/nested-advance-Search/NestedAdvanceFilter';\n\nconst AdvanceStack = (props) => {\n const { isDisabled, disabledAdvanceFilter, selectedItemList } = props;\n // check section disabled\n const checkSectionDisabled = () => {\n const hasSelectedItem = selectedItemList?.length > 0;\n\n const selectedFolder = selectedItemList?.filter((selectedItem) => {\n return selectedItem?.type === 'Folder';\n });\n\n const hasSelectedFolder = selectedFolder?.length > 0;\n\n return !hasSelectedItem || hasSelectedFolder;\n };\n\n const menuOptionProps = {\n selectedItemList,\n isSectionDisabled: checkSectionDisabled(),\n };\n\n const renderMenuOptions = (menuOptionProps) => (\n {\n // if (key === 'advancedSearch') {\n // dispatch()\n // }\n }}\n >\n {/* \n \n */}\n \n \n {(allowed) => (\n \n )}\n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n\n return (\n <>\n \n }\n disabled={isDisabled}\n label={Messages.advanceStack}\n />\n \n \n \n );\n};\n\nAdvanceStack.propTypes = {};\n\nexport default AdvanceStack;\n","import React from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport { LogoutOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport Messages from 'i18n/messages/home';\n\nimport useCloseDetail from 'hooks/useCloseDetail';\n\nimport { DISABLED_CLOSE_DETAIL_BUTTON } from 'static/Constants';\n\nconst BackControl = (props) => {\n const { isDisabled, closeDetailCallback, onClick } = props;\n\n const { goBack } = useCloseDetail();\n\n const handleClick = () => {\n if (onClick) return onClick(goBack);\n\n goBack();\n closeDetailCallback && closeDetailCallback();\n };\n\n return (\n }\n label={Messages.backText}\n onClick={handleClick}\n disabled={\n DISABLED_CLOSE_DETAIL_BUTTON.includes(window.location.pathname) ||\n isDisabled\n }\n />\n );\n};\n\nBackControl.propTypes = {\n /**\n * to detect type of ribbon view\n */\n ribbonType: PropTypes.oneOf([\n 'members',\n 'assets',\n 'reportings',\n 'workflows',\n 'products',\n ]),\n};\n\nexport default BackControl;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { FolderOutlined } from '@ant-design/icons';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\nimport { dialogFunction } from 'common/components';\n\nimport * as folderService from 'services/folder';\n\nimport Messages from 'i18n/messages/home';\nimport { injectIntl } from 'react-intl';\n\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\nimport { useCheckPermissions } from 'hooks/useCheckPermissions';\n\nconst DeleteFolderControl = (props) => {\n const { intl, selectedItemList, isSectionDisabled } = props;\n\n const clickDeleteHandler = () => {\n showConfirmDialog();\n };\n\n const showConfirmDialog = () => {\n dialogFunction({\n type: 'warn',\n content: intl.formatMessage(Messages.deleteFromFoldersConfirm),\n onOk: callApiDelete,\n });\n };\n\n const callApiDelete = () => {\n const itemList = getItemList(selectedItemList);\n\n folderService\n .deleteInAllFolders(itemList)\n .then((response) => {\n const { isSuccess } = response;\n if (isSuccess) {\n showSuccessMessageDialog();\n } else {\n callApiErrorHandler();\n }\n })\n .catch(() => {\n callApiErrorHandler();\n });\n };\n\n const getItemList = (itemList) => {\n return itemList?.map((item) => {\n const { id, type } = item;\n return {\n id,\n type,\n };\n });\n };\n\n const showSuccessMessageDialog = () => {\n dialogFunction({\n type: 'success',\n content: intl.formatMessage(Messages.deleteFromFoldersSuccess),\n cancelButtonProps: {\n style: { display: 'none' },\n },\n });\n };\n\n const callApiErrorHandler = () => {\n dialogFunction({\n type: 'error',\n content: intl.formatMessage(Messages.deleteFromFoldersError),\n cancelButtonProps: {\n style: { display: 'none' },\n },\n });\n };\n\n const EDIT_FOLDERS = [\n { action: ABILITY_ACTION.EDIT, subject: ABILITY_SUBJECT.FOLDER },\n ];\n\n const disabled = !useCheckPermissions(EDIT_FOLDERS) || isSectionDisabled;\n\n return (\n }\n label={Messages.deleteFromFolders}\n className='button-item-dropdown'\n onClick={clickDeleteHandler}\n disabled={disabled}\n />\n );\n};\n\nDeleteFolderControl.propTypes = {\n /**\n * Current selected items\n */\n selectedItemList: PropTypes.arrayOf(PropTypes.object),\n /**\n * Disable state of ribbon section\n */\n isSectionDisabled: PropTypes.bool,\n};\n\nexport default injectIntl(DeleteFolderControl);\n","import React from 'react';\nimport { useSelector } from 'react-redux';\nimport PropTypes from 'prop-types';\nimport { LayoutOutlined } from '@ant-design/icons';\nimport Messages from 'i18n/messages/home';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\nimport * as selectorsGlobal from '@redux/global/selectors';\n\nimport './DetailView.less';\n\nconst DetailControl = ({ detailClick, disabledBtn, isDetailShow }) => {\n const isDisplayShowPreviewAcceptedEula = useSelector(\n selectorsGlobal.selectIsDisplayShowPreviewAcceptedEula()\n );\n\n const handleClickDetail = () => {\n detailClick();\n };\n\n return (\n }\n label={Messages.toggleDetail}\n onClick={handleClickDetail}\n toggle={isDetailShow}\n disabled={disabledBtn || isDisplayShowPreviewAcceptedEula}\n />\n );\n};\n\nDetailControl.propTypes = {\n detailClick: PropTypes.func,\n};\n\nexport default DetailControl;\n","import React from 'react';\n\nimport reactCSS from 'reactcss';\n\nimport {\n FolderGridThumbnail,\n FolderGridTile,\n} from 'pages/folders/shared/components';\n\nconst FolderGridTileComponent = (props) => {\n return (\n
\n \n
\n );\n};\n\nconst GRID_ITEM_RENDER = {\n thumbnails: {\n folder: FolderGridThumbnail,\n },\n tilesview: {\n folder: FolderGridTileComponent,\n },\n};\n\nconst styles = reactCSS({\n default: {\n gridItem: {\n wrapper: { cursor: 'pointer' },\n },\n folder: {\n tile: {\n wrapper: {\n display: 'inline-block',\n margin: '12px 0 0 12px ',\n border: '1px solid grey',\n },\n },\n },\n },\n});\n\nconst GridItem = (props) => {\n const { searchType, viewType, handleDoubleClick, ...gridItemProps } = props;\n const GridItemComponent = GRID_ITEM_RENDER[viewType][searchType];\n\n const newGridItemProps = {\n ...gridItemProps,\n disableEvent: true,\n };\n\n return (\n handleDoubleClick(gridItemProps)}\n >\n ;\n \n );\n};\n\nexport { GridItem };\n","import React from 'react';\n\nimport { GridItem } from './GridItem';\nimport { Skeleton, Empty } from 'antd';\n\nimport reactCSS from 'reactcss';\nimport { RIBBON_TYPES, ENTITY_TYPE } from 'static/Constants';\n\nconst styles = reactCSS({\n default: {\n grid: {\n width: '100%',\n height: '100%',\n display: 'flex',\n flexFlow: 'wrap',\n alignContent: 'flex-start',\n },\n gridWrap: {\n width: '100%',\n height: '100%',\n },\n },\n});\n\nconst Grid = (props) => {\n const {\n items,\n isLoading,\n searchType = ENTITY_TYPE.FOLDER,\n viewType = RIBBON_TYPES.THUMBNAILS,\n handleDoubleClick,\n } = props;\n\n return (\n
\n {items?.length === 0 ? (\n \n ) : (\n \n
\n {items?.map((item, index) => {\n item.thumbnail = item.thumb;\n item.isOwner = true;\n\n return (\n \n );\n })}\n
\n
\n )}\n
\n );\n};\n\nexport default Grid;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Radio } from 'antd';\nimport { PictureOutlined, AlignLeftOutlined } from '@ant-design/icons';\nimport { RIBBON_TYPES } from 'static/Constants';\n\nimport reactCSS from 'reactcss';\n\nconst styles = reactCSS({\n default: {\n button: {\n height: '37px',\n fontSize: '18px',\n lineHeight: '37px',\n padding: '0 12px',\n },\n },\n});\n\nconst FindEntityInFolderResultToolbar = (props) => {\n const { typeViewHook } = props;\n const [currentView, setCurrentView] = typeViewHook;\n\n const onChangeView = (e) => {\n setCurrentView(e.target.value);\n };\n\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nFindEntityInFolderResultToolbar.propTypes = {\n typeViewHook: PropTypes.array,\n};\n\nexport default FindEntityInFolderResultToolbar;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Row, Col, Typography, Pagination } from 'antd';\nimport Messages from 'i18n/messages/home';\nimport { FormattedMessage } from 'react-intl';\n\nconst { Text } = Typography;\n\nconst FindEntityInFolderResultFooter = (props) => {\n const {\n totalResult,\n pageSize,\n pageIndex,\n onChangePage,\n classNamePrefix,\n onShowSizeChange,\n } = props;\n\n return (\n \n \n \n \n \n \n :\n  \n {totalResult}\n \n \n \n );\n};\n\nFindEntityInFolderResultFooter.propTypes = {\n totalResult: PropTypes.number,\n pageSize: PropTypes.number,\n pageIndex: PropTypes.number,\n onChangePage: PropTypes.func,\n classNamePrefix: PropTypes.string,\n onShowSizeChange: PropTypes.func,\n};\n\nFindEntityInFolderResultFooter.defaultProps = {\n onChangePage: () => null,\n onShowSizeChange: () => null,\n};\n\nexport default FindEntityInFolderResultFooter;\n","import React, { useState, useEffect } from 'react';\n\nimport Grid from '../components/Grid';\n\nimport { StyledModal } from 'common/components';\n\nimport * as folderServices from 'services/folder';\n\nimport { RIBBON_TYPES } from 'static/Constants';\n\nimport FindEntityInFolderResultToolbar from './FindEntityInFolderResultToolbar';\nimport FindEntityInFolderResultFooter from './FindEntityInFolderResultFooter';\n\nimport { sleep } from 'utils/delay';\nimport { forwardTo } from 'utils/common/route';\n\nconst FindInAllFolderModal = (props) => {\n const { showResultHook, selectedItemList } = props;\n\n const [visible, setVisible] = showResultHook;\n const typeViewHook = useState(RIBBON_TYPES.THUMBNAILS);\n const [currentView, setCurrentView] = typeViewHook;\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(false);\n const [result, setResult] = useState([]);\n const [totalResult, setTotalResult] = useState(0);\n const [pageIndex, setPageIndex] = useState(1);\n const [pageSize, setPageSize] = useState(20);\n\n const onCloseDialog = () => {\n setVisible(false);\n };\n\n const onChangePage = (newPage) => {\n setPageIndex(newPage);\n };\n\n const onShowSizeChange = (current, size) => {\n setPageSize(size);\n };\n\n const callApiFindEntityInFolder = () => {\n const itemList = generateEntityList();\n const params = {\n itemList,\n pageSize,\n pageIndex,\n };\n\n setLoading(true);\n\n folderServices\n .findInAllFolders(params)\n .then((response) => {\n const { isSuccess, data } = response;\n if (isSuccess) {\n const procGridData = data?.gridData?.map((dataItem) => ({\n ...dataItem,\n type: 'folder',\n }));\n setResult(procGridData);\n setTotalResult(data?.paging?.totalRecord);\n } else {\n callApiFindEntityInFolderErrorHandler();\n }\n })\n .catch((err) => callApiFindEntityInFolderErrorHandler())\n .finally(() => setLoading(false));\n };\n\n const generateEntityList = () => {\n return selectedItemList.map((item) => {\n const { id, type } = item;\n return {\n id,\n type,\n };\n });\n };\n\n const callApiFindEntityInFolderErrorHandler = () => {\n setError(true);\n };\n\n const resetModalState = () => {\n setResult([]);\n setPageIndex(1);\n setCurrentView(RIBBON_TYPES.THUMBNAILS);\n setLoading(true);\n setTotalResult(0);\n setError(false);\n };\n\n const handleDoubleClick = (gridItemProps) => {\n const folderId = gridItemProps?.dataDetail?.id;\n if (!folderId) return;\n\n forwardTo(`/folder/${folderId}`);\n onCloseDialog();\n };\n\n useEffect(() => {\n if (visible) {\n callApiFindEntityInFolder();\n } else {\n resetModalState();\n }\n // eslint-disable-next-line\n }, [visible, pageIndex, pageSize]);\n\n useEffect(() => {\n const onChangeViewType = async () => {\n setLoading(true);\n await sleep(500);\n setLoading(false);\n };\n\n onChangeViewType();\n }, [currentView]);\n\n const modalConfig = {\n visible,\n destroyOnClose: true,\n title: ,\n footer: (\n \n ),\n centered: true,\n width: 1019,\n style: {\n overflow: 'hidden',\n },\n bodyStyle: {\n height: '80vh',\n },\n onCancel: onCloseDialog,\n };\n\n return (\n \n \n \n );\n};\n\nexport default FindInAllFolderModal;\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { FolderOpenOutlined } from '@ant-design/icons';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n// import { FindEntityInFolderResultModal } from './../../index';\n\nimport Messages from 'i18n/messages/home';\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\nimport { useCheckPermissions } from 'hooks/useCheckPermissions';\nimport FindInAllFolderModal from 'common/components/modal/grid-view-modal/find-in-all-folder-modal/FindInAllFolderModal';\n\nconst ViewFolderControl = (props) => {\n const { isSectionDisabled, selectedItemList } = props;\n\n //* state\n const showResultHook = useState(false);\n const [, setShowResult] = showResultHook;\n //* function\n const clickSearchHandler = () => {\n showFindResultDialog();\n };\n\n const showFindResultDialog = () => {\n setShowResult(true);\n };\n\n const VIEW_FOLDERS = [\n { action: ABILITY_ACTION.VIEW, subject: ABILITY_SUBJECT.FOLDER },\n ];\n\n const disabled = !useCheckPermissions(VIEW_FOLDERS) || isSectionDisabled;\n\n return (\n <>\n }\n label={Messages.searchFolders}\n className='button-item-dropdown'\n disabled={disabled}\n onClick={clickSearchHandler}\n />\n {/* */}\n\n \n \n );\n};\n\nViewFolderControl.propTypes = {\n selectedItemList: PropTypes.array,\n isSectionDisabled: PropTypes.bool,\n};\n\nexport default ViewFolderControl;\n","import { useState, useEffect, useCallback } from 'react';\n\nimport { useQuery } from '@tanstack/react-query';\nimport { Form, message } from 'antd';\n\nimport { useAsync, useCheckPermissions, useGlobalModal } from 'hooks';\nimport { useSelector, useDispatch } from 'react-redux';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useGetDataQueryConditions } from 'hooks';\nimport { updateIdQuery } from 'utils/queryCondition';\nimport { useDefaultSearchText } from 'pages/home/utils';\n\nimport { RIBBON_TYPES } from 'static/Constants';\nimport { saveQuery } from 'services/query';\n\nimport { selectRibbonType } from '@redux/ribbon/selectors';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\n\nimport { handleCreateSearchContainer } from 'pages/reporting/utils';\nimport { getGridName } from 'utils/getGridName';\nimport { filterParamsColumns } from 'pages/home/ribbon/components/controls/home/grid-query/utils';\nimport { deleteColumnCheckbox } from './utils';\n\nimport {\n getQueryGridView,\n getQueryDetailPane,\n getAllMemberRoles,\n} from 'services/query';\nimport { getMemberList } from 'services/members';\n\nimport { PERMISSION_MANAGE_CURATED_QUERY } from 'static/Permission';\nimport messagesGridView from 'i18n/messages/gridView';\n\nconst useSetDefaultWidth = (form, columns, selectedFieldName) => {\n const valueColumns = deleteColumnCheckbox(columns);\n\n useEffect(() => {\n if (valueColumns.length === 0) return;\n\n const findColumn = valueColumns.find(\n (col) => col.fieldName === selectedFieldName\n );\n const width = findColumn?.width ?? 0;\n\n form.setFieldsValue({ width });\n }, [form, valueColumns, selectedFieldName]);\n};\n\nconst useChangeWidth = (form, width) => {\n useEffect(() => {\n form.setFieldsValue({ width });\n }, [form, width]);\n};\n\nconst useGetSavedConfig = (gridName, isMounted) => {\n const [data, setData] = useState();\n\n useEffect(() => {\n const params = {\n pageIndex: 1,\n pageSize: 10,\n sort: [\n {\n fieldName: 'lastModified',\n isAscending: false,\n },\n ],\n gridName,\n };\n const delayFetchGrid = setTimeout(() => {\n getQueryGridView(params).then((res) => {\n setData(res.data);\n });\n }, 1000);\n\n return () => clearTimeout(delayFetchGrid);\n }, [gridName, isMounted]);\n\n return data;\n};\n\nconst DEFAULT_PAGE_SIZE = 9999;\n\nconst useGetMembers = ({ valuesFilter, enabled }) => {\n const [members, setMembers] = useState([]);\n\n useEffect(() => {\n if (!enabled) return;\n\n const params = {\n type: 'GET_MEMBER_LIST',\n pageNumber: 1,\n pageSize: DEFAULT_PAGE_SIZE,\n sort: [],\n filters: [\n {\n fieldName: 'id',\n values: valuesFilter,\n },\n ],\n };\n\n getMemberList(params).then((resp) => {\n setMembers(resp.gridData);\n });\n }, [enabled, valuesFilter]);\n\n return members;\n};\n\nconst useGetCuratedQueryDetail = ({ curatedQueryId, enabled }) => {\n const { data, run } = useAsync();\n\n useEffect(() => {\n if (!enabled) return;\n\n run(getQueryDetailPane({ id: curatedQueryId }));\n }, [curatedQueryId, enabled, run]);\n\n const refetchGetCuratedQueryDetail = useCallback(() => {\n run(getQueryDetailPane({ id: curatedQueryId }));\n }, [curatedQueryId, run]);\n\n return {\n curatedQueryData: data ?? {},\n refetchGetCuratedQueryDetail,\n };\n};\n\nconst getAllMemberRolesQueryKey = () => {\n return ['get-all-member-role'];\n};\n\nconst useGetAllMemberRoles = () => {\n const hasPermissionManageCuratedQuery = useCheckPermissions(\n PERMISSION_MANAGE_CURATED_QUERY\n );\n\n const { data, ...restData } = useQuery({\n queryKey: getAllMemberRolesQueryKey(),\n queryFn: async () => {\n const response = await getAllMemberRoles();\n\n return response?.data;\n },\n enabled: hasPermissionManageCuratedQuery,\n });\n\n return {\n memberRoles: data?.memberRoles ?? [],\n ...restData,\n };\n};\n\nconst useCreateQueryForm = () => {\n const [form] = Form.useForm();\n const intl = useIntl();\n const dispatch = useDispatch();\n\n // const [visible, setVisible] = useState(false);\n const [selectedMembers, setSelectedMembers] = useState([]);\n const [toggleCuratedQuery, setCuratedQuery] = useState(false);\n const [shareType, setShareType] = useState('MemberRole');\n\n const { MODAL_NAMES, closeModal, checkModalVisible } = useGlobalModal();\n const visible = checkModalVisible(MODAL_NAMES.CREATE_QUERY);\n\n const [\n { status: statusCreate, data: dataCreate },\n createConfig,\n setDefaultState,\n ] = useMutation(saveQuery);\n const { getDefaultSearchText, getDefaultPrimaryFieldsOnly } =\n useDefaultSearchText();\n\n const { memberRoles } = useGetAllMemberRoles();\n\n const { chosenColumns } = useSelector(\n selectorsGridView.makeSelectGridConfig()\n );\n const queryConditions = useGetDataQueryConditions(window.location.pathname);\n const ribbonTypes = useSelector(selectRibbonType());\n const gridName = getGridName(window.location.pathname);\n const searchText = getDefaultSearchText(window.location.pathname);\n const primaryFieldsOnly = getDefaultPrimaryFieldsOnly(\n window.location.pathname\n );\n\n const searchCategory = useSelector(\n selectorsGridView.makeSelectSearchCategoriesList()\n );\n\n useEffect(() => {\n form.setFieldsValue({ gridName });\n }, [form, gridName]);\n\n useEffect(() => {\n form.resetFields();\n setSelectedMembers([]);\n setCuratedQuery(false);\n setShareType('MemberRole');\n }, [form, visible]);\n\n useEffect(() => {\n if (statusCreate === 'success') {\n message.success(intl.formatMessage(messagesGridView.createConfigSuccess));\n\n updateIdQuery(dispatch, dataCreate.id, window.location.pathname);\n }\n\n if (statusCreate === 'error') {\n message.error(intl.formatMessage(messagesGridView.createConfigError));\n }\n\n form.resetFields();\n closeModal(MODAL_NAMES.CREATE_QUERY);\n setDefaultState();\n }, [dispatch, form, gridName, intl, statusCreate]);\n\n const handleCreateConfig = async () => {\n const { isDefault, isCuratedQuery, dateActive, ...values } =\n await form.validateFields();\n\n const advancedSearchContainer =\n handleCreateSearchContainer(queryConditions);\n\n let params = {\n ...values,\n gridName,\n };\n\n // Add params curated query\n if (isCuratedQuery) {\n const { curatedQueryShareType, curatedQueryShareToMemberRoleId } = values;\n\n params = { ...params, isCuratedQuery };\n\n if (curatedQueryShareType === 'MemberRole') {\n if (curatedQueryShareToMemberRoleId) {\n params = {\n ...params,\n curatedQueryShareToMemberRoleId,\n curatedQueryShareToMemberType:\n memberRoles.find(\n (role) => role.memberRoleId === curatedQueryShareToMemberRoleId\n )?.memberRoleName ?? null,\n };\n }\n params = {\n ...params,\n curatedQueryShareType,\n curatedQueryShareToMembers: [],\n };\n }\n\n if (curatedQueryShareType === 'SpecificMembers') {\n params = {\n ...params,\n curatedQueryShareType,\n curatedQueryShareToMembers: selectedMembers.map(\n (member) => member.id\n ),\n };\n }\n\n if (curatedQueryShareType === 'AllMember') {\n params = {\n ...params,\n curatedQueryShareType,\n curatedQueryShareToMemberType: null,\n curatedQueryShareToMembers: [],\n };\n }\n\n if (dateActive) {\n params = {\n ...params,\n effectedDate: dateActive[0].toISOString(),\n expirationDate: dateActive[1].toISOString(),\n };\n } else {\n params = {\n ...params,\n effectedDate: null,\n expirationDate: null,\n };\n }\n }\n\n let jsonConfig;\n let downloadJsonFormat;\n if (ribbonTypes === RIBBON_TYPES.DETAILSVIEW) {\n jsonConfig = JSON.stringify({\n columns: filterParamsColumns(chosenColumns),\n queryConditions: queryConditions,\n ribbonTypes: ribbonTypes,\n urlForwardTo: window.location.pathname,\n searchText,\n 'search.searchText': searchText,\n primaryFieldsOnly,\n 'search.primaryFieldsOnly': primaryFieldsOnly,\n });\n } else {\n jsonConfig = JSON.stringify({\n queryConditions: queryConditions,\n ribbonTypes: ribbonTypes,\n urlForwardTo: window.location.pathname,\n searchText,\n 'search.searchText': searchText,\n primaryFieldsOnly,\n 'search.primaryFieldsOnly': primaryFieldsOnly,\n });\n }\n downloadJsonFormat = JSON.stringify({\n advancedSearchContainer,\n search: {\n searchText,\n primaryFieldsOnly,\n },\n isFavoriteRoute: false,\n fromDate: null,\n searchCategory,\n filters: [],\n pageSize: 20,\n pageIndex: 1,\n });\n params = Object.assign(params, {\n query: jsonConfig,\n downloadJsonFormat: downloadJsonFormat,\n });\n\n createConfig(params);\n closeModal(MODAL_NAMES.CREATE_QUERY);\n };\n return {\n toggleCuratedQuery,\n shareType,\n setShareType,\n handleCreateConfig,\n form,\n selectedMembers,\n setSelectedMembers,\n setCuratedQuery,\n gridName,\n memberRoles,\n statusCreate,\n };\n};\n\nexport {\n useSetDefaultWidth,\n useChangeWidth,\n useGetSavedConfig,\n useGetMembers,\n useGetCuratedQueryDetail,\n useGetAllMemberRoles,\n useCreateQueryForm,\n};\n","import { formatMDY } from 'utils/formatDate';\n\nconst filterParamsColumns = (columns) => {\n // first checkbox element hasn't fieldName\n const removedCheckboxColumns = columns.slice(2);\n let result = [];\n\n // check second grid folder grid is Icon\n if (removedCheckboxColumns[0]?.field === 'type') {\n const fieldNameColumns = removedCheckboxColumns\n .slice(1)\n .map((c) => ({ fieldName: c.fieldName, width: c.width }));\n result = fieldNameColumns;\n } else {\n result = removedCheckboxColumns.map((c) => ({\n fieldName: c.fieldName,\n width: c.width,\n }));\n }\n\n return result;\n};\n\nconst getStringFilteredColumns = (columns) => {\n const removedCheckboxColumns = columns.slice(2);\n let result = [];\n\n // check second grid folder grid is Icon\n if (removedCheckboxColumns[0]?.field === 'type') {\n const fieldNameColumns = removedCheckboxColumns\n .slice(1)\n .map((c) => c.fieldName);\n result = fieldNameColumns;\n } else {\n result = removedCheckboxColumns.map((c) => c.fieldName);\n }\n\n return result.join();\n};\n\nconst getListFieldName = (columns) => {\n // first checkbox element hasn't fieldName\n const removedCheckboxColumns = columns.slice(2);\n let result = [];\n\n // check first removedCheckboxColumns type is column (Icon)\n if (removedCheckboxColumns[0]?.field === 'type') {\n const fieldNameColumns = removedCheckboxColumns\n .slice(1)\n .map((c) => c.fieldName);\n result = ['type', ...fieldNameColumns];\n return result;\n }\n\n return columns.slice(1).map((c) => c.fieldName);\n};\n\nconst deleteColumnCheckbox = (columns) => {\n const removedCheckboxColumns = columns.slice(2);\n\n if (removedCheckboxColumns[0]?.field === 'type') {\n return columns.slice(3);\n }\n\n return removedCheckboxColumns;\n};\n\nconst defaultColumns = [\n {\n checkboxSelection: true,\n field: '',\n filter: false,\n suppressMenu: true,\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n displayName: 'Query Name',\n fieldName: 'name',\n fieldNameCamelCase: 'name',\n resizable: true,\n suppressMenu: true,\n width: 250,\n minWidth: 200,\n },\n {\n dataType: 'string',\n displayName: 'Description',\n fieldName: 'Description',\n fieldNameCamelCase: 'description',\n allowFilter: true,\n allowSort: true,\n suppressMenu: true,\n minWidth: 200,\n flex: 1,\n },\n {\n dataType: 'datetime',\n displayName: 'Created',\n fieldName: 'Created',\n fieldNameCamelCase: 'created',\n allowFilter: true,\n allowSort: true,\n suppressMenu: true,\n width: 150,\n minWidth: 150,\n cellRenderer: ({ value }) => {\n return formatMDY(value);\n },\n },\n {\n dataType: 'boolean',\n displayName: 'Editable',\n fieldName: 'Editable',\n fieldNameCamelCase: 'editable',\n allowFilter: true,\n allowSort: true,\n width: 120,\n minWidth: 120,\n suppressMenu: true,\n },\n {\n dataType: 'string',\n displayName: 'Owned By',\n fieldName: 'OwnerFullName',\n fieldNameCamelCase: 'ownerFullName',\n allowFilter: true,\n allowSort: true,\n width: 200,\n minWidth: 150,\n suppressMenu: true,\n },\n {\n dataType: 'boolean',\n displayName: 'Shareable',\n fieldName: 'Shareable',\n fieldNameCamelCase: 'shareable',\n allowFilter: true,\n allowSort: true,\n width: 100,\n suppressMenu: true,\n },\n {\n resizable: true,\n dataType: 'string',\n displayName: 'Shared By',\n fieldName: 'sharedByName',\n fieldNameCamelCase: 'sharedByName',\n width: 150,\n minWidth: 150,\n suppressMenu: true,\n },\n];\n\nconst isDefaultFieldColumn = {\n allowFilter: false,\n allowSort: false,\n displayName: 'Active',\n fieldName: 'active',\n fieldNameCamelCase: 'active',\n resizable: true,\n width: 100,\n suppressMenu: true,\n};\n\nconst shareFieldColumn = {\n fieldNameCamelCase: '',\n resizable: true,\n width: 350,\n suppressMenu: true,\n};\n\nconst actionFieldColumn = [\n {\n key: 4,\n field: '',\n resizable: true,\n width: 150,\n menuTabs: [],\n },\n];\n\nconst getNewDefaultColumns = (listFieldNames, allColumns, chosenColumns) => {\n const removedCheckboxColumns = allColumns.slice(2);\n\n let defaultColumns = listFieldNames.reduce((result, fieldName) => {\n const oldColumn = chosenColumns.find((col) => col.fieldName === fieldName);\n if (oldColumn) {\n result.push(oldColumn);\n } else {\n const newColumn = allColumns.find((col) => col.fieldName === fieldName);\n result.push(newColumn);\n }\n\n return result;\n }, []);\n\n if (removedCheckboxColumns[0]?.field === 'type') {\n defaultColumns = [...allColumns.slice(0, 3), ...defaultColumns];\n } else {\n defaultColumns = [...allColumns.slice(0, 2), ...defaultColumns];\n }\n return defaultColumns ?? [];\n};\n\nconst getColumnsAfterChangeWidth = (fieldName, width, chosenColumns) => {\n const defaultColumns = chosenColumns.map((col) => {\n if (col.fieldName === fieldName) {\n return { ...col, width };\n }\n return col;\n });\n\n return defaultColumns;\n};\n\nconst getDefaultConfig = (columns) => {\n const removedCheckboxColumns =\n columns[2]?.field === 'type' ? columns.slice(3) : columns.slice(2);\n\n return removedCheckboxColumns.map((col) => ({\n fieldName: col.fieldName,\n width: col.width,\n }));\n};\n\nconst filteredColumns = ['MemberName', 'IxOneId', 'CompanyBrief'];\n\nconst filterColumnsGrid = (columns) => {\n let result = [];\n\n if (columns?.length > 0) {\n columns.forEach((column) => {\n if (filteredColumns.includes(column.fieldName)) {\n if (column.fieldName === 'MemberName') {\n result.push({\n ...column,\n flex: 1,\n });\n }\n\n if (column.fieldName === 'IxOneId') {\n result.push({\n ...column,\n width: 150,\n });\n }\n\n if (column.fieldName === 'CompanyBrief') {\n result.push({\n ...column,\n width: 150,\n });\n }\n }\n });\n\n result = [columns[0], ...result];\n }\n\n return result;\n};\n\nconst filterSelectedMembers = (members, selectedIds, selectedMembers) => {\n let result = [];\n let existingIds = selectedMembers.map((member) => member.id);\n\n members.forEach((member) => {\n // prevent add same member in array\n if (selectedIds.includes(member.id) && !existingIds.includes(member.id)) {\n result.push(member);\n }\n });\n\n return result;\n};\n\nexport {\n filterParamsColumns,\n getStringFilteredColumns,\n defaultColumns,\n isDefaultFieldColumn,\n shareFieldColumn,\n actionFieldColumn,\n getListFieldName,\n deleteColumnCheckbox,\n getNewDefaultColumns,\n getColumnsAfterChangeWidth,\n getDefaultConfig,\n filterColumnsGrid,\n filterSelectedMembers,\n};\n","import React from 'react';\n\nimport { useSelector } from 'react-redux';\n\nimport { ReactComponent as IconDownloadSheet } from 'common/components/button/svg-icons/ICO_10.46.svg';\nimport { CloudDownloadOutlined } from '@ant-design/icons';\n\nimport * as productSelectors from 'pages/product-full-view/controllers/selectors';\n\nimport { forwardTo } from 'utils/common/route';\nimport { saveFile } from 'utils/saveFile';\n\nimport { downloadMappingProductSheets } from 'services/mapping';\n\nimport messages from 'i18n/messages/home';\n\nimport {\n CustomNotification,\n ItemButton,\n ContainerButton,\n RibbonButton,\n} from 'common/components';\n\nconst ProductSheets = ({ productId, disabled }) => {\n return (\n }\n label={messages.downloadSheet}\n onClick={() => forwardTo(`/product/sheets/${productId}`)}\n disabled={disabled}\n className='button-item-dropdown'\n />\n );\n};\n\nexport const DownloadMappingProductSheets = () => {\n const selectedMapping = useSelector(\n productSelectors.makeSelectSelectedMapping()\n );\n const currentHierarchy = useSelector(\n productSelectors.makeSelectCurrentHierarchy()\n );\n\n const handleDownloadMappingProductSheets = () => {\n downloadMappingProductSheets({\n mappingId: parseInt(selectedMapping?.mappingId),\n hierarchyId: parseInt(currentHierarchy?.productHierarchyId),\n })\n .then((response) => {\n if (response.isSuccess) {\n saveFile(response?.data?.url);\n } else {\n CustomNotification.error(response?.message);\n }\n })\n .catch(() => {\n CustomNotification.error('Something went wrong. Try again');\n });\n };\n\n return (\n \n \n }\n label={messages.download}\n disabled={!selectedMapping || !currentHierarchy}\n onClick={handleDownloadMappingProductSheets}\n />\n \n \n );\n};\n\nexport default ProductSheets;\n","import { useState, useEffect } from 'react';\n\nconst useToggleActiveRibbon = (isPathActive) => {\n const [isActive, setIsActive] = useState(false);\n\n useEffect(() => {\n if (isPathActive) {\n setIsActive(true);\n } else {\n setIsActive(false);\n }\n }, [isPathActive]);\n\n return isActive;\n};\n\nexport default useToggleActiveRibbon;\n","import React from 'react';\nimport { Table } from 'antd';\nimport { DeleteOutlined } from '@ant-design/icons';\n\nconst SelectedProductList = ({ productList, handleRemoveActiveProduct }) => {\n const mappingListUpload = productList;\n\n const COLUMNS_TABLE = [\n {\n title: 'Product Name',\n dataIndex: 'productName',\n render: (productName, record) => {\n return (\n <>\n \n {productName}\n \n \n );\n },\n },\n {\n title: 'GTIN',\n dataIndex: 'gtin',\n },\n {\n title: 'RIVIR ID',\n dataIndex: 'rivirId',\n },\n {\n title: 'Category I',\n dataIndex: 'category1Name',\n },\n {\n title: 'Category II',\n dataIndex: 'category2Name',\n },\n {\n title: 'Category III',\n dataIndex: 'category3Name',\n },\n {\n title: 'Category IV',\n dataIndex: 'category4Name',\n },\n {\n title: '',\n render: (_, record) => (\n handleRemoveActiveProduct(record)}\n style={{ cursor: 'pointer', color: '#ff4d4f' }}\n >\n \n \n ),\n },\n ];\n\n return (\n
\n \n
\n );\n};\n\nexport default SelectedProductList;\n","import { RetweetOutlined } from '@ant-design/icons';\nimport { Button, Col, Empty, Form, Row, Typography } from 'antd';\nimport React, { useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport {\n CustomNotification,\n FormAddButton,\n ProductCategoryTree,\n dialogFunction,\n} from 'common/components';\n\nimport SelectedProductList from './SelectedProductList';\nimport messages from 'i18n/messages/home';\nimport { StyledModal } from 'common/components';\n\nimport gridSelector from 'common/components/grid-view/controllers/selectors';\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\nimport { useGetMemberId } from 'hooks/useGetMemberId';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\nimport { useGetProductCategoryTreeView } from 'pages/company-profile/components/tabs/system/category-management/hooks/useProductCategoryManagement';\nimport * as categoryManagement from 'services/categoryManagement';\nimport { EVENT } from 'static/Constants';\nimport { apiHandler } from 'utils/api';\n\nimport ProductCategoryForm from 'pages/company-profile/components/tabs/system/category-management/components/ProductCategoryForm';\nimport {\n generateIdsBySelectedKey,\n getCategoryObjectWhenSelectNode,\n} from 'pages/company-profile/components/tabs/system/category-management/utils';\n\nimport './AssignCategoryToProductModal.less';\nimport { useGlobalModal, useUserInfo } from 'hooks';\nimport { useGetProductVersionList } from 'pages/product-history/hook';\n\nconst { Title } = Typography;\n\nconst AssignCategoryToProductModal = ({\n isProductDetail = false,\n productFull,\n}) => {\n const intl = useIntl();\n const dispatch = useDispatch();\n const [form] = Form.useForm();\n\n const [nodeSelected, setNodeSelected] = useState(null);\n const [idDeletedList, setIdDeletedList] = useState([]);\n const [isPrefetching, setIsPrefetching] = useState(true);\n const [isBlankCategory, setIsBlankCategory] = useState(false);\n const [loadingAssignCategoryToProduct, setLoadingAssignCategoryToProduct] =\n useState(false);\n\n const { memberId } = useGetMemberId();\n\n const { closeModal, checkModalVisible, MODAL_NAMES } = useGlobalModal();\n\n const isModalOpen = checkModalVisible(MODAL_NAMES.ASSIGN_CATEGORY_TO_PRODUCT);\n\n const { userInfo } = useUserInfo();\n const currentMemberId = userInfo?.member.id;\n\n const reloadPage = useDispatchReloadPage();\n\n const selectedItemDetailList = useSelector(\n gridSelector.makeSelectDetailCurrentITemsSelection()\n );\n\n const { handleRefetchProductVersioning } = useGetProductVersionList({\n enabled: false,\n });\n\n const { nestedCategory, isLoading } = useGetProductCategoryTreeView(\n currentMemberId,\n isModalOpen,\n isPrefetching,\n setIsPrefetching\n );\n\n const getProductSelectedList = () => {\n const productSelected = isProductDetail\n ? [productFull]\n : selectedItemDetailList;\n\n const productFilter = productSelected.filter(\n (item) => !idDeletedList.includes(item?.id)\n );\n return productFilter;\n };\n\n const productSelectedList = getProductSelectedList();\n\n const isDisabled =\n !isBlankCategory && (!nodeSelected || !productSelectedList.length);\n\n const onCancel = () => {\n closeModal(MODAL_NAMES.ASSIGN_CATEGORY_TO_PRODUCT);\n };\n\n const dispatchReloadCategoryEvent = () => {\n const event = new CustomEvent(EVENT.RELOAD_CATEGORY);\n document.dispatchEvent(event);\n };\n\n const resetActiveProducts = () => {\n setIdDeletedList([]);\n };\n\n const handleRemoveActiveProduct = (productItem) => {\n setIdDeletedList((prev) => [...prev, productItem?.id]);\n };\n\n const onSelectNode = (nodeFound) => {\n const fieldsValues = getCategoryObjectWhenSelectNode(\n nestedCategory,\n nodeFound\n );\n setIsBlankCategory(false);\n form.setFieldsValue(fieldsValues);\n setNodeSelected(nodeFound);\n };\n\n const sendPayLoadToBeWhenAssignCategoryToProduct = (forceUpdate = false) => {\n let params = {};\n\n const idProductAssignList = productSelectedList.map(\n (productItem) => productItem.id\n );\n\n if (isBlankCategory) {\n params = {\n category1Id: null,\n category2Id: null,\n category3Id: null,\n category4Id: null,\n };\n } else {\n const idCategoryList = generateIdsBySelectedKey(nodeSelected?.key ?? '');\n for (let i = 0; i < idCategoryList.length; i++) {\n params[`category${i + 1}Id`] = idCategoryList[i];\n }\n }\n\n const idProductList = isProductDetail\n ? [productFull.productId]\n : idProductAssignList;\n\n return (params = {\n ...params,\n memberId,\n productItemIds: idProductList,\n forceUpdate,\n });\n };\n\n const unSelectNode = () => {\n const unSelectNode = new CustomEvent('unSelectNode', {\n detail: 'reset-category-modal',\n });\n document.dispatchEvent(unSelectNode);\n };\n\n const setEmptyCategory = () => {\n form.resetFields();\n unSelectNode();\n setNodeSelected(null);\n setIsBlankCategory(true);\n };\n\n const successCallbackReassign = () => {\n dispatchReloadCategoryEvent();\n closeModal(MODAL_NAMES.ASSIGN_CATEGORY_TO_PRODUCT);\n reloadPage({ clearSelection: true });\n setLoadingAssignCategoryToProduct(false);\n dispatch(actionsGridView.updatePagesSelection([]));\n dispatch(actionsGridView.updateItemPageSelection([]));\n handleRefetchProductVersioning();\n };\n\n const onOkReassignCategoryToProduct = () => {\n setLoadingAssignCategoryToProduct(true);\n const params = sendPayLoadToBeWhenAssignCategoryToProduct(true);\n apiHandler({\n service: categoryManagement.assignCategoryToProduct,\n params,\n successMessage: intl.formatMessage(\n messages.assignCategoryToProductSuccess\n ),\n errorMessage: intl.formatMessage(messages.assignCategoryToProductFail),\n\n successCallback: successCallbackReassign,\n onFinally: () => {\n setLoadingAssignCategoryToProduct(false);\n },\n });\n };\n\n const AssignCategoryToProduct = () => {\n setLoadingAssignCategoryToProduct(true);\n const confirmOverWriteCategory = isProductDetail\n ? 'confirmOverwriteCategoryProductDetail'\n : 'confirmOverwriteCategoryProductGrid';\n\n const params = sendPayLoadToBeWhenAssignCategoryToProduct();\n\n apiHandler({\n service: categoryManagement.assignCategoryToProduct,\n params,\n successMessage: intl.formatMessage(\n messages.assignCategoryToProductSuccess\n ),\n errorMessage: intl.formatMessage(messages.assignCategoryToProductFail),\n skipNotification: true,\n successCallback: (data) => {\n if (!data.existProductLinks) {\n CustomNotification.success(\n intl.formatMessage(messages.assignCategoryToProductSuccess)\n );\n successCallbackReassign();\n }\n },\n failCallback: () => {\n setLoadingAssignCategoryToProduct(false);\n dialogFunction({\n type: 'warn',\n content: intl.formatMessage(messages[confirmOverWriteCategory]),\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: () => onOkReassignCategoryToProduct(),\n });\n },\n });\n };\n\n const renderModalFooter = () => {\n const CancelBtn = Button;\n const AssignBtn = Button;\n\n return (\n \n \n \n \n {intl.formatMessage(messages.previewRequirementsCancelButton)}\n \n \n {intl.formatMessage(messages.assignCategoryToProductText)}\n \n \n \n );\n };\n\n const modalProps = {\n title: intl.formatMessage(messages.assignCategoryToProduct),\n visible: isModalOpen,\n onCancel,\n width: '1150px',\n bodyStyle: { maxHeight: '670px', height: '66vh' },\n forceRender: true,\n footer: renderModalFooter(),\n destroyOnClose: true,\n };\n\n return (\n \n \n \n \n
\n \n
\n \n \n \n \n \n \n \n \n \n {intl.formatMessage(messages.assignedProductTitle)} (\n {productSelectedList.length})\n \n \n \n }\n onClick={resetActiveProducts}\n disabled={!idDeletedList.length}\n />\n \n \n {productSelectedList.length > 0 ? (\n \n ) : (\n \n \n \n )}\n \n \n \n \n
\n );\n};\n\nexport default AssignCategoryToProductModal;\n","import React from 'react';\n\nimport { Menu } from 'antd';\nimport { EditOutlined, UploadOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nimport messagesProduct from 'i18n/messages/product';\nimport { useGlobalModal } from 'hooks';\n\nconst BulkEditProduct = (props) => {\n const { disabled, selectedProducts, selectedFolders, disabledExport } = props;\n\n const { openModal, MODAL_NAMES } = useGlobalModal();\n const onClickExportButton = () => {\n openModal(MODAL_NAMES.EXPORT_PROPERTY_MODAL);\n };\n\n const onClickImportButton = () => {\n openModal(MODAL_NAMES.IMPORT_PROPERTY_MODAL);\n };\n\n const isDisabledExportButton =\n disabledExport || (!selectedProducts?.length && !selectedFolders?.length);\n\n return (\n <>\n \n }\n label={messagesProduct.exportSelectedProduct}\n onClick={onClickExportButton}\n disabled={isDisabledExportButton}\n />\n \n \n }\n label={messagesProduct.importBuildEdit}\n onClick={onClickImportButton}\n disabled={disabled}\n />\n \n \n );\n};\n\nexport default BulkEditProduct;\n","export const DEFAULT_COLUMNS = {\n dataRecipientGln: { headerName: 'Data Recipient GLN' },\n dataSourceGln: { headerName: 'Data Source GLN' },\n gtin: { headerName: 'GTIN' },\n publicationDate: { format: 'date' },\n targetMarket: {},\n};\n","import { DEFAULT_COLUMNS } from './constants';\n\nimport { Checkbox } from 'antd';\n\nimport { formatMDY } from 'utils/formatDate';\n\nexport const getColumnDefs = ({ item }) => {\n const fields = Object.keys(item ? item : DEFAULT_COLUMNS);\n const checkboxColumns = {\n checkboxSelection: true,\n headerCheckboxSelection: true,\n filter: false,\n resizable: false,\n suppressMenu: true,\n width: 50,\n };\n\n const columns = fields.reduce((accumulator, currentField, index) => {\n const COLUMN = DEFAULT_COLUMNS[currentField];\n const valueFormatter = getValueFormatter(COLUMN?.format);\n\n const column = {\n field: currentField,\n headerName: COLUMN?.headerName,\n valueFormatter,\n flex: 1,\n };\n\n accumulator.push(column);\n\n return accumulator;\n }, []);\n\n const actionColumn = {\n field: 'unRegisterProduct',\n flex: 1,\n headerName: 'Unregister Product',\n cellRenderer: (params) => {\n return ;\n },\n };\n return [checkboxColumns, ...columns, actionColumn];\n};\n\nconst CheckboxRender = ({ params }) => {\n const onChangeUnregisterCheckbox = (params) => (e) => {\n const rowNode = params.node;\n\n rowNode.setDataValue('unRegisterProduct', e.target.checked);\n };\n return (\n \n );\n};\n\nconst getValueFormatter = (format) => {\n const formatterCollection = {\n date: formatDate,\n };\n\n return formatterCollection[format];\n};\n\nconst formatDate = (params) => {\n return formatMDY(params.value);\n};\n","import React, { useMemo, useEffect, useRef, useState } from 'react';\n\nimport { AgGridClient } from 'common/components';\n\nimport * as utils from './utils';\n\nconst disableRowClickCols = ['unRegisterProduct'];\n\nconst PublicationTable = (props) => {\n const { data, onSelect } = props;\n\n const refAggrid = useRef();\n const [rowData, setRowData] = useState([]);\n\n const columns = useMemo(() => {\n const firstRowData = data?.[0];\n\n return utils.getColumnDefs({ item: firstRowData });\n }, [data?.[0]]);\n\n const onSelectRow = (params) => {\n const selectedRows = params.api.getSelectedRows();\n onSelect && onSelect(selectedRows);\n };\n\n const onCellClick = (clickEvent) => {\n const colId = clickEvent?.column?.colId;\n if (!disableRowClickCols.includes(colId)) {\n clickEvent.node.setSelected(true);\n }\n };\n\n useEffect(() => {\n const newData = data.map((dataItem) => ({\n unRegisterProduct: false,\n ...dataItem,\n }));\n\n setRowData(newData);\n }, [data]);\n\n return (\n \n );\n};\n\nexport default PublicationTable;\n","import { useState, useRef } from 'react';\n\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\n\nimport { dialogFunction, CustomNotification } from 'common/components';\n\nimport {\n deleteProductItemsPublication,\n getAllPublications,\n} from 'services/product';\n\nexport const useWithdrawPublication = (props = {}) => {\n const shouldReloadRef = useRef();\n const { products, enabled = false } = props;\n\n const [selectedPublications, setSelectedPublications] = useState([]);\n\n const queryClient = useQueryClient();\n\n const publicationsQuery = useQuery({\n queryKey: ['get-all-publication', products?.[0]?.id],\n queryFn: async ({ queryKey }) => {\n const productId = queryKey?.[1];\n\n if (!productId) return;\n\n const params = { productId };\n const response = await getAllPublications(params);\n\n if (!response?.isSuccess) throw new Error(response?.message);\n\n return response?.data;\n },\n enabled,\n retry: false,\n });\n\n const withdrawPublicationMutation = useMutation({\n mutationKey: 'withdraw-publication',\n mutationFn: (params) => {\n return deleteProductItemsPublication(params);\n },\n onSuccess: (response) => {\n response?.isSuccess &&\n queryClient.invalidateQueries({\n queryKey: ['get-all-publication', products?.[0]?.id],\n });\n\n shouldReloadRef.current = response?.isSuccess;\n },\n onError: () => {\n CustomNotification.error(\n 'Cannot withdraw product(s) publication/registration!'\n );\n },\n });\n\n const getWithdrawPublicationParams = () => {\n return selectedPublications.map((publicationItem) => {\n return {\n catalogueItemReferenceGtin: publicationItem?.gtin,\n dataSourceGln: publicationItem?.dataSourceGln,\n dataRecipientGln: publicationItem?.dataRecipientGln,\n catalogueItemReferenceTargetMarketCountryCode:\n publicationItem?.targetMarket,\n unRegisterProduct: publicationItem?.unRegisterProduct,\n };\n });\n };\n\n const confirmDeleteProductsPublication = () => {\n dialogFunction({\n type: 'warn',\n content:\n 'Are you sure to withdraw the selected product(s) publication/registration?',\n okText: 'Confirm',\n okButtonProps: {\n type: 'danger',\n },\n onOk: handleWithdrawPublication,\n });\n };\n\n const handleWithdrawPublication = async () => {\n withdrawPublicationMutation.mutate(\n {\n withdrawPublishedProducts: getWithdrawPublicationParams(),\n },\n {\n onSuccess: (response) => {\n if (response?.isSuccess) {\n CustomNotification.success(\n 'Withdraw product(s) publication/registration successfully!'\n );\n } else {\n CustomNotification.error(\n response?.message ||\n 'Cannot withdraw product(s) publication/registration!'\n );\n }\n setSelectedPublications([]);\n },\n }\n );\n };\n\n const selectPublications = (publicationSelected) => {\n setSelectedPublications(publicationSelected);\n };\n\n const unSelectPublication = (publication) => {\n setSelectedPublications((prevState) =>\n prevState.filter(\n (publicationItem) => publicationItem.id !== publication.id\n )\n );\n };\n\n return {\n publicationsQuery,\n confirmDeleteProductsPublication,\n selectPublications,\n selectedPublications,\n unSelectPublication,\n shouldReload: shouldReloadRef.current,\n };\n};\n","import React from 'react';\n\nimport { StyledModal, DataDisplay } from 'common/components';\nimport PublicationTable from './PublicationTable';\n\nimport { useGridView } from 'hooks';\nimport { useWithdrawPublication } from 'hooks/useWithdrawPublication';\n\nimport Messages from 'i18n/messages/home';\nimport { useIntl } from 'react-intl';\n\nconst WithdrawPublicationModal = (props) => {\n const intl = useIntl();\n\n const { visible, closeModal, products } = props;\n\n const { reloadPage } = useGridView();\n\n const {\n publicationsQuery,\n selectedPublications,\n selectPublications,\n confirmDeleteProductsPublication,\n shouldReload,\n } = useWithdrawPublication({\n products,\n enabled: visible,\n });\n\n const { data, isLoading, error } = publicationsQuery;\n const publicationList = data?.publicationListModels;\n\n const onOk = () => {\n confirmDeleteProductsPublication();\n };\n\n const onCancel = () => {\n closeModal && closeModal();\n if (shouldReload) {\n setTimeout(() => {\n reloadPage({ clearSelection: true });\n }, 300);\n }\n };\n\n const errorMessage = intl.formatMessage(Messages.getPublicationErrorMessage);\n\n return (\n \n \n \n \n \n );\n};\n\nexport default WithdrawPublicationModal;\n","import React, { useState } from 'react';\n\nimport { DeleteOutlined } from '@ant-design/icons';\n\nimport { RibbonButton } from 'common/components';\n\nimport WithdrawPublicationModal from '../../modal/withdraw-publication/WithdrawPublicationModal';\n\nimport messages from 'i18n/messages/home';\n\nconst WithdrawPublicationButton = (props) => {\n const { products, isDisabled } = props;\n const [modalVisible, setModalVisible] = useState(false);\n\n const showModal = () => {\n setModalVisible(true);\n };\n\n const closeModal = () => {\n setModalVisible(false);\n };\n\n const onClick = () => {\n showModal();\n };\n\n return (\n <>\n }\n label={messages.withDrawProductPublicationFull}\n disabled={isDisabled}\n onClick={onClick}\n />\n \n \n );\n};\n\nexport default WithdrawPublicationButton;\n","import { RIVIR_FIELDS, TAG_COLORS } from 'static/Constants';\n\nimport produce from 'immer';\n\nexport const getNewFieldsAfterChangeProperty = (\n data,\n index,\n value,\n propertyName\n) => {\n const result = produce(data, (draftFile) => {\n draftFile[index][`${propertyName}`] = value;\n });\n\n return result;\n};\nexport const getNewFieldsAfterChangePackageLevel = (data, index, value) => {\n const result = produce(data, (draftFile) => {\n draftFile[index].packageLevel = value;\n draftFile[index].fieldName = null;\n });\n\n return result;\n};\n\nexport const getNewFieldsAfterChangeModuleName = (data, index, value) => {\n const result = produce(data, (draftFile) => {\n draftFile[index].moduleName = value;\n draftFile[index].fieldName = null;\n });\n\n return result;\n};\n\nexport const getColorTag = (gln) => {\n if (gln[0] === '0') return TAG_COLORS[0];\n\n if (parseInt(gln.substring(0, 2)) % 2 === 0) return TAG_COLORS[1];\n\n if (parseInt(gln.substring(0, 2)) % 2 !== 0) return TAG_COLORS[2];\n};\n\nexport const getListModuleNames = (productSchema) => {\n if (productSchema.length > 0) {\n return productSchema.map((schema) => ({\n moduleName: schema.moduleName,\n moduleDisplayName: schema.moduleDisplayName,\n }));\n }\n return [];\n};\n\nexport const getNewFieldsAfterDelete = (fields, fieldKey) => {\n let cloneFields = fields.slice();\n cloneFields.splice(fieldKey, 1);\n return cloneFields;\n};\n\nexport const getNewFieldsAfterClone = (fields, index, cloneField) => {\n let newFields = [];\n fields.forEach((field) => {\n if (!field) {\n newFields.push({\n packageLevel: '',\n moduleName: '',\n fieldName: '',\n });\n } else {\n newFields.push(field);\n }\n });\n\n const result = produce(newFields, (draftFile) => {\n draftFile[newFields.length - 1].moduleName = cloneField.moduleName;\n draftFile[newFields.length - 1].packageLevel = cloneField.packageLevel;\n draftFile[newFields.length - 1].fieldName = '';\n });\n\n return result;\n};\n\nconst getSelectedFields = (fieldsState, fieldKey) => {\n if (fieldsState) {\n const { packageLevel } = fieldsState[fieldKey];\n\n let result = [];\n\n fieldsState.forEach((field) => {\n if (field && field.fieldName && field.packageLevel === packageLevel) {\n result.push(field.fieldName);\n }\n });\n\n return result;\n }\n return [];\n};\n\nexport const getListFieldNames = (productSchema, fieldsState, fieldKey) => {\n if (fieldsState) {\n const selectedFields = getSelectedFields(fieldsState, fieldKey);\n\n if (fieldsState[fieldKey].type === 'RIVIR') {\n return RIVIR_FIELDS.filter(\n (field) => !selectedFields.includes(field.value)\n ).map((field) => ({\n fieldName: field.value,\n fieldDisplayName: field.name,\n }));\n }\n\n const foundModuleName = productSchema.find(\n (schema) => schema.moduleName === fieldsState[fieldKey].moduleName\n );\n\n if (!foundModuleName) return [];\n\n return foundModuleName.moduleProperties\n .filter((property) => !selectedFields.includes(property.propertyName))\n .map((property) => ({\n fieldName: property.propertyName,\n fieldDisplayName: property.propertyDisplayName,\n }));\n }\n return [];\n};\n\nexport const getDisplayFieldName = (fieldKey, fieldsState, productSchema) => {\n if (fieldsState.length > 0) {\n if (\n fieldsState[fieldKey].type === 'RIVIR' &&\n fieldsState[fieldKey].fieldName\n ) {\n return fieldsState[fieldKey].fieldName;\n }\n\n const foundModuleName = productSchema.find(\n (schema) => schema.moduleName === fieldsState[fieldKey].moduleName\n );\n\n if (!foundModuleName) return `Field ${fieldKey + 1}`;\n\n const displayName = foundModuleName.moduleProperties.find(\n (property) => property.propertyName === fieldsState[fieldKey].fieldName\n );\n\n if (displayName) return displayName.propertyDisplayName;\n return `Field ${fieldKey + 1}`;\n }\n return `Field ${fieldKey + 1}`;\n};\n\nexport const getRivirFieldDisplayName = (fieldName) => {\n const rivirField = RIVIR_FIELDS.find((field) => {\n return field.value === fieldName;\n });\n\n return rivirField?.name;\n};\n\nexport const getFullFieldDisplayName = ({ fieldName, productSchema }) => {\n if (!productSchema) return '';\n if (!fieldName) return '';\n\n const fieldNamePath = fieldName.split('.');\n const displayNameListResult = fieldNamePath.reduce(\n (accumulator, currentFieldPath) => {\n accumulator = findFieldDisplayNameDeep({\n result: accumulator,\n fieldName: currentFieldPath,\n });\n\n return accumulator;\n },\n { displayNameList: [], fieldList: productSchema }\n );\n\n const displayName = displayNameListResult.displayNameList.join(' > ');\n\n return displayName;\n};\n\nconst findFieldDisplayNameDeep = ({ result, fieldName }) => {\n const fieldData = result.fieldList?.find((fieldItem) => {\n const itemFieldName = fieldItem.moduleName || fieldItem.propertyName;\n const matched = fieldName.toLowerCase() === itemFieldName.toLowerCase();\n return matched ? fieldItem : null;\n });\n\n const fieldDisplayName = fieldData\n ? fieldData.moduleDisplayName || fieldData.propertyDisplayName\n : null;\n\n if (fieldDisplayName)\n result.displayNameList = [...result.displayNameList, fieldDisplayName];\n\n const childrenFields =\n fieldData?.moduleProperties || fieldData?.childProperties;\n\n if (childrenFields?.length) result.fieldList = childrenFields;\n\n return result;\n};\n\nexport const checkDisabledModuleName = (fieldsState, fieldKey) => {\n if (fieldsState.length > 0) {\n return fieldsState[fieldKey].type === 'RIVIR';\n }\n return false;\n};\n\nexport const filterFields = (fields) => {\n if (fields) {\n let result = [];\n fields.forEach((field) => {\n const { type, ...otherValues } = field;\n result.push(otherValues);\n });\n return result;\n }\n return [];\n};\n\nexport const distinguishFieldsFromEditedFields = (fields) => {\n if (!fields.length) return [];\n return fields.map((fieldItem) => {\n const fieldName = fieldItem.fieldName;\n const isRivirType = fieldName.indexOf('.') < 0;\n\n return { ...fieldItem, type: isRivirType ? 'RIVIR' : null };\n });\n};\n\nexport const updateModuleName = ({ key, moduleName, fieldList }) => {\n return produce(fieldList, (draft) => {\n draft[key].moduleName = moduleName;\n\n if (!moduleName) return; //* just clear field name when select module name\n\n draft[key].fieldName = null;\n });\n};\n\nexport const getExpandedKeys = (productSchema, expandedKeyList) => {\n return productSchema.reduce((accumulator, currentSchemaItem) => {\n if (currentSchemaItem.moduleName)\n accumulator.push(currentSchemaItem.moduleName);\n\n if (currentSchemaItem.fieldFullPath)\n accumulator.push(currentSchemaItem.fieldFullPath);\n\n if (currentSchemaItem?.moduleProperties?.length)\n getExpandedKeys(currentSchemaItem.moduleProperties, accumulator);\n\n if (currentSchemaItem?.childProperties?.length)\n getExpandedKeys(currentSchemaItem.childProperties, accumulator);\n\n return accumulator;\n }, expandedKeyList || []);\n};\n","import * as React from \"react\";\nconst SvgIco1013 = props => ;\nexport { SvgIco1013 as ReactComponent };\nexport default \"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKCSB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTEyIDUxMjsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxnPgoJCTxwYXRoIGQ9Ik00NjcsNjFINDVDMjAuMjE4LDYxLDAsODEuMTk2LDAsMTA2djMwMGMwLDI0LjcyLDIwLjEyOCw0NSw0NSw0NWg0MjJjMjQuNzIsMCw0NS0yMC4xMjgsNDUtNDVWMTA2CgkJCUM1MTIsODEuMjgsNDkxLjg3Miw2MSw0NjcsNjF6IE00NjAuNzg2LDkxTDI1Ni45NTQsMjk0LjgzM0w1MS4zNTksOTFINDYwLjc4NnogTTMwLDM5OS43ODhWMTEyLjA2OWwxNDQuNDc5LDE0My4yNEwzMCwzOTkuNzg4egoJCQkgTTUxLjIxMyw0MjFsMTQ0LjU3LTE0NC41N2w1MC42NTcsNTAuMjIyYzUuODY0LDUuODE0LDE1LjMyNyw1Ljc5NSwyMS4xNjctMC4wNDZMMzE3LDI3Ny4yMTNMNDYwLjc4Nyw0MjFINTEuMjEzeiBNNDgyLDM5OS43ODcKCQkJTDMzOC4yMTMsMjU2TDQ4MiwxMTIuMjEyVjM5OS43ODd6Ii8+Cgk8L2c+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==\";","import React from 'react';\nimport Messages from 'i18n/messages/home';\n\nimport { ReactComponent as IconEmail } from 'common/components/button/svg-icons/ICO_10.13.svg';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport './styles.less';\n\nconst EmailControl = ({ ...otherProps }) => {\n return (\n }\n label={Messages.emailMember}\n className='button-item-dropdown'\n {...otherProps}\n />\n );\n};\n\nEmailControl.propTypes = {};\n\nexport default EmailControl;\n","import React from 'react';\nimport { SendOutlined } from '@ant-design/icons';\nimport Messages from 'i18n/messages/home';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nconst SendToFTP = ({ ...otherProps }) => {\n return (\n }\n label={Messages.sendToFTP}\n className='button-item-dropdown'\n {...otherProps}\n />\n );\n};\n\nSendToFTP.propTypes = {};\n\nexport default SendToFTP;\n","import React from 'react';\nimport { CommentOutlined } from '@ant-design/icons';\nimport Messages from 'i18n/messages/home';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nconst SendToMessage = ({ ...otherProps }) => {\n return (\n }\n label={Messages.sendViaText}\n className='button-item-dropdown'\n {...otherProps}\n />\n );\n};\n\nSendToMessage.propTypes = {};\n\nexport default SendToMessage;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { AdditionControl, DetailControl } from '../../index';\nimport ContainerButton from 'common/components/button/ContainerButton';\nimport ItemButton from 'common/components/button/ItemButton';\n\nconst Favorite = ({ detailClick, addToFolderClick }) => {\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nFavorite.propTypes = {\n detailClick: PropTypes.func,\n};\n\nexport default Favorite;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport AdvanceStack from '../../controls/home/AdvanceStack';\n\nimport ContainerButton from 'common/components/button/ContainerButton';\nimport ItemButton from 'common/components/button/ItemButton';\n\nconst Folder = ({ onSearch, toggleSearch }) => {\n return (\n \n \n \n \n \n );\n};\n\nFolder.propTypes = {\n onSearch: PropTypes.func,\n toggleSearch: PropTypes.func,\n};\n\nexport default Folder;\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport ContainerButton from 'common/components/button/ContainerButton';\nimport ItemButton from 'common/components/button/ItemButton';\n\nimport * as globalActions from '@redux/global/actions';\n\nimport AddOpenItemBtn from '../../controls/common/AddOpenItemBtn';\n\nconst MemberAddOpenItemSection = () => {\n const dispatch = useDispatch();\n\n const toggleAddOpenItem = () => {\n dispatch(globalActions.toggleIsAddingOpenItem(true));\n };\n\n return (\n \n \n {\n toggleAddOpenItem();\n }}\n />\n \n \n );\n};\n\nexport default MemberAddOpenItemSection;\n","import React from 'react';\n\nimport { BackControl } from '../../index';\nimport MemberAddOpenItemSection from '../member-full/MemberAddOpenItemSection';\n\nimport { RibbonSection } from 'common/components';\nimport { RibbonSectionDivider } from 'pages/home/ribbon/components';\n\nconst OtherLayout = (props) => {\n const {\n ribbonType,\n isHaveAddOpenItem = true,\n disableBackControl,\n closeDetailCallback,\n } = props;\n\n return (\n \n {isHaveAddOpenItem && (\n <>\n \n \n \n )}\n \n \n );\n};\n\nOtherLayout.propTypes = {\n /**\n * to detect type of ribbon view\n */\n};\n\nexport default OtherLayout;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Control from '../Control';\nconst InlineControl = (props) => {\n const { icon, text, ...rest } = props;\n return (\n \n {icon}\n {text}\n \n );\n};\n\nInlineControl.propTypes = {\n icon: PropTypes.element,\n};\n\nexport default InlineControl;\n","import React from 'react';\nimport { Typography } from 'antd';\nimport { LayoutOutlined } from '@ant-design/icons';\nimport ViewControl from './InlineControl';\nimport { FormattedMessage } from 'react-intl';\nimport Messages from 'i18n/messages/home';\nconst { Text } = Typography;\nconst QuickViewControl = (props) => {\n const { quickViewClick } = props;\n return (\n \n }\n text={\n \n \n \n }\n onClick={quickViewClick}\n >\n );\n};\n\nQuickViewControl.propTypes = {};\n\nexport default QuickViewControl;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { SearchOutlined } from '@ant-design/icons';\nimport Messages from 'i18n/messages/home';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nconst SearchControl = ({ onSearch }) => {\n return (\n }\n label={Messages.searchText}\n onClick={onSearch}\n />\n );\n};\n\nSearchControl.propTypes = {\n onSearch: PropTypes.func,\n};\n\nexport default SearchControl;\n","import React from 'react';\nimport { FileSearchOutlined } from '@ant-design/icons';\nimport Messages from 'i18n/messages/home';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nconst AdvanceSearchControl = () => {\n return (\n }\n label={Messages.advanceSearch}\n className='button-item-dropdown'\n />\n );\n};\n\nAdvanceSearchControl.propTypes = {};\n\nexport default AdvanceSearchControl;\n","import React, { useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport {\n Modal,\n Checkbox,\n Row,\n Col,\n Radio,\n InputNumber,\n Typography,\n} from 'antd';\nimport { TableOutlined } from '@ant-design/icons';\n\nimport Messages from 'i18n/messages/home';\n\nimport { Form } from 'common/components';\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\n\nimport { useSetDefaultWidth, useChangeWidth } from './hooks';\nimport {\n getListFieldName,\n deleteColumnCheckbox,\n getNewDefaultColumns,\n getColumnsAfterChangeWidth,\n getDefaultConfig,\n} from './utils';\n\nimport './style.less';\n\nconst { Text } = Typography;\n\nconst GridColumnsControl = ({ disabled }) => {\n const dispatch = useDispatch();\n const [form] = Form.useForm();\n const [visible, setVisible] = useState(false);\n const [width, setWidth] = useState(0);\n const [selectedFieldName, setSelectedFieldName] = useState('');\n\n const { allColumns, chosenColumns, id } = useSelector(\n selectorsGridView.makeSelectGridConfig()\n );\n\n useSetDefaultWidth(form, chosenColumns, selectedFieldName);\n useChangeWidth(form, width);\n\n const handleClickField = (fieldName) => {\n const findChosenColumns = chosenColumns.find(\n (col) => col.fieldName === fieldName\n );\n\n if (!findChosenColumns) {\n setWidth(0);\n }\n\n if (findChosenColumns?.width) {\n setWidth(findChosenColumns.width);\n }\n\n setSelectedFieldName(fieldName);\n };\n\n const handleChangeWidth = (width) => {\n const result = getColumnsAfterChangeWidth(\n selectedFieldName,\n width,\n chosenColumns\n );\n dispatch(actionsGridView.changeWidthColumn(result));\n };\n\n const handleFilterColumnsGrid = () => {\n let result = getDefaultConfig(chosenColumns);\n dispatch(actionsGridView.chooseGridColumns(result, id));\n dispatch(actionsGridView.updateIsRefreshGrid());\n setVisible(false);\n };\n\n return (\n <>\n setVisible(false)}\n >\n {visible && (\n \n )}\n \n }\n label={Messages.gridColumns}\n disabled={disabled}\n onClick={() => setVisible(true)}\n className='grid-config__button'\n />\n \n );\n};\n\nconst ListColumns = (props) => {\n const { form, columns, chosenColumns, handleClickField, handleChangeWidth } =\n props;\n\n const dispatch = useDispatch();\n const defaultRadio = deleteColumnCheckbox(chosenColumns)[0]?.fieldName;\n\n // Remove checkbox column\n const columnsRender = deleteColumnCheckbox(columns);\n\n const handleChangeColumns = (checkedValues) => {\n const newColumns = getNewDefaultColumns(\n checkedValues,\n columns,\n chosenColumns\n );\n dispatch(actionsGridView.changeSelectedColumns(newColumns));\n };\n\n return (\n <>\n \n handleClickField(e.target.value)}\n >\n \n {columnsRender.map((column, index) => (\n \n \n \n {column.displayName}\n \n \n ))}\n \n \n\n \n \n Width of selected column (in pixels): \n \n \n
\n \n \n \n
\n \n
\n \n \n );\n};\n\nGridColumnsControl.propTypes = {};\n\nexport default GridColumnsControl;\n","import React from 'react';\n\nimport { SaveOutlined } from '@ant-design/icons';\n\nimport Messages from 'i18n/messages/home';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport { useGlobalModal } from 'hooks';\n\nimport './SaveGrid.less';\n\nconst SaveGrid = (props) => {\n const { MODAL_NAMES, openModal } = useGlobalModal();\n\n return (\n <>\n }\n label={Messages.saveConfig}\n onClick={() => openModal(MODAL_NAMES.CREATE_QUERY)}\n className='grid-config__button'\n />\n \n );\n};\n\nSaveGrid.propTypes = {};\n\nexport default SaveGrid;\n","import React, { useState, useEffect, useMemo } from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\n\nimport {\n Input,\n Radio,\n Select,\n DatePicker,\n Row,\n Col,\n Typography,\n Badge,\n} from 'antd';\n\nimport { Form, WrapperSelect } from 'common/components';\n\nimport { CloseOutlined } from '@ant-design/icons';\n\nimport { useInjectReducer } from 'utils/common/injectedReducers';\nimport { useInjectSaga } from 'utils/common/injectSaga';\n\nimport { AgGrid, FormAddButton } from 'common/components';\nimport MemberThumbnailCard from 'pages/branded-members/components/card/MemberThumbnailCard';\n\nimport {\n MEMBER_DETAIL_GRID,\n MEMBER_DETAIL_GRID_DISTINCT,\n} from 'services/members/endpoints';\n\nimport {\n GET_ALL_QUERIES_NOT_CURATED_QUERY_GRID,\n GET_ALL_QUERIES_NOT_CURATED_QUERY_GRID_DISTINCT,\n} from 'services/markupMaintenance/endpoints';\n\nimport reducerMember from 'pages/branded-members/controllers/reducer';\nimport sagaMember from 'pages/branded-members/controllers/saga';\nimport { makeSelectColumns } from 'pages/branded-members/controllers/selectors';\nimport { gridMemberColumnInfo } from 'pages/branded-members/controllers/actions';\n\nimport usePrevious from 'hooks/usePrevious';\n\nimport { filterColumnsGrid, filterSelectedMembers } from './utils';\n\nimport { DATE_FORMAT } from 'static/Constants';\n\nimport './AddCuratedQueryConfig.less';\n\nconst layout = {\n labelCol: {\n span: 5,\n },\n wrapperCol: {\n span: 18,\n },\n};\n\nconst { Search } = Input;\nconst { RangePicker } = DatePicker;\nconst { Text } = Typography;\n\nconst AddCuratedQueryConfig = (props) => {\n const {\n form,\n selectedQueryDetail,\n setSelectedQuery,\n selectedMembers,\n setSelectedMembers,\n shareType,\n setShareType,\n mode,\n memberRoles,\n } = props;\n\n useEffect(() => {\n if (mode === 'create') {\n form.setFieldsValue({\n curatedQueryShareType: 'MemberRole',\n });\n } else if (mode === 'edit' && selectedQueryDetail?.length > 0) {\n /* Keep memberType prevent errors from old data */\n if (selectedQueryDetail[0]?.curatedQueryShareType === 'MemberType') {\n setShareType('MemberRole');\n form.setFieldsValue({\n curatedQueryShareType: 'MemberRole',\n });\n } else {\n setShareType(selectedQueryDetail[0]?.curatedQueryShareType);\n form.setFieldsValue({\n curatedQueryShareType: selectedQueryDetail[0]?.curatedQueryShareType,\n });\n }\n }\n }, [form, mode]);\n\n return (\n \n \n {mode === 'create' && (\n \n )}\n
\n \n setShareType(e.target.value)}>\n Member Role\n Pickup Members\n All Member\n \n \n\n {/* Keep memberType prevent errors from old data */}\n {shareType === 'MemberRole' || shareType === 'MemberType' ? (\n \n \n {memberRoles\n ?.slice()\n .sort()\n .map((role) => (\n \n {role?.memberRoleName}\n \n ))}\n \n \n ) : null}\n\n \n \n \n\n {shareType === 'SpecificMembers' && selectedMembers.length > 0 && (\n \n \n \n Members:\n \n \n \n \n \n \n )}\n \n \n\n {shareType === 'SpecificMembers' && (\n \n \n \n )}\n
\n );\n};\n\nconst nameGrid = 'member-detail-grid';\nconst key = 'memberList';\n\nconst MemberSelection = ({ selectedMembers, setSelectedMembers }) => {\n useInjectReducer({ key, reducer: reducerMember });\n useInjectSaga({ key, saga: sagaMember });\n\n const [selectedIds, setSelectedIds] = useState([]);\n const [searchText, setSearchText] = useState('');\n const [membersGrid, setMembersGrid] = useState([]);\n\n const prevSearchText = usePrevious(searchText);\n\n const [pagination, setPagination] = useState(1);\n\n const dispatch = useDispatch();\n\n const memberColumns = useSelector(makeSelectColumns());\n\n useEffect(() => {\n dispatch(gridMemberColumnInfo(nameGrid));\n }, [dispatch]);\n\n useEffect(() => {\n if (searchText !== prevSearchText) {\n setPagination(1);\n }\n }, [dispatch, prevSearchText, searchText]);\n\n const filteredMemberColumns = useMemo(\n () => filterColumnsGrid(memberColumns),\n [memberColumns]\n );\n\n const handleAddMembers = () => {\n const filteredMembers = filterSelectedMembers(\n membersGrid,\n selectedIds,\n selectedMembers\n );\n\n setSelectedMembers((prevMembers) => [...prevMembers, ...filteredMembers]);\n };\n\n return (\n
\n
\n setSearchText(value)}\n />\n \n
\n\n {filteredMemberColumns?.length > 0 && (\n setSelectedIds(ids)}\n handleChangePagination={(page) => setPagination(page)}\n getDataFromGrid={(items) => setMembersGrid(items)}\n paramsGrid={{\n search: {\n searchText,\n },\n }}\n pageNumberPagination={pagination}\n rowMultiSelectWithClick={true}\n />\n )}\n
\n );\n};\n\nconst MemberDisplay = ({ selectedMembers, setSelectedMembers }) => {\n const handleDeleteMember = (id) => {\n const result = selectedMembers.filter((member) => member.id !== id);\n setSelectedMembers(result);\n };\n\n return (\n \n {selectedMembers.map((member) => (\n \n handleDeleteMember(member.id)}>\n \n \n }\n className='member-display__badge'\n >\n \n \n \n ))}\n \n );\n};\n\nconst NonCuratedQuerySelection = (props) => {\n const { setSelectedQuery } = props;\n const [searchText, setSearchText] = useState('');\n const [selectedIds, setSelectedIds] = useState([]);\n const prevSearchText = usePrevious(searchText);\n const [pagination, setPagination] = useState(1);\n\n const nonCuratedQueryColumns = [\n {\n checkboxSelection: true,\n field: '',\n filter: false,\n sortable: false,\n suppressMenu: true,\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n displayName: 'Query Name',\n fieldName: 'Name',\n fieldNameCamelCase: 'name',\n resizable: true,\n flex: 1,\n minWidth: 150,\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n displayName: 'Grid Name',\n fieldName: 'GridName',\n fieldNameCamelCase: 'gridName',\n resizable: true,\n width: 200,\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'int32',\n displayName: 'Created By',\n fieldName: 'CreatedBy',\n fieldNameCamelCase: 'createdBy',\n resizable: true,\n width: 120,\n },\n {\n allowFilter: true,\n allowSort: true,\n dataType: 'string',\n displayName: 'Created By Name',\n fieldName: 'CreatedName',\n fieldNameCamelCase: 'createdName',\n resizable: true,\n width: 250,\n },\n ];\n\n useEffect(() => {\n if (searchText !== prevSearchText) {\n setPagination(1);\n }\n }, [prevSearchText, searchText]);\n\n return (\n
\n
\n setSearchText(value)}\n />\n
\n {nonCuratedQueryColumns?.length > 0 && (\n {\n setSelectedIds(ids);\n setSelectedQuery(ids);\n }}\n handleChangePagination={(page) => setPagination(page)}\n paramsGrid={{\n search: {\n searchText,\n },\n }}\n gridConfigProps={{\n rowSelection: 'single',\n }}\n pageNumberPagination={pagination}\n />\n )}\n
\n );\n};\n\nexport default AddCuratedQueryConfig;\n","import React, { useState, useEffect } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Modal, Button, Form, notification } from 'antd';\nimport AddCuratedQueryConfig from './AddCuratedQueryConfig';\n\nimport { getGridName } from 'utils/getGridName';\n\nimport { saveCuratedQuery } from 'services/markupMaintenance';\nimport * as markupActions from 'pages/markup-maintenance/controllers/actions';\nimport * as markupSelectors from 'pages/markup-maintenance/controllers/selectors';\nimport { ABILITY_ACTION, ABILITY_SUBJECT } from 'static/Permission';\nimport { useCheckPermissions } from 'hooks/useCheckPermissions';\nimport {\n useGetCuratedQueryDetail,\n useGetMembers,\n useGetAllMemberRoles,\n} from './hooks';\nimport moment from 'moment';\n\nimport './AddCuratedQuery.less';\n\nconst PERMISSION_EDIT_CURATED_QUERY = [\n {\n action: ABILITY_ACTION.MANAGE,\n subject: ABILITY_SUBJECT.CURATED_QUERY,\n },\n];\n\nconst AddCuratedQuery = (props) => {\n const { visible, setVisible, mode, selectedQueryDetail } = props;\n const hasPermissionEditCuratedQuery = useCheckPermissions(\n PERMISSION_EDIT_CURATED_QUERY\n );\n\n const { memberRoles } = useGetAllMemberRoles();\n\n const dispatch = useDispatch();\n\n const pageSize = useSelector(markupSelectors.selectCuratedQueryPageSize());\n\n const { curatedQueryData } = useGetCuratedQueryDetail({\n curatedQueryId: selectedQueryDetail[0]?.id,\n enabled:\n hasPermissionEditCuratedQuery &&\n mode === 'edit' &&\n Boolean(selectedQueryDetail[0]?.id),\n });\n\n const filteredMembers = useGetMembers({\n valuesFilter: curatedQueryData?.curatedQueryShareToMembers,\n enabled:\n hasPermissionEditCuratedQuery &&\n mode === 'edit' &&\n curatedQueryData?.curatedQueryShareToTotalsMembers > 0 &&\n curatedQueryData?.curatedQueryShareType === 'SpecificMembers',\n });\n\n const [form] = Form.useForm();\n\n const [selectedMembers, setSelectedMembers] = useState([]);\n const [selectedQuery, setSelectedQuery] = useState([]);\n const [shareType, setShareType] = useState('MemberRole');\n const [statusSubmit, setStatusSubmit] = useState('idle');\n\n const gridName = getGridName(window.location.pathname);\n\n useEffect(() => {\n form.setFieldsValue({ gridName });\n }, [form, gridName]);\n\n useEffect(() => {\n if (!visible) {\n form.resetFields();\n setSelectedMembers([]);\n setShareType('MemberRole');\n }\n }, [form, visible]);\n\n useEffect(() => {\n if (mode === 'edit' && selectedQueryDetail?.length > 0) {\n setShareType(selectedQueryDetail[0]?.curatedQueryShareType);\n\n if (selectedQueryDetail[0]?.curatedQueryShareToMemberType) {\n const curatedQueryShareToMemberRoleId =\n memberRoles.find(\n (role) =>\n role?.memberRoleName ===\n selectedQueryDetail[0]?.curatedQueryShareToMemberType\n )?.memberRoleId ?? null;\n\n form.setFieldsValue({\n curatedQueryShareToMemberRoleId,\n });\n }\n }\n }, [selectedQueryDetail, form, mode, visible, memberRoles]);\n\n useEffect(() => {\n if (hasPermissionEditCuratedQuery && visible) {\n form.setFieldsValue({\n //TODO: DATETIME\n dateActive: [\n curatedQueryData?.effectedDate\n ? moment(curatedQueryData?.effectedDate)\n : null,\n curatedQueryData?.effectedDate\n ? moment(curatedQueryData?.expirationDate)\n : null,\n ],\n curatedQueryShareToMemberType:\n curatedQueryData?.curatedQueryShareToMemberType,\n });\n }\n }, [\n hasPermissionEditCuratedQuery,\n form,\n visible,\n curatedQueryData.effectedDate,\n curatedQueryData.expirationDate,\n curatedQueryData.curatedQueryShareToMemberType,\n ]);\n\n useEffect(() => {\n if (hasPermissionEditCuratedQuery && filteredMembers.length > 0) {\n setSelectedMembers(filteredMembers);\n }\n }, [filteredMembers, hasPermissionEditCuratedQuery]);\n\n const handleCreateConfig = async () => {\n const { dateActive, ...values } = await form.validateFields();\n\n setStatusSubmit('loading');\n\n const submitId =\n selectedQueryDetail?.length > 0\n ? selectedQueryDetail[0]?.id\n : selectedQuery?.length > 0 && selectedQuery[0];\n\n let params = {\n ...values,\n id: submitId,\n gridName,\n };\n\n const { curatedQueryShareType, curatedQueryShareToMemberRoleId } = values;\n\n if (curatedQueryShareType === 'MemberRole') {\n if (curatedQueryShareToMemberRoleId) {\n params = {\n ...params,\n curatedQueryShareToMemberRoleId,\n curatedQueryShareToMemberType:\n memberRoles.find(\n (role) => role.memberRoleId === curatedQueryShareToMemberRoleId\n )?.memberRoleName ?? null,\n };\n }\n params = {\n ...params,\n curatedQueryShareType,\n curatedQueryShareToMembers: [],\n };\n }\n\n if (curatedQueryShareType === 'SpecificMembers') {\n params = {\n ...params,\n curatedQueryShareType,\n curatedQueryShareToMembers: selectedMembers.map((member) => member.id),\n };\n }\n\n if (curatedQueryShareType === 'AllMember') {\n params = {\n ...params,\n curatedQueryShareType,\n curatedQueryShareToMemberType: null,\n curatedQueryShareToMembers: [],\n };\n }\n\n if (dateActive) {\n params = {\n ...params,\n effectedDate: dateActive[0]?.toISOString(),\n expirationDate: dateActive[1]?.toISOString(),\n };\n } else {\n params = {\n ...params,\n effectedDate: null,\n expirationDate: null,\n };\n }\n\n try {\n const response = await saveCuratedQuery(params);\n const { isSuccess, message } = response;\n if (isSuccess) {\n notification.success({\n message: 'Save curated query successfully!',\n });\n form.resetFields();\n setVisible(false);\n setStatusSubmit('error');\n\n setTimeout(() => {\n dispatch(markupActions.getCuratedQueryList(1, pageSize, ''));\n }, 200);\n } else {\n setStatusSubmit('error');\n\n notification.error({\n message: message || 'Cannot save curated query!',\n });\n }\n } catch (error) {\n setStatusSubmit('error');\n notification.error({ message: error || 'Cannot save curated query!' });\n }\n };\n\n return (\n <>\n {visible && (\n setVisible(false)}\n onCancel={() => setVisible(false)}\n destroyOnClose\n width={1100}\n maskClosable={false}\n className='modal-create-query'\n footer={[\n \n Submit\n ,\n ]}\n >\n \n \n )}\n \n );\n};\n\nAddCuratedQuery.propTypes = {};\n\nexport default AddCuratedQuery;\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { Menu, Typography, message } from 'antd';\nimport {\n BarsOutlined,\n CheckCircleTwoTone,\n DoubleRightOutlined,\n ShareAltOutlined,\n} from '@ant-design/icons';\nimport { useIntl } from 'react-intl';\n\nimport MessagesGridView from 'i18n/messages/gridView';\n\nimport Messages from 'i18n/messages/home';\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\n\nimport { getGridName } from 'utils/getGridName';\nimport { updateSearchText } from 'pages/home/utils';\n\nimport { useGetSavedConfig } from './hooks';\n\nimport { RIBBON_TYPES } from 'static/Constants';\nimport * as actionsRibbon from '@redux/ribbon/actions';\n\nimport {\n updateQueryConditions,\n updateQueryAdvance,\n updateIdQuery,\n} from 'utils/queryCondition';\nimport useGetDataIdQuery from 'hooks/useGetDataIdQuery';\n\nconst { SubMenu } = Menu;\nconst { Text } = Typography;\n\nconst SavedConfigurations = ({ disabled, setVisible, isMounted }) => {\n const dispatch = useDispatch();\n const intl = useIntl();\n\n const pathname = window.location.pathname;\n\n const idQueryActive = useGetDataIdQuery(window.location.pathname);\n\n const gridName = getGridName(pathname);\n\n const data = useGetSavedConfig(gridName, isMounted);\n\n const handleSetDefault = (item) => {\n const { query, id } = item;\n const {\n queryConditions,\n columns,\n ribbonTypes,\n searchText,\n primaryFieldsOnly,\n } = JSON.parse(query);\n dispatch(actionsGridView.myQueryDoubleClick(true));\n updateSearchText(dispatch, searchText, pathname, true, primaryFieldsOnly);\n dispatch(actionsGridView.checkQueryCondition(true));\n message.success(intl.formatMessage(MessagesGridView.applyConfig));\n\n if (ribbonTypes === RIBBON_TYPES.DETAILSVIEW) {\n dispatch(actionsGridView.chooseGridColumns(columns, id));\n } else {\n dispatch(actionsGridView.chooseGridColumns([], id));\n }\n\n updateQueryConditions(dispatch, queryConditions, window.location.pathname);\n updateQueryAdvance(dispatch, queryConditions, window.location.pathname);\n updateIdQuery(dispatch, id, window.location.pathname);\n\n dispatch(actionsRibbon.changeType(ribbonTypes));\n dispatch(actionsGridView.updateVisible(false));\n dispatch(actionsGridView.toggleRefreshQuery(true));\n };\n\n const checkApplyConfig = (item) => item.id === idQueryActive;\n\n const checkIsSharedConfig = (item) => item.isOwner === false;\n\n const data10 = data?.gridData?.slice(0, 10);\n\n return (\n \n }\n label={Messages.savedConfig}\n disabled={disabled}\n className='grid-config__button'\n />\n }\n >\n {data10?.map((item) => (\n handleSetDefault(item)}\n className='grid-config__menu--item'\n >\n {item.name}\n \n {checkApplyConfig(item) ? (\n \n ) : null}\n \n \n {checkIsSharedConfig(item) ? : null}\n \n \n ))}\n\n {data?.paging.totalRecord > 10 && (\n setVisible(true)}\n >\n \n \n \n \n )}\n \n \n );\n};\n\nexport default SavedConfigurations;\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { ClearOutlined } from '@ant-design/icons';\n\nimport { dialogFunction } from 'common/components/index';\n\nimport Messages from 'i18n/messages/home';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport { defaultSearchText } from '@redux/global/reducer';\nimport * as actionsGlobal from '@redux/global/actions';\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\n\nimport {\n updateQueryConditions,\n updateQueryAdvance,\n updateIdQuery,\n} from 'utils/queryCondition';\n\nimport useGetDataIdQuery from 'hooks/useGetDataIdQuery';\n\nconst ClearQuery = (props) => {\n const dispatch = useDispatch();\n\n const idQueryActive = useGetDataIdQuery(window.location.pathname);\n\n const confirmClearQuery = () => {\n dialogFunction({\n type: 'warn',\n content: 'Are you sure to clear current query?',\n okText: 'OK',\n cancelText: 'Cancel',\n onOk: handleClearQuery,\n });\n };\n\n const handleClearQuery = () => {\n dispatch(actionsGridView.chooseGridColumns([]));\n\n updateQueryConditions(dispatch, [], window.location.pathname);\n updateQueryAdvance(dispatch, [], window.location.pathname);\n updateIdQuery(dispatch, null, window.location.pathname);\n\n dispatch(actionsGridView.myQueryDoubleClick(true));\n dispatch(actionsGridView.checkQueryCondition(true));\n dispatch(actionsGlobal.resetSearchText(defaultSearchText));\n };\n\n return (\n }\n label={Messages.clearConfig}\n onClick={confirmClearQuery}\n className='grid-config__button'\n disabled={idQueryActive === null}\n />\n );\n};\n\nClearQuery.propTypes = {};\n\nexport default ClearQuery;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Messages from 'i18n/messages/home';\n\nimport { FormOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nconst EditControl = ({ confirmEdit }) => {\n return (\n }\n label={Messages.editUser}\n onClick={confirmEdit}\n />\n );\n};\n\nEditControl.propTypes = {\n confirmEdit: PropTypes.func,\n};\n\nexport default EditControl;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Messages from 'i18n/messages/home';\n\nimport { SaveOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nconst SaveControl = ({ confirmEdit }) => {\n return (\n }\n label={Messages.saveUser}\n onClick={confirmEdit}\n />\n );\n};\n\nSaveControl.propTypes = {\n confirmEdit: PropTypes.func,\n};\n\nexport default SaveControl;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Messages from 'i18n/messages/home';\n\nimport { DeleteOutlined } from '@ant-design/icons';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nconst CancelEdit = ({ confirmEdit }) => {\n return (\n }\n label={Messages.cancelEditUser}\n onClick={confirmEdit}\n />\n );\n};\n\nCancelEdit.propTypes = {\n confirmEdit: PropTypes.func,\n};\n\nexport default CancelEdit;\n","import React from 'react';\n\nimport RibbonButton from 'common/components/button/RibbonButton';\n\nconst ToggleUploadMediaBtn = ({\n clickActionCallback,\n label,\n icon,\n disabled,\n}) => {\n return (\n \n );\n};\n\n// AddOpenItemBtn.propTypes = {\n// clickActionCallback: PropTypes.func,\n// };\n\nexport default ToggleUploadMediaBtn;\n","import React, { useEffect } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { CloseSquareOutlined, FolderOpenOutlined } from '@ant-design/icons';\n\nimport Messages from 'i18n/messages/maintenance';\n\nimport * as maintainHelpActions from 'pages/maintenance/controllers/actions';\nimport * as maintainHelpSelectors from 'pages/maintenance/controllers/selectors';\n\nimport ToggleUploadMediaBtn from '../../controls/maintenance/help/ToggleUploadMediaBtn';\n\nconst ToggleHelpUploadMediaSection = ({ disabled }) => {\n const dispatch = useDispatch();\n\n useEffect(() => {\n if (disabled) {\n dispatch(maintainHelpActions.toggleUploadHelpMedia(false));\n }\n return;\n }, [disabled, dispatch]);\n\n const isHelpUploadMediaOpen = useSelector(\n maintainHelpSelectors.selectIsHelpUploadMediaOpen()\n );\n\n const mapStatusToIcon = () => {\n if (isHelpUploadMediaOpen) {\n return ;\n } else {\n return ;\n }\n };\n\n const mapStatusToText = () => {\n if (isHelpUploadMediaOpen) {\n return Messages.closeMedia;\n } else {\n return Messages.openMedia;\n }\n };\n\n const toggleIsHelpMediaOpen = () => {\n dispatch(maintainHelpActions.toggleUploadHelpMedia(!isHelpUploadMediaOpen));\n };\n\n return (\n {\n toggleIsHelpMediaOpen();\n }}\n disabled={disabled}\n />\n );\n};\n\nexport default ToggleHelpUploadMediaSection;\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Row, Col, message, Spin, Result } from 'antd';\nimport { cloneDeep } from 'lodash';\n\nimport { GeneratePreviewItem } from '../../index';\n\nimport { getGeneratedPreview } from 'services/digitalAsset';\n\nimport Messages from 'i18n/messages/assetPreview';\nimport { injectIntl } from 'react-intl';\n\nimport './GeneratePreviewModal.less';\n\nconst GeneratePreviewModal = (props) => {\n // props\n const {\n rootDataHook,\n selectGenerateThumbHook,\n selectedAssets,\n intl,\n loadingHook,\n } = props;\n const [\n selectedGeneratedThumb,\n setSelectedGeneratedThumb,\n ] = selectGenerateThumbHook;\n\n // state\n const [loading, setLoading] = loadingHook;\n\n // this is original data, the copy of generate thumbnail response data, use for reverting thumb\n const [orgData, setOrgData] = useState([]);\n\n // this is generate thumbnail response data, and the last data submit to update asset preview thumb\n // when user upload new thumb, this data will update\n const [rootData, setRootData] = rootDataHook;\n\n const [errorMessage, setErrorMessage] = useState(false);\n\n // function\n const handleToggleSelectItem = (id) => () => {\n const isSelected = selectedGeneratedThumb?.includes(id);\n // check if id is selected, unselect this id, else select this id\n const newSelectedGeneratedThumb = isSelected\n ? selectedGeneratedThumb.filter((item) => item !== id)\n : [...selectedGeneratedThumb, id];\n\n setSelectedGeneratedThumb(newSelectedGeneratedThumb);\n };\n\n const generateSelectedAssetId = () => {\n return (\n selectedAssets?.length > 0 &&\n selectedAssets.map((asset) => {\n return asset.id;\n })\n );\n };\n\n const setResponseData = (responseData) => {\n const responseDataId = responseData.map((data) => data.assetId);\n\n setRootData(cloneDeep(responseData));\n // create copy of response data to store independently\n setOrgData(cloneDeep(responseData));\n setSelectedGeneratedThumb(responseDataId);\n };\n\n const fetchPreview = () => {\n const selectedAssetId = generateSelectedAssetId();\n const params = {\n assetIds: selectedAssetId,\n };\n\n getGeneratedPreview(params)\n .then((response) => {\n const { isSuccess, data } = response;\n if (isSuccess && data?.data?.length) {\n setResponseData(data.data);\n } else {\n errorHandler();\n }\n })\n .catch(() => errorHandler())\n .finally(() => {\n setLoading(false);\n });\n };\n\n const errorHandler = () => {\n setErrorMessage(intl.formatMessage(Messages.generatePreviewError));\n };\n\n const updateRootData = (id, newImage) => {\n try {\n // find updated data in root data\n const updatedData = cloneDeep(\n rootData.find((data) => data.assetId === id)\n );\n\n // update image in updated data\n updatedData.data = newImage;\n\n // create new root data and update it\n const index = rootData.findIndex((data) => data.assetId === id);\n let newRootData = cloneDeep(rootData);\n\n newRootData[index] = updatedData;\n\n // update root data state\n setRootData(newRootData);\n } catch (e) {\n // handle error\n updateRootDataErrorHandler();\n }\n };\n\n const revertRootData = (id) => {\n try {\n // find revert data in orgData\n const revertData = cloneDeep(orgData.find((data) => data.assetId === id));\n\n // create new root data and update it\n const index = rootData.findIndex((data) => data.assetId === id);\n\n let newRootData = cloneDeep(rootData);\n\n newRootData[index] = revertData;\n\n // update root data state\n setRootData(newRootData);\n } catch (error) {\n updateRootDataErrorHandler(true);\n }\n };\n\n const updateRootDataErrorHandler = (isRevert) => {\n const msg = isRevert\n ? Messages.generatePreviewRevertThumbError\n : Messages.generatePreviewUpdateThumbError;\n message.error(intl.formatMessage(msg));\n };\n\n const checkPreviewItemRevertable = (id) => {\n // get image from root data\n const rootItem = rootData.find((previewItem) => {\n return previewItem.assetId === id;\n });\n // get image from original data\n const originItem = orgData.find((previewItem) => {\n return previewItem.assetId === id;\n });\n\n return rootItem && originItem && rootItem.data !== originItem.data;\n };\n\n const renderGenerateThumbnailList = () => {\n // generate render list from root data\n const renderList =\n !!rootData.length &&\n rootData.map((thumbItem) => {\n // find asset detail from selected asset items\n const assetDetail = selectedAssets.find((assetDetailItem) => {\n return assetDetailItem.id === thumbItem.assetId;\n });\n\n return {\n ...thumbItem,\n assetName: assetDetail?.assetName,\n };\n });\n\n // render\n return (\n renderList &&\n renderList.map((renderItem, index) => {\n const { assetId } = renderItem;\n const isSelected = selectedGeneratedThumb.includes(assetId);\n const revertable = checkPreviewItemRevertable(assetId);\n\n return (\n \n \n \n );\n })\n );\n };\n\n const resetData = () => {\n setOrgData([]);\n setRootData([]);\n setErrorMessage(false);\n };\n\n // did mount\n useEffect(() => {\n fetchPreview();\n\n // component unmount\n return () => {\n resetData();\n };\n // eslint-disable-next-line\n }, []);\n\n const loadingTip = intl.formatMessage(Messages.generateLoading);\n\n return (\n \n \n {!loading && !!errorMessage ? (\n \n ) : (\n renderGenerateThumbnailList()\n )}\n \n \n );\n};\n\nGeneratePreviewModal.propTypes = {\n // hook to get update root data and send it back to generate thumbnail modal\n rootDataHook: PropTypes.array,\n // hook to get selected item and send it back to generate thumbnail modal\n selectGenerateThumbHook: PropTypes.array,\n // show loading hook\n loadingHook: PropTypes.array,\n // current selected asset items\n selectedAssets: PropTypes.array,\n};\n\nGeneratePreviewModal.defaultProps = {\n handleSetSelectedItem: () => {},\n selectedAssets: [],\n};\n\nexport default injectIntl(GeneratePreviewModal);\n","import React from 'react';\n\nimport { Modal, Button } from 'antd';\n\nimport { DialogIcon } from 'common/components';\n\nimport Messages from 'i18n/messages/assetPreview';\nimport { FormattedMessage } from 'react-intl';\n\nimport './GenerateConfirmModal.less';\n\nconst GenerateConfirmModal = (props) => {\n const { visible, onYes, onNo, onCancel } = props;\n\n const modalFooter = (\n
\n \n \n \n
\n );\n\n const modalConfig = {\n visible: visible,\n wrapClassName: 'dialog-modal',\n footer: modalFooter,\n closable: false,\n };\n\n return (\n \n
\n \n
\n \n
\n
\n
\n );\n};\n\nexport default GenerateConfirmModal;\n","export const detectBrowser = () => {\n const userAgentString = navigator.userAgent;\n if (userAgentString.indexOf('Chrome') > -1) return 'Chrome';\n if (userAgentString.indexOf('Firefox') > -1) return 'Firefox';\n if (userAgentString.indexOf('Safari') > -1) return 'Safari';\n return false;\n};\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Space, Upload, Button } from 'antd';\nimport { UploadOutlined } from '@ant-design/icons';\nimport { get } from 'lodash';\n\nimport { ThumbnailItem } from 'common/components';\n\nimport {\n ACCEPT_UPLOAD_IMAGE_FILE_TYPE,\n BROWSER_NOT_SUPPORTED_IMAGE_TYPES,\n} from 'static/Constants';\nimport { detectBrowser } from 'utils/browser';\n\nimport Messages from 'i18n/messages/assetPreview';\nimport { FormattedMessage } from 'react-intl';\n\nconst GeneratePreviewItem = (props) => {\n const {\n selected,\n item,\n handleToggleSelectItem,\n updateRootData,\n revertRootData,\n revertable,\n } = props;\n const { data, assetId, assetName } = item;\n\n const [imageError, setImageError] = useState(false);\n const [imageLoading, setImageLoading] = useState(false);\n\n // function\n const handleClickUploadButton = (info) => {\n let imageFile = get(info, 'file.originFileObj', false);\n\n // parse to base64\n const fileReader = new FileReader();\n fileReader.onloadstart = () => {\n // show loading\n setImageError(false);\n setImageLoading(true);\n };\n fileReader.onloadend = (e) => {\n const imageSrc = e.target.result;\n const image = new Image();\n image.src = imageSrc;\n\n updateRootData(assetId, imageSrc);\n\n image.onload = onImageLoadHandler;\n\n image.onerror = onImageErrorHandler(imageFile);\n };\n fileReader.readAsDataURL(imageFile);\n };\n\n const onImageLoadHandler = () => {\n setImageLoading(false);\n };\n\n const onImageErrorHandler = (imageFile) => () => {\n setImageErrorMessage(imageFile);\n setImageLoading(false);\n };\n\n const setImageErrorMessage = (imageFile) => {\n const fileType = imageFile.type;\n const browser = detectBrowser();\n const notSupportedImageType =\n browser && BROWSER_NOT_SUPPORTED_IMAGE_TYPES[browser];\n\n let errorMessage = Messages.generateLoadImageError;\n if (browser && notSupportedImageType?.includes(fileType)) {\n errorMessage = Messages.generateLoadImageBrowserError;\n }\n\n setImageError(errorMessage);\n };\n\n const handleClickRevertButton = () => {\n setImageError(false);\n revertRootData(assetId);\n };\n // variable\n const classNamePrefix = 'generate-preview__item';\n return (\n \n \n \n {}}\n >\n \n \n \n \n \n );\n};\n\nGeneratePreviewItem.propTypes = {\n /**\n * is selected item\n */\n selected: PropTypes.bool,\n /**\n * item data\n */\n data: PropTypes.object,\n /**\n * handle toggle select item\n */\n handleToggleSelectItem: PropTypes.func,\n /**\n * handle update root data when item update new image\n */\n updateRootData: PropTypes.func,\n /**\n * handle update root data when item revert image\n */ revertRootData: PropTypes.func,\n /**\n * enable revert button\n */\n revertable: PropTypes.bool,\n};\n\nexport default GeneratePreviewItem;\n","import React, { useState, useEffect } from 'react';\nimport { useSelector } from 'react-redux';\n\nimport {\n Skeleton,\n Table,\n Button,\n Space,\n Typography,\n Result,\n Empty,\n} from 'antd';\nimport { UserOutlined, TeamOutlined } from '@ant-design/icons';\nimport { DeleteButton } from 'common/components';\n\nimport gridSelectors from 'common/components/grid-view/controllers/selectors';\n\nimport { getShareList } from 'services/manageSharing';\nimport { formatMDY } from 'utils/formatDate';\nimport { entityTypeIconRenderer } from 'static/Icons';\n\nimport Messages from 'i18n/messages/share';\nimport { injectIntl } from 'react-intl';\n\nimport './ManageShareModal.less';\n\nconst { Text } = Typography;\n\nconst ManageShareModal = (props) => {\n const shareWithIcons = {\n user: (props) => ,\n member: (props) => ,\n };\n\n const pageSize = 10;\n\n //* props\n const {\n intl,\n selectedRowHook,\n shareListHook,\n removeShareItem,\n reloadListHook,\n } = props;\n\n const selectedItemList = useSelector(\n gridSelectors.makeSelectDetailCurrentITemsSelection()\n );\n\n //* state\n const [loading, setLoading] = useState(true);\n const [listLoading, setListLoading] = useState(false);\n const [shareList, setShareList] = shareListHook;\n const [pageIndex, setPageIndex] = useState(1);\n const [total, setTotal] = useState(0);\n const [error, setError] = useState(false);\n const [selectedRow, setSelectedRow] = selectedRowHook;\n const [reloadList, setReloadListHook] = reloadListHook;\n\n //* function\n const fetchData = (pageIndex) => {\n const params = generateGetShareListParams(pageIndex);\n getShareList(params)\n .then((response) => {\n const { data, isSuccess } = response;\n if (isSuccess) {\n setShareList(data?.gridData || []);\n setTotal(data?.paging?.totalRecord);\n } else {\n fetchDataErrorHandler();\n }\n })\n .catch(() => {\n fetchDataErrorHandler();\n })\n .finally(() => {\n setLoading(false);\n setListLoading(false);\n setReloadListHook(false);\n });\n };\n\n const generateGetShareListParams = (pageIndex) => {\n const entities =\n selectedItemList?.length &&\n selectedItemList.map((item) => {\n const { type, id } = item;\n return {\n entityType: type,\n id,\n };\n });\n\n return {\n entities,\n pageIndex,\n pageSize,\n sort: [],\n filters: [],\n };\n };\n\n const fetchDataErrorHandler = () => {\n setError(true);\n };\n\n const generateColumns = () => {\n return [\n {\n title: intl.formatMessage(Messages.entityHeading),\n dataIndex: 'sharedName',\n key: 'sharedName',\n ellipsis: true,\n render: renderEntityColumn,\n },\n {\n title: intl.formatMessage(Messages.shareWithHeading),\n dataIndex: 'with',\n key: 'with',\n ellipsis: true,\n render: renderShareWithColumn,\n },\n {\n title: intl.formatMessage(Messages.shareAtHeading),\n dataIndex: 'dateShare',\n key: 'dateShare',\n align: 'center',\n width: '200px',\n render: (text) => {\n return text ? formatMDY(text) : null;\n },\n },\n {\n title: '',\n dataIndex: 'remove',\n key: 'remove',\n align: 'right',\n width: '50px',\n render: renderRemoveColumn,\n },\n ];\n };\n\n const renderEntityColumn = (text, record) => {\n const { shareType } = record;\n\n const Icon = (props) => {\n return entityTypeIconRenderer(shareType, props);\n };\n\n return (\n \n \n {text}\n \n );\n };\n\n const renderShareWithColumn = (text, record) => {\n const { userFullName, memberFullName } = record;\n const type = !!userFullName ? 'user' : 'member';\n\n const Icon = shareWithIcons[type];\n const displayName = !!userFullName ? userFullName : memberFullName;\n return (\n \n \n {displayName}\n \n );\n };\n\n const renderRemoveColumn = (text, record) => {\n const { isEditable } = record;\n return isEditable ? (\n }\n onClick={onRemoveBtnClick(record)}\n />\n ) : null;\n };\n\n const onRemoveBtnClick = (record) => () => {\n const deleteShareList = [record];\n removeShareItem(deleteShareList);\n };\n\n const onSelectChange = (selectedRowKeys) => {\n setSelectedRow(selectedRowKeys);\n };\n\n const handleShareListTableChange = (pagination, filters, sorter, extra) => {\n const { current } = pagination;\n\n setListLoading(true);\n setPageIndex(current);\n fetchData(current);\n };\n\n const renderShareList = () => {\n const rowSelection = {\n selectedRowKeys: selectedRow,\n onChange: onSelectChange,\n columnWidth: '40px',\n };\n\n const paginationConfigs = {\n position: ['bottomLeft'],\n current: pageIndex,\n total: total,\n pageSize: pageSize,\n };\n\n return (\n \n );\n };\n\n //* did mount\n useEffect(() => {\n fetchData(pageIndex);\n }, []);\n\n useEffect(() => {\n if (reloadList) {\n setListLoading(true);\n fetchData(pageIndex);\n }\n // eslint-disable-next-line\n }, [reloadList]);\n\n return (\n \n {error ? (\n \n ) : shareList.length ? (\n renderShareList()\n ) : (\n \n )}\n \n );\n};\n\nexport default injectIntl(ManageShareModal);\n","import { useState, useEffect } from 'react';\n\nimport { useSelector } from 'react-redux';\n\nimport gridViewSelectors from 'common/components/grid-view/controllers/selectors';\n\nimport {\n pathnameFavMember,\n pathnameFavAssets,\n pathnameFavFolders,\n pathnameFavProducts,\n pathnameProduct,\n pathnameMember,\n pathnameDigitalMedia,\n pathnameDigitalMediaNew,\n pathnameAssets,\n pathnameDocument,\n pathnameMultiMedia,\n pathnameReportings,\n pathnameReportingsOwned,\n pathnameReportingsShared,\n pathnameFolders,\n pathnameFoldersOwned,\n pathnameFoldersShared,\n pathnameAssetsForMember,\n pathnameProductsForMember,\n} from 'static/Constants';\n\nconst useGetDataAdvanceFilter = (pathname) => {\n const [state, setState] = useState([]);\n\n const favMembersQueryAdvance = useSelector(\n gridViewSelectors.makeSelectFavMembersQueryAdvance()\n );\n const favAssetsQueryAdvance = useSelector(\n gridViewSelectors.makeSelectFavAssetsQueryAdvance()\n );\n const favFoldersQueryAdvance = useSelector(\n gridViewSelectors.makeSelectFavFoldersQueryAdvance()\n );\n const favProductsQueryAdvance = useSelector(\n gridViewSelectors.makeSelectFavProductsQueryAdvance()\n );\n const productsQueryAdvance = useSelector(\n gridViewSelectors.makeSelectProductsQueryAdvance()\n );\n const membersQueryAdvance = useSelector(\n gridViewSelectors.makeSelectMembersQueryAdvance()\n );\n const digitalMediaQueryAdvance = useSelector(\n gridViewSelectors.makeSelectDigitalMediaQueryAdvance()\n );\n const digitalMediaNewQueryAdvance = useSelector(\n gridViewSelectors.makeSelectDigitalMediaNewQueryAdvance()\n );\n const assetsQueryAdvance = useSelector(\n gridViewSelectors.makeSelectAssetsQueryAdvance()\n );\n const documentsQueryAdvance = useSelector(\n gridViewSelectors.makeSelectDocumentsQueryAdvance()\n );\n const multiMediaQueryAdvance = useSelector(\n gridViewSelectors.makeSelectMultiMediaQueryAdvance()\n );\n const reportingsQueryAdvance = useSelector(\n gridViewSelectors.makeSelectReportingsQueryAdvance()\n );\n const myReportsQueryAdvance = useSelector(\n gridViewSelectors.makeSelectMyReportsQueryAdvance()\n );\n const reportsSharedToMeQueryAdvance = useSelector(\n gridViewSelectors.makeSelectReportsSharedToMeQueryAdvance()\n );\n const foldersQueryAdvance = useSelector(\n gridViewSelectors.makeSelectFoldersQueryAdvance()\n );\n const myFoldersQueryAdvance = useSelector(\n gridViewSelectors.makeSelectMyFoldersQueryAdvance()\n );\n const foldersSharedToMeQueryAdvance = useSelector(\n gridViewSelectors.makeSelectFoldersSharedToMeQueryAdvance()\n );\n const assetsForMemberQueryAdvance = useSelector(\n gridViewSelectors.makeSelectAssetsForMemberQueryAdvance()\n );\n const productsForMemberQueryAdvance = useSelector(\n gridViewSelectors.makeSelectProductsForMemberQueryAdvance()\n );\n\n useEffect(() => {\n let data = [];\n\n switch (pathname) {\n case pathnameFavMember:\n data = favMembersQueryAdvance;\n break;\n case pathnameFavAssets:\n data = favAssetsQueryAdvance;\n break;\n case pathnameFavFolders:\n data = favFoldersQueryAdvance;\n break;\n case pathnameFavProducts:\n data = favProductsQueryAdvance;\n break;\n case pathnameProduct:\n data = productsQueryAdvance;\n break;\n case pathnameMember:\n data = membersQueryAdvance;\n break;\n case pathnameDigitalMedia:\n data = digitalMediaQueryAdvance;\n break;\n case pathnameDigitalMediaNew:\n data = digitalMediaNewQueryAdvance;\n break;\n case pathnameAssets:\n data = assetsQueryAdvance;\n break;\n case pathnameDocument:\n data = documentsQueryAdvance;\n break;\n case pathnameMultiMedia:\n data = multiMediaQueryAdvance;\n break;\n case pathnameReportings:\n data = reportingsQueryAdvance;\n break;\n case pathnameReportingsOwned:\n data = myReportsQueryAdvance;\n break;\n case pathnameReportingsShared:\n data = reportsSharedToMeQueryAdvance;\n break;\n case pathnameFolders:\n data = foldersQueryAdvance;\n break;\n case pathnameFoldersOwned:\n data = myFoldersQueryAdvance;\n break;\n case pathnameFoldersShared:\n data = foldersSharedToMeQueryAdvance;\n break;\n default:\n break;\n }\n if (pathname.includes(pathnameAssetsForMember)) {\n data = assetsForMemberQueryAdvance;\n }\n if (pathname.includes(pathnameProductsForMember)) {\n data = productsForMemberQueryAdvance;\n }\n setState(data);\n }, [\n pathname,\n favMembersQueryAdvance,\n favAssetsQueryAdvance,\n favFoldersQueryAdvance,\n favProductsQueryAdvance,\n productsQueryAdvance,\n membersQueryAdvance,\n digitalMediaQueryAdvance,\n digitalMediaNewQueryAdvance,\n assetsQueryAdvance,\n documentsQueryAdvance,\n multiMediaQueryAdvance,\n reportingsQueryAdvance,\n myReportsQueryAdvance,\n reportsSharedToMeQueryAdvance,\n foldersQueryAdvance,\n myFoldersQueryAdvance,\n foldersSharedToMeQueryAdvance,\n assetsForMemberQueryAdvance,\n productsForMemberQueryAdvance,\n ]);\n\n return state;\n};\n\nexport default useGetDataAdvanceFilter;\n","import React, { useState } from 'react';\nimport { FileAddOutlined } from '@ant-design/icons';\n\nimport { ButtonSmallIcon } from 'common/components';\nimport CreateProductViaFormModal from 'common/components/product-add/CreateProductViaFormModal';\n\nconst AddProductFromMember = (props) => {\n const [addModalVisible, setAddModalVisible] = useState(false);\n\n return (\n <>\n {addModalVisible && (\n \n )}\n\n }\n label={'Create Product'}\n onClick={() => setAddModalVisible(true)}\n disabled={props.disabled}\n />\n \n );\n};\n\nAddProductFromMember.propTypes = {};\n\nexport default AddProductFromMember;\n","import React from 'react';\nimport { DownloadOutlined } from '@ant-design/icons';\nimport { notification } from 'antd';\n\nimport { ButtonSmallIcon } from 'common/components';\n\nimport {\n getProductViaSpreadSheet,\n getTdcProductViaSpreadSheet,\n} from 'services/product';\nimport { saveFile } from 'utils/saveFile';\n\nconst DownloadProductTemplateFromMember = (props) => {\n const handleDownloadTemplateProduct = (type) => async () => {\n try {\n const response =\n type === 'tdc'\n ? await getTdcProductViaSpreadSheet()\n : await getProductViaSpreadSheet();\n\n const urlPath = type === 'tdc' ? 'fileUrl' : 'url';\n\n if (response.isSuccess) {\n saveFile(response.data[urlPath]);\n } else {\n notification.error({\n message: response.data.message,\n });\n }\n } catch (error) {\n console.log(error);\n }\n };\n\n return (\n }\n label={'Download Template'}\n onClick={handleDownloadTemplateProduct('pim')}\n disabled={props.disabled}\n />\n );\n};\n\nDownloadProductTemplateFromMember.propTypes = {};\n\nexport default DownloadProductTemplateFromMember;\n","import React, { useState, useEffect } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useIntl } from 'react-intl';\n\nimport { UploadOutlined } from '@ant-design/icons';\nimport { notification, Modal } from 'antd';\n\nimport { ButtonSmallIcon, UploadFile } from 'common/components';\nimport ErrorModal from 'common/components/product-publication-setup/ErrorModal.js';\n\nimport {\n usePermissionEditSharedProduct,\n useCheckIsSuperAdmin,\n useCheckPermissions,\n} from 'hooks';\n\nimport { PERMISSION_EDIT_PRODUCTS } from 'static/Permission';\nimport { UPLOAD_MAX_SIZE } from 'static/Constants';\n\nimport {\n IMPORT_PRODUCT_VIA_SPREADSHEET,\n IMPORT_TDC_PRODUCT_VIA_SPREADSHEET,\n} from 'services/product/endpoints';\n\nimport * as brandingActions from '@redux/branding/actions';\n\nimport messagesProduct from 'i18n/messages/product';\n\nconst UploadProductTemplateFromMember = (props) => {\n const [visibleModal, setVisibleModal] = useState(false);\n const [updateType, setUploadType] = useState('pim');\n\n const isSuperAdmin = useCheckIsSuperAdmin();\n\n const hasPermissionEditProducts = useCheckPermissions(\n PERMISSION_EDIT_PRODUCTS\n );\n\n const hasPermissionEditSharedProduct = usePermissionEditSharedProduct();\n\n const isAllowActionsPim =\n isSuperAdmin || hasPermissionEditProducts || hasPermissionEditSharedProduct;\n\n const onClickUploadTemplate = (type) => () => {\n setVisibleModal(true);\n setUploadType(type);\n };\n\n return (\n <>\n {visibleModal && (\n setVisibleModal(false)}\n type={updateType}\n memberId={props.memberId}\n />\n )}\n }\n label={'Upload Template'}\n onClick={onClickUploadTemplate('pim')}\n disabled={!isAllowActionsPim}\n />\n \n );\n};\n\nconst ModalUploadTemplateProduct = (props) => {\n const { visibleModal, turnOffModal, type, memberId } = props;\n const [errorList, setErrorList] = useState([]);\n\n useEffect(() => {\n if (!visibleModal) setErrorList([]);\n }, [visibleModal]);\n\n const dispatch = useDispatch();\n const intl = useIntl();\n\n const handleResponseUpload = (response) => {\n const successMessage =\n type === 'tdc'\n ? messagesProduct.uploadTdcSuccess\n : messagesProduct.createProductSuccess;\n\n if (response?.data) {\n if (response?.data?.isSuccess) {\n notification.success({\n message: intl.formatMessage(successMessage),\n });\n\n turnOffModal();\n\n if (type === 'tdc') return;\n\n dispatch(brandingActions.getBrandingNoLoading());\n } else {\n if (response?.data?.errors) {\n setErrorList(response?.data?.errors);\n }\n }\n }\n };\n\n const apiUrl =\n type === 'tdc'\n ? IMPORT_TDC_PRODUCT_VIA_SPREADSHEET\n : IMPORT_PRODUCT_VIA_SPREADSHEET;\n\n const nameFormData = type === 'tdc' ? 'file' : 'TemplateFile';\n\n return (\n \n
\n handleResponseUpload(response)}\n maxSize={UPLOAD_MAX_SIZE.GENERAL}\n additionalBodyPayload={{\n memberId: memberId,\n }}\n supportTypes={['xlsx', 'xls']}\n />\n
\n {errorList && errorList.length > 0 && (\n \n )}\n
\n
\n \n );\n};\n\nUploadProductTemplateFromMember.propTypes = {};\n\nexport default UploadProductTemplateFromMember;\n","import React from 'react';\nimport { Divider } from 'antd';\n\nconst RibbtonSectionDivider = () => {\n return ;\n};\n\nexport default RibbtonSectionDivider;\n","// import ribbon components\nimport Favorite from './sections/home-grid/Favorite';\nimport View from './sections/home-grid/ViewLayout';\nimport Folder from './sections/home-grid/Folder';\nimport Search from './sections/home-grid/SearchLayout';\nimport Grid from './sections/home-grid/GridLayout';\nimport Other from './sections/home-grid/OtherLayout';\n\nimport Addition from './controls/home/Addition';\nimport AddFolder from './controls/home/AddFolder';\nimport Detail from './controls/home/DetailView';\nimport QuickView from './controls/home/QuickView';\nimport SearchFolder from './controls/home/SearchFolder';\nimport DeleteFolder from './controls/home/DeleteFolder';\nimport ViewAlt from './controls/home/InlineControl';\nimport SearchAlt from './controls/home/Search';\nimport BackAlt from './controls/home/Back';\nimport AdvanceSearch from './controls/home/AdvanceSearch';\nimport GridColumns from './controls/home/grid-query/GridColumns';\nimport SaveGrid from './controls/home/grid-query/SaveGrid';\nimport AddCuratedQuery from './controls/home/grid-query/AddCuratedQuery';\nimport ManageGridQuery from './controls/home/grid-query/ManageGridQuery';\nimport SavedConfigurations from './controls/home/grid-query/SavedConfigurations';\nimport ClearQuery from './controls/home/grid-query/ClearQuery';\nimport EditMember from './sections/member-full/EditMember';\nimport BrandImage from './sections/member-full/BrandImage';\nimport ToggleHelpUploadMediaSection from './sections/post-full/ToggleHelpUploadMediaSection';\nimport ToggleEulaUploadMediaSection from './sections/eula-full/ToggleEulaUploadMediaSection';\nimport ToggleTagLineUploadMediaSection from './sections/member-full/ToggleTagLineUploadMediaSection';\n\nimport OpenAsset from './controls/asset/OpenAsset';\n\nimport GeneratePreviewModal from './modal/generate-preview/GeneratePreviewModal';\nimport GenerateConfirmModal from './modal/generate-confirm/GenerateConfirmModal';\nimport GeneratePreviewItem from './modal/generate-preview/GeneratePreviewItem';\nimport ManageShareModal from './modal/manage-share/ManageShareModal';\nimport ManageShareModalToolbar from './modal/manage-share/ManageShareModalToolbar';\n\nimport AdvanceFilter from './controls/home/AdvanceFilter';\nimport AdvanceStack from './controls/home/AdvanceStack';\nimport PimActions from './controls/home/PimActions';\nimport GridConfig from './sections/home-grid/GridConfig';\n\nimport ManageSharingSection from '../components/sections/shared/ManageSharingSection';\nimport DetailSection from '../components/sections/home-grid/DetailSection';\n\n//? ribbon btn divider\nimport RibbonSectionDivider from './ribbbonSectionDivider/RibbonSectionDivider';\n\n// export ribbon component\n\nexport { EditMember, BrandImage };\n\nexport const FavoriteLayout = Favorite;\nexport const ViewLayout = View;\nexport const FolderLayout = Folder;\nexport const SearchLayout = Search;\nexport const GridLayout = Grid;\nexport const OtherLayout = Other;\n\nexport const AdditionControl = Addition;\nexport const AddFolderControl = AddFolder;\nexport const DetailControl = Detail;\nexport const QuickViewControl = QuickView;\nexport const ViewLayoutControl = ViewAlt;\nexport const SearchFolderControl = SearchFolder;\nexport const DeleteFolderControl = DeleteFolder;\nexport const SearchControl = SearchAlt;\nexport const BackControl = BackAlt;\nexport const AdvanceSearchControl = AdvanceSearch;\nexport const GridColumnsControl = GridColumns;\nexport const SaveGridControl = SaveGrid;\nexport const AddCuratedQueryControl = AddCuratedQuery;\nexport const ManageQuery = ManageGridQuery;\n\nexport const OpenAssetControl = OpenAsset;\n\nexport {\n GeneratePreviewModal,\n GeneratePreviewItem,\n GenerateConfirmModal,\n ManageShareModal,\n ManageShareModalToolbar,\n ToggleHelpUploadMediaSection,\n ToggleEulaUploadMediaSection,\n ToggleTagLineUploadMediaSection,\n SavedConfigurations,\n AdvanceFilter,\n ClearQuery,\n AdvanceStack,\n PimActions,\n GridConfig,\n RibbonSectionDivider,\n ManageSharingSection,\n DetailSection,\n};\n","import React from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\n\nimport { ControlOutlined } from '@ant-design/icons';\n\nimport ButtonSmallIcon from 'common/components/button/ButtonSmallIcon';\n\nimport selectorsGridView from 'common/components/grid-view/controllers/selectors';\n\nimport * as actionGlobal from '@redux/global/actions';\nimport * as selectorsGlobal from '@redux/global/selectors';\n\nimport { useGlobalModal } from 'hooks';\n\nimport Messages from 'i18n/messages/home';\n\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\n\nimport * as actions from '@redux/global/actions';\n\nconst ManageGridQuery = (props) => {\n const dispatch = useDispatch();\n\n const isAddToFolderShow = useSelector(\n selectorsGlobal.selectShowAddToFolder()\n );\n const isDetailShow = useSelector(selectorsGridView.makeSelectVisible());\n\n const { MODAL_NAMES, openModal } = useGlobalModal();\n\n const openModalManageQueries = () => {\n if (isAddToFolderShow) dispatch(actionGlobal.toggleAddToFolder());\n if (isDetailShow) dispatch(actionsGridView.updateVisible(false));\n dispatch(actions.hideDetail());\n openModal(MODAL_NAMES.MANAGE_QUERIES);\n };\n return (\n <>\n }\n label={Messages.manageConfig}\n onClick={openModalManageQueries}\n className='grid-config__button'\n />\n \n );\n};\n\nexport default ManageGridQuery;\n","import React, { useEffect, useRef, useMemo } from 'react';\n\nimport { Row, Col, Space, Checkbox, Input } from 'antd';\n\nimport {\n getAllExpandKeys,\n getTreeData,\n compareExpandKey,\n} from 'utils/exportProductProperties';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/product';\n\nconst { Search } = Input;\n\nconst CopyProductToolbar = (props) => {\n const intl = useIntl();\n const expandKeysRef = useRef([]);\n\n const {\n visible,\n dataSource,\n leftExpandedKeys,\n setLeftExpandedKeys,\n setIsShowSelection,\n isSameSize,\n onChangeSameSize,\n isSameStyleFlavor,\n onChangeSameStyleFlavor,\n isHeaderOnly,\n onChangeHeaderOnly,\n isCopyAllPopulated,\n setIsCopyAllPopulated,\n searchHook,\n disabled,\n } = props;\n\n const [searchText, setSearchText] = searchHook;\n\n const isExpandedAll = useMemo(\n () => compareExpandKey(leftExpandedKeys, expandKeysRef.current, visible),\n [leftExpandedKeys, visible]\n );\n\n const onSearch = (value) => {\n setSearchText(value);\n };\n\n const onChangeExpandAll = (e) => {\n const checked = e.target.checked;\n if (checked) setLeftExpandedKeys(expandKeysRef.current);\n else setLeftExpandedKeys([]);\n };\n\n const onChangeShowSelection = (e) => {\n const checked = e.target.checked;\n setIsShowSelection(checked);\n };\n\n const onChangeCopyAllPopulated = (e) => {\n const checked = e.target.checked;\n setIsCopyAllPopulated(checked);\n };\n\n const initExpandKeys = () => {\n const treeData = getTreeData(dataSource);\n const allExpandKeys = getAllExpandKeys(treeData);\n expandKeysRef.current = allExpandKeys;\n };\n\n useEffect(() => {\n initExpandKeys();\n }, [dataSource]);\n\n return (\n \n \n \n \n \n\n \n\n \n \n \n {intl.formatMessage(Messages.exportPropertiesExpandAll)}\n \n \n \n \n \n \n \n \n \n Header Only\n
\n \n Same Size\n
\n \n Same Style/Flavor\n
\n \n Copy All Populated\n \n \n \n \n \n );\n};\n\nexport default CopyProductToolbar;\n","import React from 'react';\nimport { Typography, List, Avatar } from 'antd';\n\nimport { Images } from 'config/assets';\n\nimport classnames from 'classnames';\n\nimport './CopyProductResult.less';\n\nconst { Title } = Typography;\n\nconst CopyProductResult = (props) => {\n const { listData = [] } = props;\n\n return (\n
\n Please check list of copied products:\n
\n {\n return (\n \n \n \n
\n }\n title={\n \n {`RIVIR ID: ${item.rivirId}`}\n \n }\n />\n \n );\n }}\n />\n
\n \n );\n};\n\nexport default CopyProductResult;\n","import { useMemo } from 'react';\n\nimport _ from 'lodash';\n\nimport * as productServices from 'services/product';\nimport { NUMERIC_TYPE } from 'static/Constants';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/product';\nimport { useQuery } from '@tanstack/react-query';\n\nconst KEY_COPY_PRODUCT = {\n GET_PROPERTIES_FOR_COPY_PRODUCT: ['pim', 'copy-product-item'],\n};\n\nconst useGetPropertiesForCopyProduct = (visible) =>\n useQuery({\n queryKey: KEY_COPY_PRODUCT.GET_PROPERTIES_FOR_COPY_PRODUCT,\n queryFn: async () => {\n const response = await productServices.getPropertiesForCopyProduct();\n if (response?.isSuccess) {\n return response?.data?.properties;\n } else {\n throw new Error(response?.message);\n }\n },\n enabled: visible,\n retry: false,\n });\n\nexport const useGetProductPropertiesToCopy = (visible) => {\n const intl = useIntl();\n\n const noHeaderLabel = intl.formatMessage(\n Messages.exportProductPropertiesNoHeaderTitle\n );\n\n const { status: loadingStatus, data: rootData } =\n useGetPropertiesForCopyProduct(visible);\n\n const generateSourceData = (data) => {\n if (!data) return [];\n const moduleData = generateModuleData(data);\n const propertyItemData = generatePropertyItemData(moduleData, data);\n const objectTypePropertyData =\n generateOjectTypePropertiesData(propertyItemData);\n\n return [...moduleData, ...objectTypePropertyData, ...propertyItemData];\n };\n\n const generateModuleData = (data) => {\n if (!data) return [];\n const moduleData = data.map((propertyItem) => {\n return {\n key: propertyItem.moduleName || 'noHeader',\n title: propertyItem.moduleDisplayName || noHeaderLabel,\n type: 'group',\n };\n });\n\n const uniqData = _.uniqBy(moduleData, 'key');\n\n return uniqData;\n };\n\n const generatePropertyItemData = (moduleData, data) => {\n if (!moduleData || !data) return;\n\n const formattedPropertiesData = data.map((propertyItem) => {\n const { dataType, displayName, fieldFullPath, fieldName } = propertyItem;\n\n let changeInt;\n if (NUMERIC_TYPE.includes(dataType?.toLowerCase())) changeInt = 'Number';\n\n const propertyModuleName =\n propertyItem.moduleDisplayName || noHeaderLabel;\n\n const modulePath = moduleData.find((moduleItem) => {\n return moduleItem.title === propertyModuleName;\n })?.key;\n const propertyPathArray = fieldFullPath.split('.');\n //* remove the first path as it is module path\n if (propertyItem.moduleDisplayName) propertyPathArray.shift();\n\n const realPropertyPath = propertyPathArray.join('.');\n const formattedPropertyPath = modulePath + '.' + realPropertyPath;\n\n return {\n key: formattedPropertyPath,\n data: {\n displayName,\n fieldName,\n fieldFullPath,\n dataType: changeInt ?? dataType,\n },\n };\n });\n return formattedPropertiesData;\n };\n\n const generateOjectTypePropertiesData = (propertiesData) => {\n if (!propertiesData) return [];\n const objectTypePropertyData = [];\n propertiesData.forEach((propertyItem) => {\n const paths = propertyItem.key.split('.');\n if (paths.length <= 2) return;\n let pathString = '';\n\n for (let i = 0; i < paths.length - 1; i++) {\n pathString += paths[i];\n\n const isPathStringAdded = objectTypePropertyData.find(\n (propertyObjectItem) => propertyObjectItem.key === pathString\n );\n\n if (!isPathStringAdded && pathString.includes('.')) {\n objectTypePropertyData.push({\n key: pathString,\n fieldName: paths[i],\n title: _.startCase(paths[i]),\n type: 'object',\n });\n }\n pathString += '.';\n }\n });\n return objectTypePropertyData;\n };\n\n const sourceData = useMemo(() => {\n return generateSourceData(rootData);\n }, [rootData]);\n\n return { rootData, sourceData, loadingStatus };\n};\n","import React, { useState, useEffect, useRef, useMemo } from 'react';\n\nimport {\n Typography,\n Row,\n Col,\n Modal,\n notification,\n Result,\n InputNumber,\n Space,\n} from 'antd';\n\nimport ExportPropertiesTree from './ExportPropertiesTree';\nimport CopyProductToolbar from './CopyProductToolbar';\nimport CopyProductResult from './CopyProductResult';\n\nimport * as productServices from 'services/product';\nimport { useGetProductPropertiesToCopy } from 'hooks/copyProductPropertiesHooks';\nimport {\n WithLoading,\n CustomizeTransfer,\n dialogFunction,\n} from 'common/components';\n\nimport { useGetProductItemModules } from 'pages/product-full-view/components/product-detail-view/hooks';\nimport {\n useQueryFactsPanel,\n useQuerySupplementFactsPanel,\n useQueryDrugFactsPanel,\n useQueryPetFoodPanel,\n} from 'pages/product-full-view/components/product-media-area/multiple-panel/facts-panel/useQueryFactsPanel';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/product';\nimport { useMutation } from '@tanstack/react-query';\nimport { isArray, isObject, union } from 'lodash';\n\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\nimport { useDispatch } from 'react-redux';\nimport { useGlobalModal } from 'hooks';\n\nimport * as actionsGridView from 'common/components/grid-view/controllers/actions';\n\nimport { KEY_COPY_PROPERTIES } from 'static/Constants';\n\nimport './BulkEditProduct.less';\n\nconst { Title } = Typography;\n\nconst CopyProductPropertiesModal = (props) => {\n const dispatch = useDispatch();\n const intl = useIntl();\n const addedKeysRef = useRef([]);\n const reloadPage = useDispatchReloadPage();\n\n const { productId } = props;\n\n const { closeModal, checkModalVisible, MODAL_NAMES } = useGlobalModal();\n\n const isModalOpen = checkModalVisible(MODAL_NAMES.COPY_PRODUCT_MODAL);\n\n const [leftExpandedKeys, setLeftExpandedKeys] = useState([]);\n const [isShowSelection, setIsShowSelection] = useState(false);\n const [isHeaderOnly, setIsHeaderOnly] = useState(false);\n const [isSameSize, setIsSameSize] = useState(false);\n const [isSameStyleFlavor, setIsSameStyleFlavor] = useState(false);\n const [isCopyAllPopulated, setIsCopyAllPopulated] = useState(false);\n const searchHook = useState('');\n const [searchText, setSearchText] = searchHook;\n const [submitDisabled, setSubmitDisabled] = useState(true);\n const [numberOfCopies, setNumberOfCopies] = useState(1);\n const [keyHeaderOnly, setKeyHeaderOnly] = useState([]);\n const [keySameSize, setKeySameSize] = useState([]);\n const [keySameStyle, setKeySameStyle] = useState([]);\n\n const { sourceData, rootData, loadingStatus } =\n useGetProductPropertiesToCopy(isModalOpen);\n\n const productItemQuery = useGetProductItemModules(productId, true);\n const { productItemModules, statusFetchProductItem: moduleStatus } =\n productItemQuery;\n\n const { listFactsPanel, isLoading: loadingFacts } = useQueryFactsPanel({\n id: productId,\n });\n const { listSupplementFactsPanel, isLoading: loadingSupFacts } =\n useQuerySupplementFactsPanel({\n id: productId,\n });\n const { listDrugFactsPanel, isLoading: loadingDrugFacts } =\n useQueryDrugFactsPanel({\n id: productId,\n });\n\n const { listPetFoodPanel, isLoading: loadingPetFood } = useQueryPetFoodPanel({\n id: productId,\n });\n\n const copyMutation = useMutation({\n mutationFn: productServices.copyProductItem,\n });\n\n const onOk = () => {\n dialogFunction({\n type: 'warn',\n okButtonProps: {\n loading: copyMutation.isLoading,\n },\n content: `Do you want to copy ${numberOfCopies} product(s)?`,\n onOk: callApiCopyProperties,\n });\n };\n\n const onCancel = () => {\n closeModal(MODAL_NAMES.COPY_PRODUCT_MODAL);\n };\n\n const onTransferChange = (addedKeys) => {\n addedKeysRef.current = addedKeys;\n setSubmitDisabled(!addedKeys.length);\n };\n\n const callApiCopyProperties = () => {\n const properties = getPropertyFieldName({\n data: sourceData,\n addedKeys: addedKeysRef.current,\n });\n const params = {\n productItemId: productId,\n numberOfCopies: numberOfCopies,\n isPopulated: isCopyAllPopulated,\n selectedColumns: properties,\n };\n\n copyMutation.mutate(params, {\n onSuccess: async (result) => {\n if (result?.isSuccess) {\n dialogFunction({\n type: 'info',\n content: (\n \n ),\n cancelButtonProps: {\n hidden: true,\n },\n });\n reloadPage();\n dispatch(actionsGridView.deleteItemsSelection());\n } else {\n notification.error({\n message:\n result?.message ||\n result?.data?.message ||\n intl.formatMessage(Messages.copyProductPropertiesError),\n });\n }\n closeModal(MODAL_NAMES.COPY_PRODUCT_MODAL);\n },\n onError: () => {\n notification.error({\n message: intl.formatMessage(Messages.copyProductPropertiesError),\n });\n },\n });\n };\n\n const getPropertyFieldName = ({ data, addedKeys }) => {\n return addedKeys.reduce((accumulator, currentAddedKeys) => {\n const addedPropertyData = data.find((propertyItem) => {\n return propertyItem.key === currentAddedKeys;\n });\n const fieldFullPath = addedPropertyData?.data?.fieldFullPath;\n\n if (addedPropertyData && fieldFullPath)\n accumulator.push({ fieldName: fieldFullPath });\n\n return accumulator;\n }, []);\n };\n\n const resetState = () => {\n if (isModalOpen) return;\n\n setIsShowSelection(false);\n setLeftExpandedKeys([]);\n setSearchText('');\n };\n\n useEffect(() => {\n resetState();\n }, [isModalOpen]);\n\n const getKeyHasValue = (arrKey, data, nameKey) => {\n const invalidValues = [null, undefined, ''];\n for (const [key, value] of Object.entries(data)) {\n if (!invalidValues.includes(value)) {\n if (isArray(value)) {\n value.forEach((val) => {\n if (isObject(val)) {\n getKeyHasValue(arrKey, val, `${nameKey}.${key}`);\n } else {\n arrKey.push(`${nameKey}.${key}`.toLocaleLowerCase());\n }\n });\n } else if (isObject(value)) {\n getKeyHasValue(arrKey, value, `${nameKey}.${key}`);\n } else {\n arrKey.push(`${nameKey}.${key}`.toLocaleLowerCase());\n }\n // triggle BE field LIST STRING\n if (\n nameKey.includes('DrugFacts') &&\n (key === 'useDetail' ||\n key === 'warningDetail' ||\n key === 'otherInformation') &&\n value?.length > 0\n ) {\n arrKey.push(`${nameKey}.${key}`.toLocaleLowerCase());\n }\n }\n }\n };\n\n const keyNonHeaderData = useMemo(() => {\n let key = [];\n productItemModules?.productItemModules?.length > 0 &&\n productItemModules?.productItemModules.forEach((module) => {\n if (module.moduleName !== 'Header') {\n const arrKey = [];\n getKeyHasValue(arrKey, module?.data, module.moduleName);\n key = key.concat(arrKey);\n }\n });\n listFactsPanel?.length > 0 &&\n listFactsPanel.forEach((fact) => {\n const arrKey = [];\n getKeyHasValue(arrKey, fact, 'NutritionFacts');\n key = key.concat(arrKey);\n });\n listSupplementFactsPanel?.length > 0 &&\n listSupplementFactsPanel.forEach((fact) => {\n const arrKey = [];\n getKeyHasValue(arrKey, fact, 'SupplementFacts');\n key = key.concat(arrKey);\n });\n listDrugFactsPanel?.length > 0 &&\n listDrugFactsPanel.forEach((fact) => {\n const arrKey = [];\n getKeyHasValue(arrKey, fact, 'DrugFacts');\n key = key.concat(arrKey);\n });\n listPetFoodPanel?.length > 0 &&\n listPetFoodPanel.forEach((fact) => {\n const arrKey = [];\n getKeyHasValue(arrKey, fact, 'PetNutritionFacts');\n key = key.concat(arrKey);\n });\n return key;\n }, [\n productItemModules,\n listFactsPanel,\n listSupplementFactsPanel,\n listDrugFactsPanel,\n listPetFoodPanel,\n ]);\n\n const getKey = (sameSize) => {\n let key = [];\n let keyInclude = [];\n let keyNotInclude = [];\n\n if (sameSize) {\n key = KEY_COPY_PROPERTIES.SAME_SIZE;\n keyNotInclude = KEY_COPY_PROPERTIES.SAME_SIZE_NOT_INCLUDE;\n } else {\n key = KEY_COPY_PROPERTIES.SAME_STYLE_FLAVOR;\n keyNotInclude = KEY_COPY_PROPERTIES.SAME_STYLE_NOT_INCLUDE;\n keyInclude = KEY_COPY_PROPERTIES.SAME_STYLE_INCLUDE;\n }\n sourceData.forEach((val) => {\n if (val?.data)\n if (!keyNotInclude.includes(val?.key)) {\n const splitKey = val?.key?.split('.');\n if (!keyNotInclude.includes(splitKey[0])) {\n if (keyNonHeaderData && keyNonHeaderData.length > 0) {\n if (\n keyNonHeaderData.includes(\n val?.data?.fieldFullPath?.toLocaleLowerCase()\n )\n ) {\n key.push(val.key);\n }\n }\n }\n if (keyInclude && keyInclude.includes(splitKey[0])) {\n key.push(val.key);\n }\n }\n });\n return key;\n };\n\n const onChangeSameSize = (e) => {\n const checked = e.target.checked;\n setIsSameSize(checked);\n let keyStyle = getKey(false);\n let keySize = getKey(true);\n let key = [];\n if (checked) {\n if (isHeaderOnly) {\n key = key.concat(KEY_COPY_PROPERTIES.HEADER_ONLY);\n }\n if (isSameStyleFlavor) {\n key = key.concat(keyStyle);\n }\n\n const newKey = addedKeysRef?.current.filter((val) => !key.includes(val));\n setKeySameSize(union(keySize, newKey));\n } else {\n key = key.concat(keySize);\n if (isHeaderOnly) {\n key = key.concat(KEY_COPY_PROPERTIES.HEADER_ONLY);\n }\n if (isSameStyleFlavor) {\n key = key.concat(keyStyle);\n }\n const newKey = addedKeysRef?.current.filter((val) => !key.includes(val));\n setKeySameSize(newKey);\n }\n if (!isSameStyleFlavor) {\n setKeySameStyle([]);\n }\n if (!isHeaderOnly) {\n setKeyHeaderOnly([]);\n }\n };\n\n const onChangeSameStyleFlavor = (e) => {\n const checked = e.target.checked;\n setIsSameStyleFlavor(checked);\n let keyStyle = getKey(false);\n let keySize = getKey(true);\n let key = [];\n\n if (checked) {\n if (isHeaderOnly) {\n key = key.concat(KEY_COPY_PROPERTIES.HEADER_ONLY);\n }\n if (isSameSize) {\n key = key.concat(keySize);\n }\n const newKey = addedKeysRef?.current.filter((val) => !key.includes(val));\n setKeySameStyle(union(keyStyle, newKey));\n } else {\n key = key.concat(keyStyle);\n if (isHeaderOnly) {\n key = key.concat(KEY_COPY_PROPERTIES.HEADER_ONLY);\n }\n if (isSameSize) {\n key = key.concat(keySize);\n }\n const newKey = addedKeysRef?.current.filter((val) => !key.includes(val));\n setKeySameStyle(newKey);\n }\n if (!isSameSize) {\n setKeySameSize([]);\n }\n if (!isHeaderOnly) {\n setKeyHeaderOnly([]);\n }\n };\n\n const onChangeHeaderOnly = (e) => {\n const checked = e.target.checked;\n setIsHeaderOnly(checked);\n\n let keyStyle = getKey(false);\n let keySize = getKey(true);\n let key = [];\n if (checked) {\n if (isSameSize) {\n key = key.concat(keySize);\n }\n if (isSameStyleFlavor) {\n key = key.concat(keyStyle);\n }\n const newKey = addedKeysRef?.current.filter((val) => !key.includes(val));\n setKeyHeaderOnly(union(KEY_COPY_PROPERTIES.HEADER_ONLY, newKey));\n } else {\n key = key.concat(KEY_COPY_PROPERTIES.HEADER_ONLY);\n if (isSameSize) {\n key = key.concat(keySize);\n }\n if (isSameStyleFlavor) {\n key = key.concat(keyStyle);\n }\n const newKey = addedKeysRef?.current.filter((val) => !key.includes(val));\n setKeyHeaderOnly(newKey);\n }\n if (!isSameSize) {\n setKeySameSize([]);\n }\n if (!isSameStyleFlavor) {\n setKeySameStyle([]);\n }\n };\n\n const addRightKey = useMemo(() => {\n return union(keySameSize, keySameStyle, keyHeaderOnly);\n }, [keySameSize, keySameStyle, keyHeaderOnly]);\n\n const renderModalTitle = () => {\n const title = intl.formatMessage(Messages.copyProperties);\n\n return (\n \n \n \n {title}\n \n \n \n \n \n \n Number of copies\n \n {\n setNumberOfCopies(value);\n }}\n onKeyPress={(event) => {\n if (!/[0-9]/.test(event.key)) {\n event.preventDefault();\n }\n }}\n onBlur={() => {\n if (!numberOfCopies) {\n setNumberOfCopies(1);\n }\n }}\n />\n \n \n \n );\n };\n\n return (\n \n \n {loadingStatus === 'loading' ? (\n
\n \n
\n ) : null}\n {loadingStatus === 'error' ? (\n
\n \n
\n ) : null}\n {loadingStatus === 'success' ? (\n
\n \n {(listProps) => (\n \n )}\n \n
\n ) : null}\n \n );\n};\n\nexport default CopyProductPropertiesModal;\n","import React, { useEffect, useRef, useMemo } from 'react';\n\nimport { Row, Col, Space, Checkbox, Input } from 'antd';\n\nimport {\n getAllExpandKeys,\n getTreeData,\n compareExpandKey,\n} from 'utils/exportProductProperties';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/product';\n\nconst { Search } = Input;\n\nconst ExportProductToolbar = (props) => {\n const intl = useIntl();\n const expandKeysRef = useRef([]);\n\n const {\n visible,\n dataSource,\n leftExpandedKeys,\n setLeftExpandedKeys,\n isShowSelection,\n setIsShowSelection,\n searchHook,\n isPopulated,\n setIsPopulated,\n submitDisabled,\n } = props;\n\n const [searchText, setSearchText] = searchHook;\n\n const isExpandedAll = useMemo(\n () => compareExpandKey(leftExpandedKeys, expandKeysRef.current, visible),\n [leftExpandedKeys, visible]\n );\n\n const onSearch = (value) => {\n setSearchText(value);\n };\n\n const onChangeExpandAll = (e) => {\n const checked = e.target.checked;\n if (checked) setLeftExpandedKeys(expandKeysRef.current);\n else setLeftExpandedKeys([]);\n };\n\n const onChangeShowSelection = (e) => {\n const checked = e.target.checked;\n setIsShowSelection(checked);\n };\n\n const onChangeAllPopulated = (e) => {\n const checked = e.target.checked;\n setIsPopulated(checked);\n };\n\n const initExpandKeys = () => {\n const treeData = getTreeData(dataSource);\n const allExpandKeys = getAllExpandKeys(treeData);\n expandKeysRef.current = allExpandKeys;\n };\n\n useEffect(() => {\n initExpandKeys();\n }, [dataSource]);\n\n return (\n \n \n \n \n\n \n\n \n \n \n {intl.formatMessage(Messages.populateAllProduct)}\n \n \n {intl.formatMessage(Messages.exportPropertiesExpandAll)}\n \n \n {intl.formatMessage(Messages.exportPropertiesShowSelection)}\n \n \n \n \n );\n};\n\nexport default ExportProductToolbar;\n","import { useMemo } from 'react';\n\nimport _ from 'lodash';\n\nimport * as productServices from 'services/product';\nimport { NUMERIC_TYPE } from 'static/Constants';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/product';\nimport { useQuery } from '@tanstack/react-query';\n\nconst KEY_EXPORT_PRODUCT = {\n GET_PRODUCT_PROPERTIES_TO_EXPORT: [\n 'pim',\n 'get-product-properties-to-export-data',\n ],\n};\n\nconst useGetPropertiesForExportProduct = (visible) =>\n useQuery({\n queryKey: KEY_EXPORT_PRODUCT.GET_PRODUCT_PROPERTIES_TO_EXPORT,\n queryFn: async () => {\n const response = await productServices.getProductPropertiesToExport();\n if (response?.isSuccess) {\n return response?.data?.properties;\n } else {\n throw new Error(response?.message);\n }\n },\n enabled: visible,\n retry: false,\n });\n\nexport const useGetProductPropertiesToExport = (visible) => {\n const intl = useIntl();\n\n const { status: loadingStatus, data: rootData } =\n useGetPropertiesForExportProduct(visible);\n\n const noHeaderLabel = intl.formatMessage(\n Messages.exportProductPropertiesNoHeaderTitle\n );\n\n const generateSourceData = (data) => {\n if (!data) return [];\n const moduleData = generateModuleData(data);\n const propertyItemData = generatePropertyItemData(moduleData, data);\n const objectTypePropertyData =\n generateOjectTypePropertiesData(propertyItemData);\n\n return [...moduleData, ...objectTypePropertyData, ...propertyItemData];\n };\n\n const generateModuleData = (data) => {\n if (!data) return [];\n const moduleData = data.map((propertyItem) => {\n return {\n key: propertyItem.moduleName || 'noHeader',\n title: propertyItem.moduleDisplayName || noHeaderLabel,\n type: 'group',\n };\n });\n\n const uniqData = _.uniqBy(moduleData, 'key');\n\n return uniqData;\n };\n\n const generatePropertyItemData = (moduleData, data) => {\n if (!moduleData || !data) return;\n\n const formattedPropertiesData = data.map((propertyItem) => {\n const { dataType, displayName, fieldFullPath, fieldName } = propertyItem;\n\n let changeInt;\n if (NUMERIC_TYPE.includes(dataType?.toLowerCase())) changeInt = 'Number';\n\n const propertyModuleName =\n propertyItem.moduleDisplayName || noHeaderLabel;\n\n const modulePath = moduleData.find((moduleItem) => {\n return moduleItem.title === propertyModuleName;\n })?.key;\n const propertyPathArray = fieldFullPath.split('.');\n //* remove the first path as it is module path\n if (propertyItem.moduleDisplayName) propertyPathArray.shift();\n\n const realPropertyPath = propertyPathArray.join('.');\n const formattedPropertyPath = modulePath + '.' + realPropertyPath;\n\n return {\n key: formattedPropertyPath,\n data: {\n displayName,\n fieldName,\n fieldFullPath,\n dataType: changeInt ?? dataType,\n },\n };\n });\n return formattedPropertiesData;\n };\n\n const generateOjectTypePropertiesData = (propertiesData) => {\n if (!propertiesData) return [];\n const objectTypePropertyData = [];\n propertiesData.forEach((propertyItem) => {\n const paths = propertyItem.key.split('.');\n if (paths.length <= 2) return;\n let pathString = '';\n\n for (let i = 0; i < paths.length - 1; i++) {\n pathString += paths[i];\n\n const isPathStringAdded = objectTypePropertyData.find(\n (propertyObjectItem) => propertyObjectItem.key === pathString\n );\n\n if (!isPathStringAdded && pathString.includes('.')) {\n objectTypePropertyData.push({\n key: pathString,\n fieldName: paths[i],\n title: _.startCase(paths[i]),\n type: 'object',\n });\n }\n pathString += '.';\n }\n });\n return objectTypePropertyData;\n };\n\n const sourceData = useMemo(() => {\n return generateSourceData(rootData);\n }, [rootData]);\n\n return { rootData, sourceData, loadingStatus };\n};\n","import React, { useState, useEffect, useRef } from 'react';\nimport { useSelector } from 'react-redux';\n\nimport {\n Button,\n Typography,\n Row,\n Col,\n Modal,\n notification,\n Result,\n Tooltip,\n} from 'antd';\nimport { QuestionCircleOutlined } from '@ant-design/icons';\n\nimport classnames from 'classnames';\n\nimport { WithLoading } from 'common/components';\n\nimport { CustomizeTransfer } from 'common/components';\nimport ExportPropertiesTree from './ExportPropertiesTree';\nimport ExportProductToolbar from './ExportProductToolbar';\n\nimport * as productServices from 'services/product';\nimport { useGetProductPropertiesToExport } from 'hooks/exportProductPropertiesHooks';\nimport { useGlobalModal } from 'hooks';\n\nimport * as api from 'config/axios';\nimport * as globalSelectors from '@redux/global/selectors';\nimport { CustomNotification } from 'common/components';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/product';\n\nimport './BulkEditProduct.less';\n\nconst { Title, Text } = Typography;\n\nconst ExportProductPropertiesModal = (props) => {\n const intl = useIntl();\n const addedKeysRef = useRef([]);\n\n const { selectedProducts, selectedFolders } = props;\n const { MODAL_NAMES, closeModal, checkModalVisible } = useGlobalModal();\n\n const visible = checkModalVisible(MODAL_NAMES.EXPORT_PROPERTY_MODAL);\n\n const [leftExpandedKeys, setLeftExpandedKeys] = useState([]);\n const [isShowSelection, setIsShowSelection] = useState(false);\n const searchHook = useState('');\n const [searchText, setSearchText] = searchHook;\n const [submitLoading, setSubmitLoading] = useState(false);\n const [submitDisabled, setSubmitDisabled] = useState(true);\n const [isExportProperties, setIsExportProperties] = useState(false);\n const [isPopulated, setIsPopulated] = useState(false);\n\n const { sourceData, rootData, loadingStatus } =\n useGetProductPropertiesToExport(visible);\n\n const upDownProgressData = useSelector(\n globalSelectors.selectUploadDownloadProgress()\n );\n\n const onOk = () => {\n setSubmitLoading(true);\n setIsExportProperties(true);\n const exportProperties = !isPopulated\n ? getExportedPropertyFieldName({\n data: sourceData,\n addedKeys: addedKeysRef.current,\n })\n : [];\n\n callApiExportProperties(exportProperties, isPopulated);\n };\n\n const closeExportModal = () => {\n if (!isExportProperties) return;\n\n const isDownLoadSuccess = upDownProgressData\n ?.filter((item) => item?.type === 'download')\n ?.every((item) => item?.status === 'done');\n\n if (isDownLoadSuccess) {\n setSubmitLoading(false);\n closeModal(MODAL_NAMES.EXPORT_PROPERTY_MODAL);\n setIsExportProperties(false);\n }\n };\n\n useEffect(() => {\n closeExportModal();\n }, [upDownProgressData]);\n\n const onCancel = () => {\n closeModal(MODAL_NAMES.EXPORT_PROPERTY_MODAL);\n };\n\n const onClickDownloadManual = () => {\n callApiDownloadManual();\n };\n\n const onTransferChange = (addedKeys) => {\n addedKeysRef.current = addedKeys;\n setSubmitDisabled(!addedKeys.length);\n };\n\n const callApiDownloadManual = () => {\n productServices\n .downloadManualEditingBulkProduct()\n .then((response) => {\n const { isSuccess, data } = response;\n if (isSuccess && data) api.sendDownload({ url: response?.data?.url });\n else handleDownloadManualError(response);\n })\n .catch(() => {\n setSubmitLoading(false);\n handleDownloadManualError();\n });\n };\n\n const handleDownloadManualError = (response) => {\n notification.error({\n message:\n response?.message ||\n response?.data?.message ||\n intl.formatMessage(Messages.exportPropertiesDownloadManualError),\n });\n };\n\n const callApiExportProperties = (exportProperties, allPopulated) => {\n const params = {\n productIds: selectedProducts,\n folderIds: selectedFolders,\n selectedColumns: exportProperties,\n allPopulated,\n };\n\n productServices\n .exportProductProperties(params)\n .then((response) => {\n const { isSuccess, data } = response;\n\n if (isSuccess && data) {\n api.sendDownload({ url: response?.data?.url });\n CustomNotification.success('Download successfully');\n } else {\n notification.error({\n message:\n response?.message ||\n response?.data?.message ||\n intl.formatMessage(Messages.exportProductPropertiesError),\n });\n }\n })\n .catch((e) => {\n notification.error({\n message: intl.formatMessage(Messages.exportProductPropertiesError),\n });\n });\n };\n\n const getExportedPropertyFieldName = ({ data, addedKeys }) => {\n return addedKeys.reduce((accumulator, currentAddedKeys) => {\n const addedPropertyData = data.find((propertyItem) => {\n return propertyItem.key === currentAddedKeys;\n });\n const fieldFullPath = addedPropertyData?.data?.fieldFullPath;\n\n if (addedPropertyData && fieldFullPath) accumulator.push(fieldFullPath);\n\n return accumulator;\n }, []);\n };\n\n const resetState = () => {\n if (visible) return;\n\n setIsShowSelection(false);\n setLeftExpandedKeys([]);\n setSearchText('');\n };\n\n useEffect(() => {\n resetState();\n }, [visible]);\n\n const renderModalTitle = () => {\n const title = intl.formatMessage(Messages.exportProperties);\n\n const DownloadManualBtn = Button;\n\n return (\n \n \n \n {title}\n \n \n \n \n \n }\n onClick={onClickDownloadManual}\n />\n \n \n \n );\n };\n\n return (\n \n \n {loadingStatus === 'loading' ? (\n
\n \n
\n ) : null}\n {loadingStatus === 'error' ? (\n
\n \n
\n ) : null}\n {loadingStatus === 'success' ? (\n \n \n \n All properties are populated!\n \n \n \n {(listProps) => (\n \n )}\n \n \n ) : null}\n \n );\n};\n\nexport default ExportProductPropertiesModal;\n","import React, { useState, useEffect, useMemo, useRef } from 'react';\n\nimport _ from 'lodash';\nimport { Tree, Typography, Row, Col } from 'antd';\nimport { MemberRoleSectionWrapper as SectionWrapper } from 'pages/role/components';\nimport { EVENT } from 'static/Constants';\n\nimport useDocumentAttachEvent from 'hooks/documentAttachEventHook';\nimport * as exportProductPropertiesUtils from 'utils/exportProductProperties';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/product';\n\nconst { Title, Text, Paragraph } = Typography;\n\nconst ExportPropertiesTree = (props) => {\n const intl = useIntl();\n const movingRightToLeftKeysRef = useRef([]);\n const treeContainerRef = useRef([]);\n\n const {\n visible,\n dataSource,\n direction,\n addKeysHook,\n selectKeysHook,\n setLeftExpandedKeys,\n leftExpandedKeys,\n isShowSelection,\n searchText,\n propertyTitle,\n rootData,\n } = props;\n\n // console.log('leftExpandedKeys: ', leftExpandedKeys);\n const [addedKeys, setAddedKey] = addKeysHook;\n const [selectedKeys, setSelectedKeys] = selectKeysHook;\n\n const [treeData, setTreeData] = useState([]);\n const [checkedKeys, setCheckedKeys] = useState([]);\n const [treeHeight, setTreeHeight] = useState(450);\n\n const semiFlattenData = useMemo(() => {\n const semiFlattenData = [];\n exportProductPropertiesUtils.semiFlatData({\n data: treeData,\n result: semiFlattenData,\n });\n\n return semiFlattenData;\n }, [treeData]);\n\n const onExpand = (expandedKeysValue, e) => {\n if (e?.node?.data) return;\n if (direction === 'right') return;\n const newExpandedKeys = exportProductPropertiesUtils.getExpandKeysOnEvent(\n leftExpandedKeys,\n e\n );\n setLeftExpandedKeys(newExpandedKeys);\n };\n\n const onSelect = (selectedKeys, e) => {\n if (direction === 'right') return;\n const newExpandedKeys = exportProductPropertiesUtils.getExpandKeysOnEvent(\n leftExpandedKeys,\n e\n );\n setLeftExpandedKeys(newExpandedKeys);\n };\n\n const onCheck = (_, e) => {\n const { checkedNodes, node } = e;\n\n const checkedKeys = checkedNodes.map((nodeItem) => nodeItem.key);\n const reCheckedKeys = reGenCheckedKeys(checkedKeys);\n const reSelectedKeys = reGenSelectedKeys(reCheckedKeys);\n\n setCheckedKeys(reCheckedKeys);\n setSelectedKeys(reSelectedKeys);\n\n expandOnCheckedNode(node);\n };\n\n const reGenCheckedKeys = (originCheckedKeys) => {\n return originCheckedKeys.reduce((accumulator, currentKey) => {\n const currentData = semiFlattenData.find((dataItem) => {\n return dataItem.key === currentKey;\n });\n\n if (!currentData?.children?.length) accumulator.push(currentKey);\n\n return accumulator;\n }, []);\n };\n\n const reGenSelectedKeys = (checkedKey) => {\n if (direction === 'right') return checkedKey;\n\n return checkedKey.filter((keyItem) => {\n return !addedKeys.includes(keyItem);\n });\n };\n const expandOnCheckedNode = (node) => {\n //* expand this node and all its children\n if (node?.data) return;\n if (direction === 'right') return;\n\n const shouldCollapse = node.expanded && node.checked;\n\n const expandKeysOnNode = [node.key];\n exportProductPropertiesUtils.getAllChildrenKeyDeep(\n node?.children,\n expandKeysOnNode\n );\n\n const newExpandedKeys = shouldCollapse\n ? leftExpandedKeys.filter((leftExpandedKeyItem) => {\n return !expandKeysOnNode.includes(leftExpandedKeyItem);\n })\n : [...expandKeysOnNode, ...leftExpandedKeys];\n\n setLeftExpandedKeys(newExpandedKeys);\n };\n\n const expandAllTreeNodes = (treeData) => {\n const expandedKeys = getExpandKeyFromTreeData(treeData);\n setLeftExpandedKeys(expandedKeys);\n };\n\n const getExpandKeyFromTreeData = (treeData) => {\n const semiFlattenData = [];\n exportProductPropertiesUtils.semiFlatData({\n data: treeData,\n result: semiFlattenData,\n });\n return semiFlattenData.map((dataItem) => dataItem.key);\n };\n\n const generateTreeDataFromSource = ({ data, inCase }) => {\n const treeData = exportProductPropertiesUtils.getTreeData(data);\n\n if (direction === 'left') return generateLeftTree({ treeData, inCase });\n else return generateRightTree(rootData);\n };\n\n const generateTreeDataFromFiltered = () => {\n if (direction === 'right')\n return generateTreeDataFromSource({ data: dataSource, inCase: 'filter' });\n\n const filteredData = _.cloneDeep(treeData);\n\n const flattenData = [];\n\n exportProductPropertiesUtils.flatData({\n data: filteredData,\n result: flattenData,\n });\n\n const newTreeData = exportProductPropertiesUtils.getTreeData(flattenData);\n\n return generateLeftTree({ treeData: newTreeData });\n };\n\n const generateLeftTree = ({ treeData, inCase }) => {\n if (inCase === 'update')\n updateCheckedKeysByAddedKeys({\n treeData,\n movingKeys: movingRightToLeftKeysRef.current,\n });\n return exportProductPropertiesUtils.mapDisabledData(treeData, addedKeys);\n };\n\n const generateRightTree = (data) => {\n const arrRightData = data.filter((val) => {\n const propertyPathArray = val?.fieldFullPath?.split('.');\n //* remove the first path as it is module path\n if (val?.moduleDisplayName) propertyPathArray.shift();\n\n const realPropertyPath = propertyPathArray.join('.');\n const modulePath = val?.moduleName || 'noHeader';\n const key = modulePath + '.' + realPropertyPath;\n\n return addedKeys.includes(key);\n });\n const newRightData =\n exportProductPropertiesUtils.generateSourceData(arrRightData);\n const treeRightData =\n exportProductPropertiesUtils.getTreeData(newRightData);\n\n return treeRightData;\n };\n\n const filterShowSelection = () => {\n if (direction === 'right') return;\n\n setTreeData((prevState) => {\n const clonedData = _.cloneDeep(prevState);\n\n const filteredData = exportProductPropertiesUtils.createFilterData(\n clonedData,\n checkedKeys,\n addedKeys\n );\n\n //* all checkbox should be checked\n checkAllFilterSelection(filteredData);\n\n //* disabled added items\n const newState = exportProductPropertiesUtils.mapDisabledData(\n filteredData,\n addedKeys\n );\n\n return newState;\n });\n };\n\n const checkAllFilterSelection = (filteredData) => {\n // treeData\n const semiFlattenData = [];\n exportProductPropertiesUtils.semiFlatData({\n data: filteredData,\n result: semiFlattenData,\n });\n const newCheckedKeys = semiFlattenData.map((dataItem) => {\n return dataItem.key;\n });\n\n setCheckedKeys(newCheckedKeys);\n };\n\n const deFilterShowSelection = () => {\n if (direction === 'right') return;\n const treeData = exportProductPropertiesUtils.getTreeData(dataSource);\n const treeDataWithDisabledNote =\n exportProductPropertiesUtils.mapDisabledData(treeData, addedKeys);\n deFilterUpdateCheckedKeys(treeDataWithDisabledNote);\n setTreeData(treeDataWithDisabledNote);\n };\n\n const deFilterUpdateCheckedKeys = (data) => {\n const semiFlattenData = [];\n exportProductPropertiesUtils.semiFlatData({\n data,\n result: semiFlattenData,\n });\n const newCheckedKeys = semiFlattenData.reduce(\n (accumulator, currentDataItem) => {\n const isChecked =\n !currentDataItem.children.length &&\n checkedKeys.includes(currentDataItem.key);\n\n const isAllChildrenChecked =\n exportProductPropertiesUtils.checkAllChildrenCheckedDeep(\n currentDataItem,\n checkedKeys\n );\n\n if (isChecked || isAllChildrenChecked)\n accumulator.push(currentDataItem.key);\n\n return accumulator;\n },\n []\n );\n //* if there are added keys, they should be checked\n setCheckedKeys([...newCheckedKeys, ...addedKeys]);\n };\n\n const updateCheckedKeysByAddedKeys = ({ treeData, movingKeys }) => {\n const semiFlattenData = [];\n exportProductPropertiesUtils.semiFlatData({\n data: treeData,\n result: semiFlattenData,\n });\n\n const filteredOutMovingKeys = selectedKeys.filter(\n (selectedKeyItem) => !movingKeys.includes(selectedKeyItem)\n );\n\n const newCheckedKeys = semiFlattenData.reduce(\n (accumulator, currentDataItem) => {\n const isChecked =\n !currentDataItem?.children?.length &&\n filteredOutMovingKeys.includes(currentDataItem.key);\n\n const isAllChildrenAdded =\n exportProductPropertiesUtils.checkAllChildrenAddedDeep(\n currentDataItem,\n addedKeys\n );\n\n if (isAllChildrenAdded || isChecked)\n return [...accumulator, currentDataItem.key];\n return accumulator;\n },\n []\n );\n\n setCheckedKeys(newCheckedKeys);\n };\n\n const getExpandedKeyFromAddedKey = () => {\n return addedKeys.reduce((accumulator, currentAddedKey) => {\n const currentAddedKeyPath = currentAddedKey.split('.');\n currentAddedKeyPath.forEach((path, index) => {\n const parentKey = currentAddedKeyPath.slice(0, index + 1).join('.');\n accumulator.push(parentKey);\n });\n return accumulator;\n }, []);\n };\n\n const onMoveLeftCallback = (e) => {\n const { rightSelectedKeys: movingKeys } = e.detail;\n\n movingRightToLeftKeysRef.current = movingKeys;\n\n if (direction === 'left') return;\n setCheckedKeys([]);\n };\n\n useDocumentAttachEvent({\n name: EVENT.EXPORT_PRODUCT_PROPERTIES_TRANSFER.toLeft,\n handler: onMoveLeftCallback,\n });\n\n // const initTreeData = () => {\n // const treeData = generateTreeData();\n\n // setTreeData(treeData);\n // };\n\n const updateTreeData = () => {\n const treeData = isShowSelection\n ? generateTreeDataFromFiltered()\n : generateTreeDataFromSource({ data: dataSource, inCase: 'update' });\n\n setTreeData(treeData);\n };\n\n const searchProperties = () => {\n if (direction === 'right') return;\n\n const originTreeData = generateTreeDataFromSource({\n data: dataSource,\n inCase: 'search',\n });\n\n const searchedResults =\n exportProductPropertiesUtils.searchItems(originTreeData, searchText) ||\n [];\n\n setTreeData(searchedResults);\n expandAllTreeNodes(searchedResults);\n };\n\n const getTotalItemSelected = () => {\n const totalItemSelected = exportProductPropertiesUtils.getTotalItemSelected(\n {\n data: semiFlattenData,\n selectedKeys,\n addedKeys: direction === 'left' ? addedKeys : [],\n }\n );\n return totalItemSelected;\n };\n\n const clearState = () => {\n if (visible) return;\n\n setAddedKey([]);\n setSelectedKeys([]);\n setTreeData([]);\n setCheckedKeys([]);\n };\n const getTreeHeight = () => {\n const treeContainer = treeContainerRef.current;\n\n setTreeHeight(treeContainer.offsetHeight);\n };\n\n const getTreeHeightDebounce = _.debounce(getTreeHeight, 500);\n\n //* make tree vertical responsive\n useEffect(() => {\n window.addEventListener('resize', getTreeHeightDebounce);\n return () => {\n window.removeEventListener('resize', getTreeHeightDebounce);\n };\n }, []);\n\n useEffect(() => {\n isShowSelection && filterShowSelection();\n !isShowSelection && deFilterShowSelection();\n }, [isShowSelection]);\n\n useEffect(() => {\n if (direction === 'left' && searchText) searchProperties();\n else updateTreeData();\n }, [addedKeys, searchText, dataSource]);\n\n useEffect(() => {\n clearState();\n }, [visible]);\n\n const renderTitle = (nodeData) => {\n const { title, data, fieldName } = nodeData;\n\n if (title)\n return (\n \n {title}\n \n );\n\n return (\n \n \n \n {data?.displayName || fieldName}\n \n \n {data ? (\n \n \n \n {intl.formatMessage(\n Messages.exportProductPropertiesFieldNameLabel\n )}\n :{' '}\n \n {data?.fieldName}\n \n \n \n {intl.formatMessage(\n Messages.exportProductPropertiesFieldTypeLabel\n )}\n :{' '}\n \n \n {data.dataType}\n \n \n \n ) : null}\n \n );\n };\n\n const expandedKeys =\n direction === 'right' ? getExpandedKeyFromAddedKey() : leftExpandedKeys;\n\n const sectionTitle =\n direction === 'left' ? 'productProperties' : propertyTitle;\n\n const totalItemSelected = getTotalItemSelected({\n data: dataSource,\n selectedKeys,\n });\n\n const totalItemSelectedText =\n totalItemSelected > 1 ? 'totalItemsSelected' : 'totalItemSelected';\n\n return (\n
\n \n
\n ' ' : undefined}\n onExpand={onExpand}\n expandedKeys={expandedKeys}\n onCheck={onCheck}\n onSelect={onSelect}\n checkedKeys={checkedKeys}\n treeData={treeData}\n titleRender={renderTitle}\n defaultExpandParent={direction === 'right'}\n />\n
\n \n {propertyTitle === 'exportProperties' && (\n \n {totalItemSelected}{' '}\n {intl.formatMessage(Messages[totalItemSelectedText])}\n \n )}\n
\n );\n};\n\nexport default ExportPropertiesTree;\n","import React, { useState } from 'react';\n\nimport { useParams } from 'react-router-dom';\n\nimport { List, Modal, notification, Typography } from 'antd';\nimport { InfoCircleOutlined } from '@ant-design/icons';\nimport { useQueryClient } from '@tanstack/react-query';\n\nimport * as api from 'config/axios';\nimport { CustomNotification, UploadFile, WithLoading } from 'common/components';\n\nimport {\n GET_EDITING_FIELDS_FORM_TEMPLATE,\n IMPORT_PRODUCT_FOR_BULK_EDITING,\n} from 'services/product/endpoints';\nimport { UPLOAD_MAX_SIZE } from 'static/Constants';\nimport { useDispatchReloadPage } from 'hooks/useReloadPage';\nimport { useProductFullView } from 'hooks/useProductFullView';\n\nimport { useReloadDocumentCertificateTab } from 'hooks/useReloadDocumentCertificateTab';\n\nimport { useIntl } from 'react-intl';\nimport Messages from 'i18n/messages/product';\nimport {\n IXONECertificationWrapper,\n TYPE_VIEW,\n} from 'common/components/product-add/IXONECertificationWrapper';\nimport useUpdateIXONEShield from 'common/components/product-add/useUpdateIXONEShield';\nimport { useRefetchQaSpecData } from 'hooks/qa-spec/useRefetchQaSpecData';\nimport { useGlobalModal } from 'hooks';\n\nconst { Text, Paragraph } = Typography;\n\nconst ImportProductBulkEditModal = (props) => {\n const intl = useIntl();\n const reloadPage = useDispatchReloadPage();\n const { reloadDocumentCertificateTab } = useReloadDocumentCertificateTab();\n\n const { handleUpdateIXONEShield } = useUpdateIXONEShield();\n\n const queryClient = useQueryClient();\n const { isProductDetail } = props;\n\n const { closeModal, MODAL_NAMES, checkModalVisible } = useGlobalModal();\n\n const { id } = useParams();\n\n const [errorList, setErrorList] = useState([]);\n const [fileUpload, setFileUpload] = useState();\n const [tdcProductIds, setTdcProductIds] = useState([]);\n const [loading, setLoading] = useState(false);\n const [bulkEditLoading, setBulkEditLoading] = useState(false);\n\n const productId = isProductDetail ? id : null;\n\n const isImportModalOpen = checkModalVisible(\n MODAL_NAMES.IMPORT_PROPERTY_MODAL\n );\n\n const { productFull, reloadProductFullView } = useProductFullView({\n productId,\n });\n\n const refetchQaSpecData = useRefetchQaSpecData();\n\n const onCancel = () => {\n closeModal(MODAL_NAMES.IMPORT_PROPERTY_MODAL);\n setErrorList([]);\n };\n\n const handleResponseUpload = async (response, ixoneIgnore) => {\n setErrorList([]);\n\n if (response?.isSuccess) {\n if (ixoneIgnore === 'continue') {\n await handleUpdateIXONEShield(ixoneIgnore, tdcProductIds);\n }\n const systemMessage = response?.message;\n CustomNotification.success(\n systemMessage ||\n intl.formatMessage(Messages.importProductBulkEditSuccess)\n );\n reloadPage();\n\n if (productFull?.productId) {\n queryClient.invalidateQueries({ queryKey: ['pim'] });\n\n reloadProductFullView();\n\n reloadDocumentCertificateTab();\n\n refetchQaSpecData();\n }\n\n setBulkEditLoading(false);\n closeModal(MODAL_NAMES.IMPORT_PROPERTY_MODAL);\n } else {\n notification.error({\n message:\n response?.message ||\n intl.formatMessage(Messages.importProductBulkEditError),\n });\n if (response?.data?.validateFailDetails) {\n setErrorList(response?.data?.validateFailDetails);\n }\n setBulkEditLoading(false);\n }\n };\n\n const renderErrorList = () => {\n return (\n
\n \n Error\n \n }\n bordered\n dataSource={errorList}\n renderItem={(errorItem) => {\n const errorMessage = errorItem.reason || 'Invalid data';\n return (\n \n \n \n {errorMessage}\n {' '}\n in{' '}\n \n {errorItem?.sheetName}\n {' '}\n sheet, on row{' '}\n \n {errorItem?.row}\n \n , column{' '}\n \n {errorItem?.column}\n \n \n \n );\n }}\n />\n
\n );\n };\n\n const getFileChange = (paramsUpload) => {\n setFileUpload(paramsUpload.file.originFileObj);\n };\n\n const handleValidateFileUpload = (handleConfirmIXONE) => {\n setLoading(true);\n api\n .sendUpload({\n api: GET_EDITING_FIELDS_FORM_TEMPLATE,\n payload: {\n file: fileUpload,\n },\n })\n .then(({ data }) => {\n if (data?.isSuccess) {\n const productList = data?.data?.data;\n let Ids = [];\n productList?.forEach((product) => {\n const { ixOneId, ixOneCertifiedStatus, productId } = product;\n if (ixOneId && ixOneCertifiedStatus !== 'Removed') {\n Ids.push(+productId);\n }\n });\n setTdcProductIds(Ids);\n\n handleConfirmIXONE({\n originalData: Ids,\n changedFields: data?.data?.fields,\n });\n setLoading(false);\n } else {\n setLoading(false);\n CustomNotification.warning(data?.message ?? 'Server error');\n }\n })\n .catch(() => {\n setLoading(false);\n CustomNotification.warning('Server error');\n });\n };\n\n const handleUploadBulkEdit = (ixoneIgnore) => {\n setBulkEditLoading(true);\n api\n .sendUpload({\n api: IMPORT_PRODUCT_FOR_BULK_EDITING,\n payload: {\n file: fileUpload,\n },\n })\n .then(async (response) => {\n await handleResponseUpload(response?.data, ixoneIgnore);\n })\n .catch(() => {\n CustomNotification.warning('Server error');\n setBulkEditLoading(false);\n });\n };\n\n return (\n {\n handleUploadBulkEdit(ixoneIgnore);\n }}\n onCancel={onCancel}\n >\n {(handleConfirmIXONE) => (\n \n \n
\n {\n handleValidateFileUpload(handleConfirmIXONE);\n }}\n maxSize={UPLOAD_MAX_SIZE.GENERAL}\n />\n
\n
\n {errorList?.length ? renderErrorList() : null}\n \n )}\n \n );\n};\n\nexport default ImportProductBulkEditModal;\n","import React from 'react';\n\nimport { List, Row, Col, Checkbox, Typography } from 'antd';\nimport classnames from 'classnames';\n\nconst { Text } = Typography;\n\nconst HierarchyProductList = (props) => {\n const {\n productList,\n selectedProduct,\n setSelectedProduct,\n getProduct,\n totalProduct,\n pageIndex,\n setPageIndex,\n } = props;\n\n const onClickProduct = (product) => () => {\n setSelectedProduct(product);\n };\n\n const onChangePagination = (page) => {\n setPageIndex(page);\n getProduct({ page });\n };\n\n const checkSelectedProduct = (product) => {\n return selectedProduct?.id === product.id;\n };\n\n const pagination = {\n pageSize: 5,\n total: totalProduct,\n current: pageIndex,\n onChange: onChangePagination,\n };\n\n return (\n \n {productList.map((product, index) => {\n const isSelected = checkSelectedProduct(product);\n return (\n \n \n \n \n \n \n \n \n \n \n \n {product.productName}\n \n \n \n \n \n Package Level:\n \n {product.packageLevel}\n \n \n \n UPC12:\n \n {product.upc12}\n \n \n GTIN:\n {product.gtin}\n \n \n \n \n \n );\n })}\n \n );\n};\n\nexport default HierarchyProductList;\n","import React, { useEffect, useRef, useState } from 'react';\n\nimport { LeftOutlined } from '@ant-design/icons';\nimport { Button, Input, Row, Space, Typography } from 'antd';\n\nimport { WithLoading } from 'common/components';\nimport HierarchyProductList from './HierarchyProductList';\n\nimport * as productServices from 'services/product';\nimport { HIERARCHY_LEVEL } from 'static/Constants';\n\nimport Messages from 'i18n/messages/product';\nimport { useIntl } from 'react-intl';\n\nimport { useGetProductFullView } from 'hooks';\n\nconst { Text } = Typography;\n\nconst AddProductHierarchy = (props) => {\n const intl = useIntl();\n const searchInputRef = useRef(null);\n\n const {\n selectedLevel,\n setSelectedProduct,\n selectedProduct,\n goBackToSelectLevelView,\n productId,\n } = props;\n\n const [searchText, setSearchText] = useState('');\n const [totalProduct, setTotalProduct] = useState(0);\n const [pageIndex, setPageIndex] = useState(1);\n\n const [searchProductData, setSearchProductData] = useState([]);\n const [searchProductError, setSearchProductError] = useState(false);\n const [searchLoading, setSearchLoading] = useState(false);\n\n const { productFull: currentProduct } = useGetProductFullView({ productId });\n\n const pageSize = 5;\n\n const onClickBackButton = () => {\n goBackToSelectLevelView();\n };\n\n const onSearchProduct = (value) => {\n setSearchText(value);\n callApiSearchProduct({ page: 1, search: value });\n };\n\n const callApiSearchProduct = ({ page, search }) => {\n setSearchLoading(true);\n setSearchProductData([]);\n setSearchProductError(false);\n\n const selectedLevelParams = Object.values(HIERARCHY_LEVEL).find(\n (LEVEL) => LEVEL.KEY === selectedLevel.key\n )?.NAME;\n\n const params = {\n packageLevels: [selectedLevelParams],\n search: {\n searchText: typeof search === 'string' ? search : searchText,\n },\n pageIndex: page,\n pageSize,\n ownerId: currentProduct?.ownerId,\n };\n\n productServices\n .searchProductForAddHierarchy(params)\n .then((response) => {\n const { isSuccess, data } = response;\n\n if (isSuccess && data?.gridData?.length) {\n setSearchProductData(data.gridData);\n setTotalProduct(data.paging?.totalRecord);\n } else {\n throw new Error();\n }\n })\n .catch((error) => {\n setSearchProductError(true);\n })\n .finally(() => {\n setSearchLoading(false);\n });\n };\n\n const focusSearchInput = () => {\n if (!searchInputRef.current) return;\n searchInputRef.current.focus({\n cursor: 'start',\n });\n };\n\n useEffect(() => {\n focusSearchInput();\n }, []);\n\n return (\n <>\n
\n \n }\n onClick={onClickBackButton}\n size='small'\n shape='circle'\n />\n \n \n \n {searchLoading ? (\n \n ) : null}\n {searchProductError ? (\n \n {intl.formatMessage(Messages.searchProductError)}\n \n ) : null}\n {searchProductData.length ? (\n \n ) : null}\n \n
\n \n );\n};\n\nexport default AddProductHierarchy;\n","import React from 'react';\n\nimport {\n Col,\n Typography,\n Button,\n InputNumber,\n Form,\n Tooltip,\n Space,\n} from 'antd';\nimport { UndoOutlined } from '@ant-design/icons';\nimport _ from 'lodash';\n\nimport { DeleteButton, dialogFunction } from 'common/components';\n\nimport * as utils from 'utils/productHierarchy';\n\nimport Messages from 'i18n/messages/product';\nimport { useIntl } from 'react-intl';\n\nconst { Text, Link } = Typography;\n\nconst HierarchyLevelProductItem = (props) => {\n const intl = useIntl();\n const {\n form,\n hierarchyProductList,\n currentProduct,\n product,\n level,\n highestLevel,\n isCopy,\n hierarchyLevelList,\n setHierarchyLevelList,\n onClickLevelButton,\n onClickRevertBtn,\n } = props;\n\n const onDeleteProduct = (level) => () => {\n dialogFunction({\n type: 'warn',\n content: intl.formatMessage(Messages.deletePackageLevelMessage),\n onOk: deletePackageLevel(level),\n okText: intl.formatMessage(Messages.deletePackageLevelYes),\n });\n };\n\n const deletePackageLevel = (level) => () => {\n removeLevel(level);\n };\n\n const removeLevel = (deletedLevel) => {\n setHierarchyLevelList((prevState) => {\n const cloneState = _.cloneDeep(prevState);\n\n _.set(cloneState, `[${deletedLevel.index}].productItemId`, null);\n _.set(cloneState, `[${deletedLevel.index}].parentProductItemId`, null);\n\n const removedState = utils.getRemovedLevelResultList({\n deletedLevel,\n levelList: cloneState,\n });\n\n const reIndexState = utils.reIndexLevelList(removedState);\n\n removeParentProductItem({ level: deletedLevel, levelList: reIndexState });\n\n reSetHighestLevelQuantity({ levelList: reIndexState });\n\n return reIndexState;\n });\n };\n\n const removeParentProductItem = ({ level, levelList }) => {\n const childrenLevelList = levelList.filter((levelItem) => {\n return levelItem.parentProductItemId === level.productItemId;\n });\n\n childrenLevelList.forEach((levelItem) => {\n _.set(\n levelList,\n `${levelItem.index}.parentProductItemId`,\n level.parentProductItemId\n );\n });\n };\n\n const reSetHighestLevelQuantity = ({ levelList }) => {\n const highestLevel = utils.getHighestLevel(levelList);\n\n const highestLevelList = levelList.filter(\n (levelItem) => levelItem.packageLevel === highestLevel\n );\n\n highestLevelList.forEach((levelItem) => {\n _.set(levelList, `${levelItem.index}.quantity`, 1);\n\n form.setFieldsValue({\n [levelItem.index]: 1,\n });\n });\n };\n\n const isCurrentProduct = product.productItemId === currentProduct.productId;\n const currentProductCount = utils.countCurrentProduct({\n currentProduct,\n levelList: hierarchyLevelList,\n });\n const shouldShowDeleteBtn = !isCurrentProduct || currentProductCount > 1;\n\n const isHighestLevel = level.packageLevel === highestLevel;\n const shouldChangeProduct = !isCurrentProduct && isCopy && isHighestLevel;\n\n const productInfoText =\n product.productName ||\n product.productDescription ||\n product.gtin ||\n product.upc12 ||\n product.rivirId ||\n intl.formatMessage(Messages.hierarchyProductNoInfo);\n\n const isRevertable = utils.checkRevertable({\n productList: hierarchyProductList,\n level,\n shouldChangeProduct,\n });\n\n const quantityRule = [\n { required: true, message: intl.formatMessage(Messages.required) },\n ];\n\n return (\n <>\n \n \n \n \n {!isCurrentProduct ? (\n \n {productInfoText}\n \n ) : (\n \n {product?.productName}\n \n )}\n \n {shouldChangeProduct ? (\n \n \n \n {isRevertable ? (\n \n \n \n ) : null}\n \n \n \n ) : (\n <>\n \n