Merge branch 'develop' into feature/security-active-sessions
This commit is contained in:
commit
b656f2ce22
@ -51906,6 +51906,138 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>RoomsPinLimitMessage</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<default_text/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-SA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>az-Latn-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>bg-BG</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>cs-CZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>el-GR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-ES</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fi-FI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>hy-AM</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>it-IT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ja-JP</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ko-KR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lo-LA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lv-LV</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>nl-NL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pl-PL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-PT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ro-RO</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>si-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sk-SK</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sl-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sr-Cyrl-RS</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sr-Latn-RS</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>uk-UA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>RoomsPinned</name>
|
||||
<description/>
|
||||
|
@ -149,6 +149,7 @@
|
||||
"RoomOwner": "Room owner",
|
||||
"RoomPinned": "Room pinned",
|
||||
"RoomRemoved": "Room removed",
|
||||
"RoomsPinLimitMessage": "You can't pin more than 10 rooms to the top. Unpin some that are currently pinned.",
|
||||
"RoomsPinned": "Rooms pinned: {{count}}",
|
||||
"RoomsRemoved": "Rooms removed",
|
||||
"RoomsUnpinned": "Rooms unpinned: {{count}}",
|
||||
|
@ -179,8 +179,11 @@ const EditRoomEvent = ({
|
||||
actions.push(addTagsToRoom(room.id, newTags));
|
||||
room.tags = tags;
|
||||
}
|
||||
if (removedTags.length)
|
||||
|
||||
if (removedTags.length) {
|
||||
actions.push(removeTagsFromRoom(room.id, removedTags));
|
||||
room.tags = tags;
|
||||
}
|
||||
|
||||
await Promise.all(actions);
|
||||
|
||||
|
@ -57,11 +57,10 @@ const Main = (props) => {
|
||||
|
||||
React.useEffect(() => {
|
||||
window.addEventListener("resize", onResize);
|
||||
window.visualViewport.addEventListener("resize", onResize);
|
||||
|
||||
return () => {
|
||||
window.addEventListener("resize", onResize);
|
||||
window.visualViewport.removeEventListener("resize", onResize);
|
||||
|
||||
clearTimeout(updateSizeRef.current);
|
||||
};
|
||||
}, [onResize, isFrame]);
|
||||
|
@ -1112,12 +1112,9 @@ const SectionFilterContent = ({
|
||||
label = t("Media");
|
||||
break;
|
||||
case FilterType.FilesOnly.toString():
|
||||
label = t("AllFiles");
|
||||
label = t("Translations:Files");
|
||||
break;
|
||||
case FilterType.OFormTemplateOnly.toString():
|
||||
label = t("FormsTemplates");
|
||||
break;
|
||||
case FilterType.OFormOnly.toString():
|
||||
case FilterType.Pdf.toString():
|
||||
label = t("Forms");
|
||||
break;
|
||||
}
|
||||
@ -1640,18 +1637,18 @@ const SectionFilterContent = ({
|
||||
isLast: !isTrash,
|
||||
},
|
||||
...folders,
|
||||
{
|
||||
id: "filter_type-all-files",
|
||||
key: FilterType.FilesOnly.toString(),
|
||||
group: FilterGroups.filterType,
|
||||
label: t("Translations:Files").toLowerCase(),
|
||||
},
|
||||
{
|
||||
id: "filter_type-documents",
|
||||
key: FilterType.DocumentsOnly.toString(),
|
||||
group: FilterGroups.filterType,
|
||||
label: t("Common:Documents").toLowerCase(),
|
||||
},
|
||||
{
|
||||
id: "filter_type-presentations",
|
||||
key: FilterType.PresentationsOnly.toString(),
|
||||
group: FilterGroups.filterType,
|
||||
label: t("Translations:Presentations").toLowerCase(),
|
||||
},
|
||||
{
|
||||
id: "filter_type-spreadsheets",
|
||||
key: FilterType.SpreadsheetsOnly.toString(),
|
||||
@ -1659,27 +1656,20 @@ const SectionFilterContent = ({
|
||||
label: t("Translations:Spreadsheets").toLowerCase(),
|
||||
},
|
||||
{
|
||||
id: "filter_type-form-templates",
|
||||
key: FilterType.OFormTemplateOnly.toString(),
|
||||
id: "filter_type-presentations",
|
||||
key: FilterType.PresentationsOnly.toString(),
|
||||
group: FilterGroups.filterType,
|
||||
label: t("FormsTemplates").toLowerCase(),
|
||||
label: t("Translations:Presentations").toLowerCase(),
|
||||
},
|
||||
{
|
||||
id: "filter_type-forms",
|
||||
key: FilterType.OFormOnly.toString(),
|
||||
key: FilterType.Pdf.toString(),
|
||||
group: FilterGroups.filterType,
|
||||
label: t("Forms").toLowerCase(),
|
||||
},
|
||||
...archives,
|
||||
|
||||
...images,
|
||||
...media,
|
||||
{
|
||||
id: "filter_type-all-files",
|
||||
key: FilterType.FilesOnly.toString(),
|
||||
group: FilterGroups.filterType,
|
||||
label: t("AllFiles").toLowerCase(),
|
||||
},
|
||||
];
|
||||
|
||||
const subjectOptions = [
|
||||
|
@ -159,6 +159,7 @@ const PureHome = (props) => {
|
||||
userId,
|
||||
getFolderModel,
|
||||
scrollToTop,
|
||||
isEmptyGroups,
|
||||
} = props;
|
||||
|
||||
//console.log(t("ComingSoon"))
|
||||
@ -173,6 +174,7 @@ const PureHome = (props) => {
|
||||
const isPeopleAccounts = location.pathname.includes("accounts/people");
|
||||
const isGroupsAccounts =
|
||||
location.pathname.includes("accounts/groups") && !groupId;
|
||||
const isAccountsEmptyFilter = isGroupsAccounts && isEmptyGroups;
|
||||
|
||||
const { onDrop } = useFiles({
|
||||
t,
|
||||
@ -387,8 +389,10 @@ const PureHome = (props) => {
|
||||
</Section.SectionWarning>
|
||||
)}
|
||||
|
||||
{(((!isEmptyPage || showFilterLoader) && !isErrorRoomNotAvailable) ||
|
||||
isAccountsPage) &&
|
||||
{(((!isEmptyPage || showFilterLoader) &&
|
||||
!isAccountsEmptyFilter &&
|
||||
!isErrorRoomNotAvailable) ||
|
||||
(!isAccountsEmptyFilter && isAccountsPage)) &&
|
||||
!isSettingsPage && (
|
||||
<Section.SectionFilter>
|
||||
{isFrame ? (
|
||||
@ -560,7 +564,8 @@ export default inject(
|
||||
const { usersStore, groupsStore, viewAs: accountsViewAs } = peopleStore;
|
||||
|
||||
const { getUsersList: fetchPeople } = usersStore;
|
||||
const { getGroups: fetchGroups, fetchGroup } = groupsStore;
|
||||
const { getGroups: fetchGroups, fetchGroup, groups } = groupsStore;
|
||||
const isEmptyGroups = (groups && groups.length === 0) || !Boolean(groups);
|
||||
|
||||
if (!firstLoad) {
|
||||
if (isLoading) {
|
||||
@ -673,6 +678,7 @@ export default inject(
|
||||
setSelectedFolder,
|
||||
getFolderModel,
|
||||
scrollToTop,
|
||||
isEmptyGroups,
|
||||
};
|
||||
},
|
||||
)(observer(Home));
|
||||
|
@ -112,11 +112,7 @@ const FileSelector = (props) => {
|
||||
label: t(`Translations:Spreadsheets`),
|
||||
},
|
||||
{
|
||||
key: FilterType.OFormTemplateOnly,
|
||||
label: t(`Files:FormsTemplates`),
|
||||
},
|
||||
{
|
||||
key: FilterType.OFormOnly,
|
||||
key: FilterType.Pdf,
|
||||
label: t(`Files:Forms`),
|
||||
},
|
||||
{
|
||||
@ -133,7 +129,7 @@ const FileSelector = (props) => {
|
||||
},
|
||||
{
|
||||
key: FilterType.FilesOnly,
|
||||
label: t(`Files:AllFiles`),
|
||||
label: t(`Translations:Files`),
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -138,7 +138,7 @@ export const FilterBlock = ({ t, config, setConfig }) => {
|
||||
const filterOptions = [
|
||||
{
|
||||
key: "filter-type-all",
|
||||
label: t("Files:AllFiles"),
|
||||
label: t("Translations:Files"),
|
||||
typeKey: FilterType.FilesOnly,
|
||||
},
|
||||
{
|
||||
@ -176,15 +176,10 @@ export const FilterBlock = ({ t, config, setConfig }) => {
|
||||
label: t("Files:Media"),
|
||||
typeKey: FilterType.MediaOnly,
|
||||
},
|
||||
{
|
||||
key: "filter-type-forms-templates",
|
||||
label: t("Files:FormsTemplates"),
|
||||
typeKey: FilterType.OFormTemplateOnly,
|
||||
},
|
||||
{
|
||||
key: "filter-type-forms",
|
||||
label: t("Files:Forms"),
|
||||
typeKey: FilterType.OFormOnly,
|
||||
typeKey: FilterType.Pdf,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
import SendClockReactSvgUrl from "PUBLIC_DIR/images/send.clock.react.svg?url";
|
||||
import PencilOutlineReactSvgUrl from "PUBLIC_DIR/images/pencil.outline.react.svg?url";
|
||||
import DefaultUserAvatarMax from "PUBLIC_DIR/images/default_user_photo_size_200-200.png";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { inject, observer } from "mobx-react";
|
||||
@ -92,20 +92,43 @@ const MainProfile = (props) => {
|
||||
} = props;
|
||||
|
||||
const [horizontalOrientation, setHorizontalOrientation] = useState(false);
|
||||
const [dimension, setDimension] = useState(window.innerHeight);
|
||||
const [dropDownMaxHeight, setDropDownMaxHeight] = useState(352);
|
||||
const { interfaceDirection } = useTheme();
|
||||
const dirTooltip = interfaceDirection === "rtl" ? "left" : "right";
|
||||
|
||||
const { isOwner, isAdmin, isRoomAdmin, isCollaborator } = profile;
|
||||
|
||||
useEffect(() => {
|
||||
checkWidth();
|
||||
window.addEventListener("resize", checkWidth);
|
||||
return () => window.removeEventListener("resize", checkWidth);
|
||||
}, []);
|
||||
const comboBoxRef = useRef(null);
|
||||
|
||||
const checkWidth = () => {
|
||||
setDimension(innerHeight);
|
||||
const updateDropDownMaxHeight = () => {
|
||||
const newDimension = window.innerHeight;
|
||||
|
||||
if (comboBoxRef.current) {
|
||||
const comboBoxRect = comboBoxRef.current.getBoundingClientRect();
|
||||
let availableSpaceBottom = newDimension - comboBoxRect.bottom - 20;
|
||||
|
||||
availableSpaceBottom = Math.max(availableSpaceBottom, 100);
|
||||
|
||||
const newDropDownMaxHeight = Math.min(availableSpaceBottom, 352);
|
||||
setDropDownMaxHeight(newDropDownMaxHeight);
|
||||
}
|
||||
};
|
||||
|
||||
const checkScroll = () => {
|
||||
updateDropDownMaxHeight();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
updateDropDownMaxHeight();
|
||||
window.addEventListener("resize", updateDropDownMaxHeight);
|
||||
window.addEventListener("scroll", checkScroll);
|
||||
return () => {
|
||||
window.removeEventListener("resize", updateDropDownMaxHeight);
|
||||
window.removeEventListener("scroll", checkScroll);
|
||||
};
|
||||
}, [cultureNames]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMobileOnly) return;
|
||||
|
||||
if (!isMobile()) {
|
||||
@ -113,7 +136,7 @@ const MainProfile = (props) => {
|
||||
} else {
|
||||
setHorizontalOrientation(false);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const role = getUserRole(profile);
|
||||
|
||||
@ -356,7 +379,7 @@ const MainProfile = (props) => {
|
||||
tooltipContent={tooltipLanguage}
|
||||
/>
|
||||
</StyledLabel>
|
||||
<div className="language-combo-box-wrapper">
|
||||
<div className="language-combo-box-wrapper" ref={comboBoxRef}>
|
||||
<ComboBox
|
||||
className="language-combo-box"
|
||||
directionY={isMobileHorizontalOrientation ? "bottom" : "both"}
|
||||
@ -368,7 +391,7 @@ const MainProfile = (props) => {
|
||||
scaledOptions={false}
|
||||
size="content"
|
||||
showDisabledItems={true}
|
||||
dropDownMaxHeight={dimension < 620 ? 200 : 364}
|
||||
dropDownMaxHeight={dropDownMaxHeight}
|
||||
manualWidth="280px"
|
||||
isDefaultMode={
|
||||
isMobileHorizontalOrientation
|
||||
@ -552,7 +575,7 @@ const MainProfile = (props) => {
|
||||
scaledOptions={false}
|
||||
size="content"
|
||||
showDisabledItems={true}
|
||||
dropDownMaxHeight={dimension < 620 ? 200 : 364}
|
||||
dropDownMaxHeight={dropDownMaxHeight}
|
||||
manualWidth="280px"
|
||||
isDefaultMode={
|
||||
isMobileHorizontalOrientation
|
||||
|
@ -82,10 +82,7 @@ const Sdk = ({
|
||||
[FilterType.FoldersOnly]: t("Common:SelectTypeFiles", {
|
||||
type: t("Translations:Folders").toLowerCase(),
|
||||
}),
|
||||
[FilterType.OFormTemplateOnly]: t("Common:SelectTypeFiles", {
|
||||
type: t("Files:FormsTemplates").toLowerCase(),
|
||||
}),
|
||||
[FilterType.OFormOnly]: t("Common:SelectTypeFiles", {
|
||||
[FilterType.Pdf]: t("Common:SelectTypeFiles", {
|
||||
type: t("Files:Forms").toLowerCase(),
|
||||
}),
|
||||
EditorSupportedTypes: t("Common:SelectTypeFiles", {
|
||||
|
@ -1108,7 +1108,10 @@ class FilesActionStore {
|
||||
: t("RoomPinned"),
|
||||
),
|
||||
)
|
||||
.catch((error) => console.log(error));
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
toastr.error(t("RoomsPinLimitMessage"));
|
||||
});
|
||||
case "unpin":
|
||||
items.forEach((item) => {
|
||||
updateRoomPin(item);
|
||||
|
@ -2072,7 +2072,8 @@ class FilesStore {
|
||||
item.viewAccessibility.ImageView || item.viewAccessibility.MediaView;
|
||||
const canViewFile = item.viewAccessibility.WebView;
|
||||
|
||||
const isMasterForm = item.fileExst === ".docxf";
|
||||
const isOldForm =
|
||||
item.fileExst === ".docxf" || item.fileExst === ".oform"; //TODO: Remove after change security options
|
||||
const isPdf = item.fileExst === ".pdf";
|
||||
|
||||
let fileOptions = [
|
||||
@ -2197,10 +2198,10 @@ class FilesStore {
|
||||
fileOptions = this.removeOptions(fileOptions, ["move"]);
|
||||
}
|
||||
|
||||
if (!(isMasterForm && canDuplicate))
|
||||
if (!(isOldForm && canDuplicate))
|
||||
fileOptions = this.removeOptions(fileOptions, ["make-form"]);
|
||||
|
||||
if (!canSubmitToFormGallery || isMasterForm) {
|
||||
if (!canSubmitToFormGallery || isOldForm) {
|
||||
fileOptions = this.removeOptions(fileOptions, [
|
||||
"submit-to-gallery",
|
||||
"separator-SubmitToGallery",
|
||||
@ -3541,7 +3542,7 @@ class FilesStore {
|
||||
case FilterType.ArchiveOnly:
|
||||
return t("Archives");
|
||||
case FilterType.FilesOnly:
|
||||
return t("AllFiles");
|
||||
return t("Translations:Files");
|
||||
case `room-${RoomsType.FillingFormsRoom}`:
|
||||
return t("Common:FillingFormRooms");
|
||||
case `room-${RoomsType.CustomRoom}`:
|
||||
|
@ -1647,6 +1647,7 @@ class UploadDataStore {
|
||||
.then(() =>
|
||||
this.moveToCopyTo(destFolderId, pbData, true, fileIds, folderIds),
|
||||
)
|
||||
.catch((error) => toastr.error(error))
|
||||
.finally(async () => {
|
||||
//to update the status of trashIsEmpty filesStore
|
||||
if (this.treeFoldersStore.isRecycleBinFolder)
|
||||
|
@ -1,51 +0,0 @@
|
||||
{
|
||||
"name": "@docspace/common",
|
||||
"version": "2.0.3",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "echo 'skip it'",
|
||||
"clean": "echo 'skip it'",
|
||||
"deploy": "echo 'skip it'",
|
||||
"start": "echo 'skip it'",
|
||||
"start-prod": "echo 'skip it'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@loadable/component": "^5.15.3",
|
||||
"axios": "^0.22.0",
|
||||
"cross-fetch": "3.1.5",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"global": "^4.4.0",
|
||||
"i18next": "^20.6.1",
|
||||
"mobx": "^6.8.0",
|
||||
"mobx-react": "^7.6.0",
|
||||
"moment": "^2.29.4",
|
||||
"moment-timezone": "^0.5.43",
|
||||
"prop-types": "^15.8.1",
|
||||
"query-string": "7.1.3",
|
||||
"re-resizable": "^6.9.9",
|
||||
"react": "^18.2.0",
|
||||
"react-autosize-textarea": "^7.1.0",
|
||||
"react-content-loader": "^5.1.4",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hammerjs": "^1.0.1",
|
||||
"react-i18next": "^13.2.1",
|
||||
"react-player": "^1.15.3",
|
||||
"react-router": "^6.10.0",
|
||||
"react-router-dom": "^6.10.0",
|
||||
"react-tooltip": "^5.23.0",
|
||||
"react-viewer": "^3.2.2",
|
||||
"react-virtualized-auto-sizer": "^1.0.7",
|
||||
"react-window": "^1.8.8",
|
||||
"react-window-infinite-loader": "^1.0.8",
|
||||
"screenfull": "^5.2.0",
|
||||
"sjcl": "^1.0.8",
|
||||
"socket.io-client": "^4.6.1",
|
||||
"styled-components": "^5.3.9",
|
||||
"workbox-window": "^6.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/crypto-js": "^4.2.1",
|
||||
"@welldone-software/why-did-you-render": "^6.2.3"
|
||||
}
|
||||
}
|
@ -1,244 +0,0 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import TextInput from "../text-input";
|
||||
import { Icons } from "../icons";
|
||||
import IconButton from "../icon-button";
|
||||
import {
|
||||
StyledInputGroup,
|
||||
StyledChildrenBlock,
|
||||
StyledIconBlock,
|
||||
} from "./styled-input-block";
|
||||
|
||||
//const iconNames = Object.keys(Icons);
|
||||
|
||||
class InputBlock extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
onIconClick = (e) => {
|
||||
if (
|
||||
typeof this.props.onIconClick === "function" /*&& !this.props.isDisabled*/
|
||||
)
|
||||
this.props.onIconClick(e);
|
||||
};
|
||||
onChange = (e) => {
|
||||
if (typeof this.props.onChange === "function") this.props.onChange(e);
|
||||
};
|
||||
|
||||
render() {
|
||||
let iconButtonSize = 0;
|
||||
const {
|
||||
hasError,
|
||||
hasWarning,
|
||||
isDisabled,
|
||||
scale,
|
||||
size,
|
||||
className,
|
||||
style,
|
||||
children,
|
||||
id,
|
||||
name,
|
||||
type,
|
||||
value,
|
||||
placeholder,
|
||||
tabIndex,
|
||||
maxLength,
|
||||
onBlur,
|
||||
onFocus,
|
||||
onKeyDown,
|
||||
isReadOnly,
|
||||
isAutoFocussed,
|
||||
autoComplete,
|
||||
mask,
|
||||
keepCharPositions,
|
||||
iconName,
|
||||
iconColor,
|
||||
hoverColor,
|
||||
isIconFill,
|
||||
onIconClick,
|
||||
iconSize,
|
||||
theme,
|
||||
forwardedRef,
|
||||
onClick,
|
||||
iconButtonClassName,
|
||||
iconNode,
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
if (typeof iconSize == "number" && iconSize > 0) {
|
||||
iconButtonSize = iconSize;
|
||||
} else {
|
||||
switch (size) {
|
||||
case "base":
|
||||
iconButtonSize = 16;
|
||||
break;
|
||||
case "middle":
|
||||
iconButtonSize = 18;
|
||||
break;
|
||||
case "big":
|
||||
iconButtonSize = 21;
|
||||
break;
|
||||
case "huge":
|
||||
iconButtonSize = 24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<StyledInputGroup
|
||||
hasError={hasError}
|
||||
hasWarning={hasWarning}
|
||||
isDisabled={isDisabled}
|
||||
scale={scale}
|
||||
size={size}
|
||||
className={className}
|
||||
style={style}
|
||||
color={iconColor}
|
||||
hoverColor={hoverColor}
|
||||
>
|
||||
<div className="prepend">
|
||||
<StyledChildrenBlock className="prepend-children">
|
||||
{children}
|
||||
</StyledChildrenBlock>
|
||||
</div>
|
||||
<TextInput
|
||||
id={id}
|
||||
className={className}
|
||||
name={name}
|
||||
type={type}
|
||||
value={value}
|
||||
onClick={onClick}
|
||||
isDisabled={isDisabled}
|
||||
hasError={hasError}
|
||||
hasWarning={hasWarning}
|
||||
placeholder={placeholder}
|
||||
tabIndex={tabIndex}
|
||||
maxLength={maxLength}
|
||||
onBlur={onBlur}
|
||||
onFocus={onFocus}
|
||||
isReadOnly={isReadOnly}
|
||||
isAutoFocussed={isAutoFocussed}
|
||||
autoComplete={autoComplete}
|
||||
size={size}
|
||||
scale={scale}
|
||||
onChange={this.onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
withBorder={false}
|
||||
mask={mask}
|
||||
keepCharPositions={keepCharPositions}
|
||||
forwardedRef={forwardedRef}
|
||||
{...props}
|
||||
/>
|
||||
{iconName && (
|
||||
<div className="append">
|
||||
<StyledIconBlock
|
||||
className={`input-block-icon ${iconButtonClassName}`}
|
||||
//isDisabled={isDisabled}
|
||||
onClick={this.onIconClick}
|
||||
isClickable={typeof onIconClick === "function"}
|
||||
>
|
||||
<IconButton
|
||||
size={iconButtonSize}
|
||||
iconNode={iconNode}
|
||||
iconName={iconName}
|
||||
isFill={isIconFill}
|
||||
//isDisabled={isDisabled}
|
||||
isClickable={typeof onIconClick === "function"}
|
||||
color={iconColor}
|
||||
hoverColor={hoverColor}
|
||||
/>
|
||||
</StyledIconBlock>
|
||||
</div>
|
||||
)}
|
||||
</StyledInputGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
InputBlock.propTypes = {
|
||||
/** Used as HTML `id` property */
|
||||
id: PropTypes.string,
|
||||
/** Forwarded ref */
|
||||
forwardedRef: PropTypes.object,
|
||||
/** Used as HTML `name` property */
|
||||
name: PropTypes.string,
|
||||
/** Supported type of the input fields. */
|
||||
type: PropTypes.oneOf(["text", "password"]),
|
||||
/** Defines max length of value */
|
||||
maxLength: PropTypes.number,
|
||||
/** Placeholder text for the input */
|
||||
placeholder: PropTypes.string,
|
||||
/** Accepts css tab-index */
|
||||
tabIndex: PropTypes.number,
|
||||
/** input text mask */
|
||||
mask: PropTypes.oneOfType([PropTypes.array, PropTypes.func]),
|
||||
/** Allows to add or delete characters without changing the positions of the existing characters.*/
|
||||
keepCharPositions: PropTypes.bool,
|
||||
/** Supported size of the input fields. */
|
||||
size: PropTypes.oneOf(["base", "middle", "big", "huge", "large"]),
|
||||
/** Indicates that the input field has scale */
|
||||
scale: PropTypes.bool,
|
||||
/** The callback function that is required when the input is not read only. The function is called with the new value. Parent should pass it back as `value` */
|
||||
onChange: PropTypes.func,
|
||||
/** The callback function that is called when the field is blurred */
|
||||
onBlur: PropTypes.func,
|
||||
/** The callback function that is called when the field is focused */
|
||||
onFocus: PropTypes.func,
|
||||
/** Focuses on the input field on initial render */
|
||||
isAutoFocussed: PropTypes.bool,
|
||||
/** Indicates that the field cannot be used (e.g not authorised, or changes not saved) */
|
||||
isDisabled: PropTypes.bool,
|
||||
/** Indicates that the field is displaying read-only content */
|
||||
isReadOnly: PropTypes.bool,
|
||||
/** Indicates the input field has an error */
|
||||
hasError: PropTypes.bool,
|
||||
/** Indicates the input field has a warning */
|
||||
hasWarning: PropTypes.bool,
|
||||
/** Used as HTML `autocomplete` */
|
||||
autoComplete: PropTypes.string,
|
||||
/** Value of the input */
|
||||
value: PropTypes.string,
|
||||
/** Path to icon */
|
||||
iconName: PropTypes.string,
|
||||
/** Specifies the icon color */
|
||||
iconColor: PropTypes.string,
|
||||
/** Icon color on hover action */
|
||||
hoverColor: PropTypes.string,
|
||||
/** Size icon */
|
||||
iconSize: PropTypes.number,
|
||||
/** Determines if icon fill is needed */
|
||||
isIconFill: PropTypes.bool,
|
||||
/** The callback function that is triggered when the icon is clicked */
|
||||
onIconClick: PropTypes.func,
|
||||
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node,
|
||||
]),
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Sets the classNaame of the icon button */
|
||||
iconButtonClassName: PropTypes.string,
|
||||
};
|
||||
|
||||
InputBlock.defaultProps = {
|
||||
type: "text",
|
||||
maxLength: 255,
|
||||
size: "base",
|
||||
scale: false,
|
||||
tabIndex: -1,
|
||||
hasError: false,
|
||||
hasWarning: false,
|
||||
autoComplete: "off",
|
||||
|
||||
value: "",
|
||||
iconName: "",
|
||||
isIconFill: false,
|
||||
isDisabled: false,
|
||||
keepCharPositions: false,
|
||||
iconButtonClassName: "",
|
||||
};
|
||||
|
||||
export default InputBlock;
|
@ -1,99 +0,0 @@
|
||||
import React from "react";
|
||||
import CrossReactSvgUrl from "PUBLIC_DIR/images/cross.react.svg?url";
|
||||
import { StyledSelectedItem, StyledLabel } from "./styled-selected-item";
|
||||
import PropTypes from "prop-types";
|
||||
import IconButton from "../icon-button";
|
||||
|
||||
const SelectedItem = (props) => {
|
||||
const {
|
||||
label,
|
||||
onClose,
|
||||
isDisabled,
|
||||
onClick,
|
||||
isInline,
|
||||
className,
|
||||
id,
|
||||
propKey,
|
||||
group,
|
||||
forwardedRef,
|
||||
classNameCloseButton,
|
||||
hideCross,
|
||||
} = props;
|
||||
if (!label) return <></>;
|
||||
|
||||
const onCloseClick = (e) => {
|
||||
!isDisabled && onClose && onClose(propKey, label, group, e);
|
||||
};
|
||||
|
||||
const handleOnClick = (e) => {
|
||||
!isDisabled &&
|
||||
onClick &&
|
||||
!e.target.classList.contains("selected-tag-removed") &&
|
||||
onClick(propKey, label, group, e);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledSelectedItem
|
||||
onClick={handleOnClick}
|
||||
isInline={isInline}
|
||||
className={className}
|
||||
isDisabled={isDisabled}
|
||||
id={id}
|
||||
ref={forwardedRef}
|
||||
>
|
||||
<StyledLabel
|
||||
className="selected-item_label"
|
||||
truncate={true}
|
||||
noSelect
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
{label}
|
||||
</StyledLabel>
|
||||
{!hideCross && (
|
||||
<IconButton
|
||||
className={"selected-tag-removed " + classNameCloseButton}
|
||||
iconName={CrossReactSvgUrl}
|
||||
size={12}
|
||||
onClick={onCloseClick}
|
||||
isFill
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
)}
|
||||
</StyledSelectedItem>
|
||||
);
|
||||
};
|
||||
|
||||
SelectedItem.propTypes = {
|
||||
/** Selected item text */
|
||||
label: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||||
/** Sets the 'width: fit-content' property */
|
||||
isInline: PropTypes.bool,
|
||||
/** Hide cross icon */
|
||||
hideCross: PropTypes.bool,
|
||||
/** Sets a callback function that is triggered when the cross icon is clicked */
|
||||
onClose: PropTypes.func.isRequired,
|
||||
/** Sets a callback function that is triggered when the selected item is clicked */
|
||||
onClick: PropTypes.func,
|
||||
/** Sets the button to present a disabled state */
|
||||
isDisabled: PropTypes.bool,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Accepts key to remove item */
|
||||
propKey: PropTypes.string,
|
||||
/** Accepts group key to remove item */
|
||||
group: PropTypes.string,
|
||||
/** Passes ref to component */
|
||||
forwardedRef: PropTypes.object,
|
||||
};
|
||||
|
||||
SelectedItem.defaultProps = {
|
||||
isInline: true,
|
||||
hideCross: false,
|
||||
isDisabled: false,
|
||||
};
|
||||
|
||||
export default React.memo(SelectedItem);
|
@ -1,70 +0,0 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import equal from "fast-deep-equal/react";
|
||||
|
||||
import Text from "../text";
|
||||
import StyledSocialButton from "./styled-social-button";
|
||||
import { ReactSVG } from "react-svg";
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
||||
class SocialButton extends React.Component {
|
||||
shouldComponentUpdate(nextProps) {
|
||||
return !equal(this.props, nextProps);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { label, iconName, IconComponent, image, isConnect, ...otherProps } =
|
||||
this.props;
|
||||
return (
|
||||
<StyledSocialButton isConnect={isConnect} {...otherProps}>
|
||||
{IconComponent ? (
|
||||
<IconComponent className="iconWrapper" />
|
||||
) : (
|
||||
<ReactSVG className="iconWrapper" src={iconName} />
|
||||
)}
|
||||
{label && (
|
||||
<Text as="div" className="social_button_text">
|
||||
{label}
|
||||
</Text>
|
||||
)}
|
||||
</StyledSocialButton>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SocialButton.propTypes = {
|
||||
/** Button text */
|
||||
label: PropTypes.string,
|
||||
/** Button icon */
|
||||
iconName: PropTypes.string,
|
||||
/** Accepts tabindex prop */
|
||||
tabIndex: PropTypes.number,
|
||||
/** Sets the button to present a disabled state */
|
||||
isDisabled: PropTypes.bool,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Sets a callback function that is triggered when the button is clicked */
|
||||
onClick: PropTypes.func,
|
||||
/** Accepts the icon options */
|
||||
$iconOptions: PropTypes.object,
|
||||
/** Sets the image size. Contains the small and the basic size options */
|
||||
size: PropTypes.oneOf(["base", "small"]),
|
||||
/** Changes the button style if the user is connected to the social network account */
|
||||
isConnect: PropTypes.bool,
|
||||
};
|
||||
|
||||
SocialButton.defaultProps = {
|
||||
label: "",
|
||||
iconName: "SocialButtonGoogleIcon",
|
||||
tabIndex: -1,
|
||||
isDisabled: false,
|
||||
$iconOptions: {},
|
||||
size: "base",
|
||||
isConnect: false,
|
||||
};
|
||||
|
||||
export default SocialButton;
|
@ -1,208 +0,0 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import CrossIconReactSvgUrl from "PUBLIC_DIR/images/cross.react.svg?url";
|
||||
import TagIconReactSvgUrl from "PUBLIC_DIR/images/tag.react.svg?url";
|
||||
import DropDown from "../drop-down";
|
||||
import DropDownItem from "../drop-down-item";
|
||||
import IconButton from "../icon-button";
|
||||
import Text from "../text";
|
||||
|
||||
import {
|
||||
StyledTag,
|
||||
StyledDropdownIcon,
|
||||
StyledDropdownText,
|
||||
} from "./styled-tag";
|
||||
|
||||
const Tag = ({
|
||||
tag,
|
||||
label,
|
||||
isNewTag,
|
||||
isDisabled,
|
||||
isDefault,
|
||||
isLast,
|
||||
onDelete,
|
||||
onClick,
|
||||
advancedOptions,
|
||||
tagMaxWidth,
|
||||
id,
|
||||
className,
|
||||
style,
|
||||
icon,
|
||||
removeTagIcon,
|
||||
}) => {
|
||||
const [openDropdown, setOpenDropdown] = React.useState(false);
|
||||
|
||||
const tagRef = React.useRef(null);
|
||||
const isMountedRef = React.useRef(true);
|
||||
const onClickOutside = React.useCallback((e) => {
|
||||
if (e?.target?.className?.includes("advanced-tag") || !isMountedRef.current)
|
||||
return;
|
||||
|
||||
setOpenDropdown(false);
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (openDropdown) {
|
||||
return document.addEventListener("click", onClickOutside);
|
||||
}
|
||||
|
||||
document.removeEventListener("click", onClickOutside);
|
||||
return () => {
|
||||
document.removeEventListener("click", onClickOutside);
|
||||
};
|
||||
}, [openDropdown, onClickOutside]);
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => {
|
||||
isMountedRef.current = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const openDropdownAction = (e) => {
|
||||
if (e?.target?.className?.includes("backdrop-active")) return;
|
||||
|
||||
setOpenDropdown(true);
|
||||
};
|
||||
|
||||
const onClickAction = React.useCallback(
|
||||
(e) => {
|
||||
if (onClick && !isDisabled) {
|
||||
onClick(e.target.dataset.tag);
|
||||
}
|
||||
},
|
||||
[onClick, isDisabled]
|
||||
);
|
||||
|
||||
const onDeleteAction = React.useCallback(
|
||||
(e) => {
|
||||
if (e.target != tagRef.current && onDelete) {
|
||||
onDelete && onDelete(tag);
|
||||
}
|
||||
},
|
||||
[onDelete, tag, tagRef]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{!!advancedOptions ? (
|
||||
<>
|
||||
<StyledTag
|
||||
id={id}
|
||||
className={`tag advanced-tag ${className ? ` ${className}` : ""}`}
|
||||
style={style}
|
||||
ref={tagRef}
|
||||
onClick={openDropdownAction}
|
||||
isDisabled={isDisabled}
|
||||
isDefault={isDefault}
|
||||
isLast={isLast}
|
||||
tagMaxWidth={tagMaxWidth}
|
||||
isClickable={!!onClick}
|
||||
>
|
||||
<Text className={"tag-text"} font-size={"13px"} noSelect>
|
||||
...
|
||||
</Text>
|
||||
</StyledTag>
|
||||
<DropDown
|
||||
open={openDropdown}
|
||||
forwardedRef={tagRef}
|
||||
clickOutsideAction={onClickOutside}
|
||||
// directionX={"right"}
|
||||
manualY={"4px"}
|
||||
>
|
||||
{advancedOptions.map((tag, index) => (
|
||||
<DropDownItem
|
||||
className="tag__dropdown-item tag"
|
||||
key={`${tag}_${index}`}
|
||||
onClick={onClickAction}
|
||||
data-tag={tag}
|
||||
>
|
||||
{!removeTagIcon && (
|
||||
<StyledDropdownIcon
|
||||
className="tag__dropdown-item-icon"
|
||||
src={TagIconReactSvgUrl}
|
||||
/>
|
||||
)}
|
||||
<StyledDropdownText
|
||||
className="tag__dropdown-item-text"
|
||||
fontWeight={600}
|
||||
fontSize={"12px"}
|
||||
truncate
|
||||
removeTagIcon={removeTagIcon}
|
||||
>
|
||||
{tag}
|
||||
</StyledDropdownText>
|
||||
</DropDownItem>
|
||||
))}
|
||||
</DropDown>
|
||||
</>
|
||||
) : (
|
||||
<StyledTag
|
||||
title={label}
|
||||
onClick={onClickAction}
|
||||
isNewTag={isNewTag}
|
||||
isDisabled={isDisabled}
|
||||
isDefault={isDefault}
|
||||
tagMaxWidth={tagMaxWidth}
|
||||
data-tag={label}
|
||||
id={id}
|
||||
className={`tag${className ? ` ${className}` : ""}`}
|
||||
style={style}
|
||||
isLast={isLast}
|
||||
isClickable={!!onClick}
|
||||
>
|
||||
{icon ? (
|
||||
<ReactSVG className="third-party-tag" src={icon} />
|
||||
) : (
|
||||
<>
|
||||
<Text
|
||||
className={"tag-text"}
|
||||
title={label}
|
||||
font-size={"13px"}
|
||||
noSelect
|
||||
truncate
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
{isNewTag && (
|
||||
<IconButton
|
||||
className={"tag-icon"}
|
||||
iconName={CrossIconReactSvgUrl}
|
||||
size={"10px"}
|
||||
onClick={onDeleteAction}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</StyledTag>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Tag.propTypes = {
|
||||
/** Accepts the tag id */
|
||||
tag: PropTypes.string,
|
||||
/** Accepts the tag label */
|
||||
label: PropTypes.string,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Accepts the tag styles as new and adds the delete button */
|
||||
isNewTag: PropTypes.bool,
|
||||
/** Accepts the tag styles as disabled and disables clicking */
|
||||
isDisabled: PropTypes.bool,
|
||||
/** Accepts the function that is called when the tag is clicked */
|
||||
onClick: PropTypes.func,
|
||||
/** Accepts the function that ist called when the tag delete button is clicked */
|
||||
onDelete: PropTypes.func,
|
||||
/** Accepts the max width of the tag */
|
||||
tagMaxWidth: PropTypes.string,
|
||||
/** Accepts the dropdown options */
|
||||
advancedOptions: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
};
|
||||
|
||||
export default React.memo(Tag);
|
@ -1,147 +0,0 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import Tag from "../tag";
|
||||
|
||||
import StyledTags from "./StyledTags";
|
||||
|
||||
const Tags = ({
|
||||
id,
|
||||
className,
|
||||
style,
|
||||
tags,
|
||||
columnCount,
|
||||
onSelectTag,
|
||||
removeTagIcon,
|
||||
}) => {
|
||||
const [renderedTags, setRenderedTags] = React.useState(null);
|
||||
|
||||
const tagsRef = React.useRef(null);
|
||||
|
||||
const updateRenderedTags = React.useCallback(() => {
|
||||
if (tags && tagsRef) {
|
||||
if (!columnCount) return;
|
||||
|
||||
const newTags = [];
|
||||
const containerWidth = tagsRef.current.offsetWidth;
|
||||
|
||||
if (tags.length === 1) {
|
||||
if (tags[0]?.isDefault) {
|
||||
const tag = { ...tags[0], maxWidth: `100%` };
|
||||
newTags.push(tag);
|
||||
} else if (tags[0]?.isThirdParty) {
|
||||
const tag = { ...tags[0], maxWidth: `36px` };
|
||||
newTags.push(tag);
|
||||
} else {
|
||||
const tag = { label: tags[0].label || tags[0], maxWidth: `100%` };
|
||||
newTags.push(tag);
|
||||
}
|
||||
|
||||
return setRenderedTags(newTags);
|
||||
}
|
||||
|
||||
if (
|
||||
columnCount >= tags.length ||
|
||||
(tags.length === 2 && tags[0]?.isThirdParty && tags[1]?.isDefault)
|
||||
) {
|
||||
const thirdPartyTagCount = tags[0]?.isThirdParty ? 1 : 0;
|
||||
|
||||
const currentTagMaxWidth =
|
||||
(containerWidth -
|
||||
thirdPartyTagCount * 40 -
|
||||
(tags.length - thirdPartyTagCount) * 4) /
|
||||
(tags.length - thirdPartyTagCount);
|
||||
|
||||
const maxWidthPercent = Math.floor(
|
||||
(currentTagMaxWidth / containerWidth) * 100
|
||||
);
|
||||
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
if (tags[i]?.isThirdParty) {
|
||||
const tag = { ...tags[i], maxWidth: `36px` };
|
||||
newTags.push(tag);
|
||||
} else if (tags[i]?.isDefault) {
|
||||
const tag = { ...tags[i], maxWidth: `${maxWidthPercent}%` };
|
||||
newTags.push(tag);
|
||||
} else {
|
||||
const tag = { label: tags[i], maxWidth: `${maxWidthPercent}%` };
|
||||
newTags.push(tag);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const tagWithDropdown = {
|
||||
key: "selector",
|
||||
advancedOptions: tags.slice(columnCount, tags.length),
|
||||
};
|
||||
|
||||
const currentTagMaxWidth =
|
||||
(containerWidth - columnCount * 4 - 35) / columnCount;
|
||||
|
||||
const maxWidthPercent = Math.floor(
|
||||
(currentTagMaxWidth / containerWidth) * 100
|
||||
);
|
||||
|
||||
if (columnCount !== 0) {
|
||||
for (let i = 0; i < columnCount; i++) {
|
||||
if (tags[i]?.isThirdParty) {
|
||||
const tag = { ...tags[i], maxWidth: `36px` };
|
||||
newTags.push(tag);
|
||||
} else if (tags[i]?.isDefault) {
|
||||
const tag = { ...tags[i], maxWidth: `${maxWidthPercent}%` };
|
||||
newTags.push(tag);
|
||||
} else {
|
||||
const tag = { label: tags[i], maxWidth: `${maxWidthPercent}%` };
|
||||
newTags.push(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newTags.push(tagWithDropdown);
|
||||
|
||||
newTags[newTags.length - 1].maxWidth = `35px`;
|
||||
}
|
||||
|
||||
setRenderedTags(newTags);
|
||||
}
|
||||
}, [tags, tagsRef, columnCount]);
|
||||
|
||||
React.useEffect(() => {
|
||||
updateRenderedTags();
|
||||
}, [tags, tagsRef, columnCount]);
|
||||
|
||||
return (
|
||||
<StyledTags id={id} className={className} style={style} ref={tagsRef}>
|
||||
{renderedTags?.length > 0 &&
|
||||
renderedTags.map((tag, index) => (
|
||||
<Tag
|
||||
key={`${tag.label}_${index}`}
|
||||
label={tag.label}
|
||||
advancedOptions={tag.advancedOptions}
|
||||
tagMaxWidth={tag.maxWidth}
|
||||
tagMinWidth={tag.minWidth}
|
||||
isNewTag={false}
|
||||
onClick={onSelectTag}
|
||||
isLast={index === renderedTags.length - 1}
|
||||
removeTagIcon={removeTagIcon}
|
||||
{...tag}
|
||||
/>
|
||||
))}
|
||||
</StyledTags>
|
||||
);
|
||||
};
|
||||
|
||||
Tags.propTypes = {
|
||||
/** Accepts the tags */
|
||||
tags: PropTypes.array,
|
||||
/** Accepts the tag column count */
|
||||
columnCount: PropTypes.number,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Accepts the function that is called when the tag is selected */
|
||||
onSelectTag: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Tags;
|
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,7 @@ import { mobile, tablet } from "@docspace/shared/utils/device";
|
||||
|
||||
export const LoginFormWrapper = styled.div<{ bgPattern: string }>`
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
|
@ -306,8 +306,14 @@ const LoginForm = ({
|
||||
return;
|
||||
}
|
||||
|
||||
checkConfirmLink(confirmData);
|
||||
|
||||
try {
|
||||
if (confirmData) await checkConfirmLink(confirmData);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return res;
|
||||
})
|
||||
.then((res: string | object) => {
|
||||
const isConfirm = typeof res === "string" && res.includes("confirm");
|
||||
const redirectPath =
|
||||
referenceUrl || sessionStorage.getItem("referenceUrl");
|
||||
@ -364,6 +370,7 @@ const LoginForm = ({
|
||||
router,
|
||||
clientId,
|
||||
referenceUrl,
|
||||
loginData,
|
||||
]);
|
||||
|
||||
const onBlurEmail = () => {
|
||||
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"date": "2024711_121949",
|
||||
"checksums": {
|
||||
"api.js": "9b7b808480a7a3b84fff3bbc086fb3c7",
|
||||
"api.poly.js": "6ef0a93fc185ef373f73abeaa1c9104e",
|
||||
"browserDetector.js": "fedff3ea7197068a5c86c5cf2c51ec31",
|
||||
"config.json": "225114f784ac16f33c0a0cb0a6363438"
|
||||
}
|
||||
}
|
@ -36,8 +36,9 @@ export const initSSR = (headers: Record<string, string>) => {
|
||||
export const request = (
|
||||
options: TReqOption & AxiosRequestConfig,
|
||||
skipRedirect = false,
|
||||
isOAuth = false,
|
||||
) => {
|
||||
return client.request(options, skipRedirect);
|
||||
return client.request(options, skipRedirect, isOAuth);
|
||||
};
|
||||
|
||||
export const setWithCredentialsStatus = (state: boolean) => {
|
||||
|
@ -14,10 +14,14 @@ import {
|
||||
} from "../../utils/oauth/types";
|
||||
|
||||
export const getClient = async (clientId: string): Promise<IClientProps> => {
|
||||
const client = (await request({
|
||||
method: "get",
|
||||
url: `/clients/${clientId}`,
|
||||
})) as IClientResDTO;
|
||||
const client = (await request(
|
||||
{
|
||||
method: "get",
|
||||
url: `/clients/${clientId}`,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
)) as IClientResDTO;
|
||||
|
||||
return transformToClientProps(client);
|
||||
};
|
||||
@ -26,10 +30,14 @@ export const getClientList = async (
|
||||
page: number,
|
||||
limit: number,
|
||||
): Promise<IClientListProps> => {
|
||||
const data = (await request({
|
||||
method: "get",
|
||||
url: `/clients?page=${page}&limit=${limit}`,
|
||||
})) as IClientListDTO;
|
||||
const data = (await request(
|
||||
{
|
||||
method: "get",
|
||||
url: `/clients?page=${page}&limit=${limit}`,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
)) as IClientListDTO;
|
||||
|
||||
const clients: IClientListProps = { ...data, data: [] };
|
||||
|
||||
@ -45,66 +53,94 @@ export const getClientList = async (
|
||||
export const addClient = async (data: IClientReqDTO): Promise<IClientProps> => {
|
||||
data.logout_redirect_uri = data.website_url;
|
||||
|
||||
const client = (await request({
|
||||
method: "post",
|
||||
url: `/clients`,
|
||||
data,
|
||||
})) as IClientResDTO;
|
||||
const client = (await request(
|
||||
{
|
||||
method: "post",
|
||||
url: `/clients`,
|
||||
data,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
)) as IClientResDTO;
|
||||
|
||||
return transformToClientProps(client);
|
||||
};
|
||||
|
||||
export const updateClient = async (clientId: string, data: IClientReqDTO) => {
|
||||
await request({
|
||||
method: "put",
|
||||
url: `/clients/${clientId}`,
|
||||
data,
|
||||
});
|
||||
await request(
|
||||
{
|
||||
method: "put",
|
||||
url: `/clients/${clientId}`,
|
||||
data,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
export const changeClientStatus = async (
|
||||
clientId: string,
|
||||
status: boolean,
|
||||
): Promise<void> => {
|
||||
await request({
|
||||
method: "patch",
|
||||
url: `/clients/${clientId}/activation`,
|
||||
data: { status },
|
||||
});
|
||||
await request(
|
||||
{
|
||||
method: "patch",
|
||||
url: `/clients/${clientId}/activation`,
|
||||
data: { status },
|
||||
},
|
||||
false,
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
export const regenerateSecret = async (
|
||||
clientId: string,
|
||||
): Promise<{ client_secret: string }> => {
|
||||
const clientSecret = (await request({
|
||||
method: "patch",
|
||||
url: `/clients/${clientId}/regenerate`,
|
||||
})) as { client_secret: string };
|
||||
const clientSecret = (await request(
|
||||
{
|
||||
method: "patch",
|
||||
url: `/clients/${clientId}/regenerate`,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
)) as { client_secret: string };
|
||||
|
||||
return clientSecret;
|
||||
};
|
||||
|
||||
export const deleteClient = async (clientId: string): Promise<void> => {
|
||||
await request({
|
||||
method: "delete",
|
||||
url: `/clients/${clientId}`,
|
||||
});
|
||||
await request(
|
||||
{
|
||||
method: "delete",
|
||||
url: `/clients/${clientId}`,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
export const getScope = async (name: string): Promise<TScope> => {
|
||||
const scope = (await request({
|
||||
method: "get",
|
||||
url: `/scopes/${name}`,
|
||||
})) as TScope;
|
||||
const scope = (await request(
|
||||
{
|
||||
method: "get",
|
||||
url: `/scopes/${name}`,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
)) as TScope;
|
||||
|
||||
return scope;
|
||||
};
|
||||
|
||||
export const getScopeList = async (): Promise<TScope[]> => {
|
||||
const scopeList = (await request({
|
||||
method: "get",
|
||||
url: `/scopes`,
|
||||
})) as TScope[];
|
||||
const scopeList = (await request(
|
||||
{
|
||||
method: "get",
|
||||
url: `/scopes`,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
)) as TScope[];
|
||||
|
||||
return scopeList;
|
||||
};
|
||||
@ -113,10 +149,14 @@ export const getConsentList = async (
|
||||
page: number = 0,
|
||||
limit: number = 100,
|
||||
): Promise<TConsentList & { consents: IClientProps[] }> => {
|
||||
const consentList = (await request({
|
||||
method: "get",
|
||||
url: `/clients/consents?page=${page}&limit=${limit}`,
|
||||
})) as TConsentList;
|
||||
const consentList = (await request(
|
||||
{
|
||||
method: "get",
|
||||
url: `/clients/consents?page=${page}&limit=${limit}`,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
)) as TConsentList;
|
||||
|
||||
const consents: IClientProps[] = [];
|
||||
|
||||
@ -138,10 +178,14 @@ export const getConsentList = async (
|
||||
};
|
||||
|
||||
export const revokeUserClient = async (clientId: string): Promise<void> => {
|
||||
await request({
|
||||
method: "delete",
|
||||
url: `/clients/${clientId}/revoke`,
|
||||
});
|
||||
await request(
|
||||
{
|
||||
method: "delete",
|
||||
url: `/clients/${clientId}/revoke`,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
export const onOAuthSubmit = (
|
||||
@ -158,15 +202,19 @@ export const onOAuthSubmit = (
|
||||
formData.append("scope", s);
|
||||
});
|
||||
|
||||
return request({
|
||||
method: "post",
|
||||
url: `/oauth2/authorize`,
|
||||
data: formData,
|
||||
withRedirect: true,
|
||||
headers: {
|
||||
"X-Disable-Redirect": "true",
|
||||
return request(
|
||||
{
|
||||
method: "post",
|
||||
url: `/oauth2/authorize`,
|
||||
data: formData,
|
||||
withRedirect: true,
|
||||
headers: {
|
||||
"X-Disable-Redirect": "true",
|
||||
},
|
||||
},
|
||||
});
|
||||
false,
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
export const onOAuthCancel = (clientId: string, clientState: string) => {
|
||||
@ -175,13 +223,17 @@ export const onOAuthCancel = (clientId: string, clientState: string) => {
|
||||
formData.append("client_id", clientId);
|
||||
formData.append("state", clientState);
|
||||
|
||||
return request({
|
||||
method: "post",
|
||||
url: `/oauth2/authorize`,
|
||||
data: formData,
|
||||
withRedirect: true,
|
||||
headers: {
|
||||
"X-Disable-Redirect": "true",
|
||||
return request(
|
||||
{
|
||||
method: "post",
|
||||
url: `/oauth2/authorize`,
|
||||
data: formData,
|
||||
withRedirect: true,
|
||||
headers: {
|
||||
"X-Disable-Redirect": "true",
|
||||
},
|
||||
},
|
||||
});
|
||||
false,
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
@ -144,8 +144,14 @@ export const enum FilterType {
|
||||
ArchiveOnly = 10,
|
||||
ByExtension = 11,
|
||||
MediaOnly = 12,
|
||||
OFormTemplateOnly = 18,
|
||||
OFormOnly = 19,
|
||||
FillingFormsRooms = 13,
|
||||
EditingRooms = 14,
|
||||
ReviewRooms = 15,
|
||||
ReadOnlyRooms = 16,
|
||||
CustomRooms = 17,
|
||||
PublicRooms = 20,
|
||||
FormRooms = 21,
|
||||
Pdf = 22,
|
||||
}
|
||||
|
||||
/**
|
||||
@ -550,7 +556,6 @@ export const enum FilesSelectorExtendedFilterTypes {
|
||||
Media = "Media",
|
||||
Archives = "Archives",
|
||||
AllFiles = "AllFiles",
|
||||
FormTemplates = "FormTemplates",
|
||||
Forms = "Forms",
|
||||
}
|
||||
|
||||
|
@ -158,16 +158,12 @@ const useFilesHelper = ({
|
||||
filter.extension = "gz,tar";
|
||||
break;
|
||||
|
||||
case FilesSelectorFilterTypes.DOCXF:
|
||||
filter.filterType = FilterType.OFormTemplateOnly;
|
||||
break;
|
||||
|
||||
case FilesSelectorFilterTypes.XLSX:
|
||||
filter.filterType = FilterType.SpreadsheetsOnly;
|
||||
break;
|
||||
|
||||
case FilesSelectorFilterTypes.PDF:
|
||||
filter.extension = FilesSelectorFilterTypes.PDF;
|
||||
filter.filterType = FilterType.Pdf;
|
||||
break;
|
||||
|
||||
case FilterType.DocumentsOnly:
|
||||
@ -198,19 +194,12 @@ const useFilesHelper = ({
|
||||
filter.filterType = FilterType.FoldersOnly;
|
||||
break;
|
||||
|
||||
case FilterType.OFormTemplateOnly:
|
||||
filter.filterType = FilterType.OFormTemplateOnly;
|
||||
break;
|
||||
|
||||
case FilterType.OFormOnly:
|
||||
filter.filterType = FilterType.OFormOnly;
|
||||
break;
|
||||
|
||||
case FilterType.FilesOnly:
|
||||
filter.filterType = FilterType.FilesOnly;
|
||||
break;
|
||||
|
||||
case FilesSelectorFilterTypes.ALL:
|
||||
filter.applyFilterOption = ApplyFilterOption.All;
|
||||
filter.filterType = FilterType.None;
|
||||
break;
|
||||
|
||||
|
@ -185,6 +185,7 @@ class AxiosClient {
|
||||
request = (
|
||||
options: TReqOption & AxiosRequestConfig,
|
||||
skipRedirect = false,
|
||||
isOAuth = false,
|
||||
) => {
|
||||
const onSuccess = (response: TRes) => {
|
||||
const error = this.getResponseError(response);
|
||||
@ -216,9 +217,9 @@ class AxiosClient {
|
||||
if (options.baseURL === "/apisystem" && !response.data.response)
|
||||
return response.data;
|
||||
|
||||
return typeof response.data.response !== "undefined"
|
||||
? response.data.response
|
||||
: response.data;
|
||||
if (isOAuth && !response.data.response) return response.data;
|
||||
|
||||
return response.data.response;
|
||||
};
|
||||
|
||||
const onError = (error: TError) => {
|
||||
|
Loading…
Reference in New Issue
Block a user