Merge branch 'hotfix/v2.6.1' into feature/optimization-editor
This commit is contained in:
commit
24aabb1287
@ -95638,6 +95638,138 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>LdapQuotaInfo</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>LdapSecondName</name>
|
||||
<description/>
|
||||
|
@ -36,6 +36,7 @@
|
||||
"LdapPortNumber": "Port Number",
|
||||
"LdapPortNumberTooltip": "Enter the port number for your LDAP server/Active Directory.",
|
||||
"LdapQuota": "User quota",
|
||||
"LdapQuotaInfo": "To be able to use this attribute, enable user quota in the <0>Storage management settings</0>",
|
||||
"LdapSecondName": "Second name",
|
||||
"LdapSendWelcomeLetter": "Send welcome letter",
|
||||
"LdapSendWelcomeLetterTooltip": "If checked all new users will receive welcome letter. Available only when Mail Attribute is mapped to LDAP.",
|
||||
|
@ -7,7 +7,7 @@
|
||||
"PersonalQuotaHeader": "Your personal storage quota exceeded",
|
||||
"PersonalQuotaHeaderForAdmins": "Storage quota per user exceeded",
|
||||
"PersonalUserQuotaAdminsDescription": "To upload and create new files and folders, please free up disk space, or manage quota per user in the <1>Storage management settings.</1>",
|
||||
"PersonalUserQuotaDescription": "To upload and create new files and folders, please free up disk space, or contact the administrator to increase the storage quota.",
|
||||
"PersonalUserQuotaDescription": "To upload and create new files and folders, please free up disk space, or contact the {{productName}} administrator to increase the storage quota.",
|
||||
"RemoveFilesOrClickToUpgrade": "Remove the unnecessary files or <1>click here</1> to upgrade your tariff plan.",
|
||||
"RemoveFilesOrContactToUpgrade": "Remove the unnecessary files or contact the {{productName}} administrator to upgrade the tariff plan.",
|
||||
"RemoveFilesOrContactToUpgradeQuota": "Remove the unnecessary files or contact the {{productName}} administrator to increase the storage quota.",
|
||||
|
@ -149,7 +149,10 @@ const QuotasBar = ({
|
||||
};
|
||||
|
||||
const getPersonalQuotaDescription = () => {
|
||||
if (!isAdmin) return t("PersonalUserQuotaDescription");
|
||||
if (!isAdmin)
|
||||
return t("PersonalUserQuotaDescription", {
|
||||
productName: t("Common:ProductName"),
|
||||
});
|
||||
|
||||
return (
|
||||
<Trans
|
||||
|
@ -26,16 +26,18 @@
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { matchPath } from "react-router";
|
||||
import { withTranslation } from "react-i18next";
|
||||
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { ModalDialog } from "@docspace/shared/components/modal-dialog";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { mobileMore } from "@docspace/shared/utils";
|
||||
import api from "@docspace/shared/api";
|
||||
|
||||
import ModalDialogContainer from "../ModalDialogContainer";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import styled, { css } from "styled-components";
|
||||
import { mobileMore } from "@docspace/shared/utils";
|
||||
import BodyComponent from "./sub-components/BodyComponent";
|
||||
|
||||
const { deleteUser } = api.people;
|
||||
@ -108,6 +110,7 @@ const DeleteProfileEverDialogComponent = (props) => {
|
||||
removeUser,
|
||||
userIds,
|
||||
filter,
|
||||
refreshInsideGroup,
|
||||
setSelected,
|
||||
deleteWithoutReassign,
|
||||
onlyOneUser,
|
||||
@ -123,15 +126,22 @@ const DeleteProfileEverDialogComponent = (props) => {
|
||||
|
||||
const areUsersOnly = usersToDelete.every((user) => user.isVisitor);
|
||||
|
||||
const isInsideGroup = matchPath(
|
||||
"/accounts/groups/:groupId/filter",
|
||||
location.pathname,
|
||||
);
|
||||
|
||||
const onDeleteUser = (id) => {
|
||||
setIsRequestRunning(true);
|
||||
|
||||
deleteUser(id)
|
||||
.then(() => {
|
||||
return isInsideGroup
|
||||
? refreshInsideGroup()
|
||||
: getUsersList(filter, true);
|
||||
})
|
||||
.then(() => {
|
||||
toastr.success(t("SuccessfullyDeleteUserInfoMessage"));
|
||||
getUsersList(filter, true);
|
||||
|
||||
return;
|
||||
})
|
||||
.catch((error) => toastr.error(error))
|
||||
.finally(() => {
|
||||
@ -142,7 +152,7 @@ const DeleteProfileEverDialogComponent = (props) => {
|
||||
};
|
||||
const onDeleteUsers = (ids) => {
|
||||
setIsRequestRunning(true);
|
||||
removeUser(ids, filter)
|
||||
removeUser(ids, filter, isInsideGroup)
|
||||
.then(() => {
|
||||
toastr.success(t("DeleteGroupUsersSuccessMessage"));
|
||||
})
|
||||
@ -239,6 +249,7 @@ DeleteProfileEverDialog.propTypes = {
|
||||
|
||||
export default inject(({ peopleStore }, { users }) => {
|
||||
const { dialogStore, selectionStore, filterStore, usersStore } = peopleStore;
|
||||
const { refreshInsideGroup } = peopleStore.groupsStore;
|
||||
|
||||
const { getUsersList, needResetUserSelection } = peopleStore.usersStore;
|
||||
|
||||
@ -272,6 +283,7 @@ export default inject(({ peopleStore }, { users }) => {
|
||||
removeUser: usersStore.removeUser,
|
||||
needResetUserSelection,
|
||||
filter: filterStore.filter,
|
||||
refreshInsideGroup,
|
||||
getUsersList,
|
||||
deleteWithoutReassign,
|
||||
onlyOneUser,
|
||||
|
@ -204,7 +204,7 @@ const StyledRow = styled.div`
|
||||
}
|
||||
|
||||
.combo-button-label {
|
||||
color: ${(props) => props.theme.text.disableColor};
|
||||
color: ${(props) => props.theme.accessRightSelect.descriptionColor};
|
||||
}
|
||||
.combo-buttons_expander-icon path {
|
||||
fill: ${(props) => props.theme.text.disableColor};
|
||||
|
@ -41,9 +41,12 @@ const Auth = (props) => {
|
||||
const { linkData } = props;
|
||||
let [searchParams, setSearchParams] = useSearchParams();
|
||||
const { t } = useTranslation(["Common"]);
|
||||
let referenceUrl = searchParams.get("referenceUrl");
|
||||
const isFileHandler = referenceUrl.indexOf("filehandler.ashx") !== -1;
|
||||
const isExternalDownloading = referenceUrl.indexOf("action=download") !== -1;
|
||||
|
||||
const referenceUrl = searchParams.get("referenceUrl");
|
||||
const isFileHandler =
|
||||
referenceUrl && referenceUrl.indexOf("filehandler.ashx") !== -1;
|
||||
const isExternalDownloading =
|
||||
referenceUrl && referenceUrl.indexOf("action=download") !== -1;
|
||||
|
||||
useEffect(() => {
|
||||
loginWithConfirmKey({
|
||||
|
@ -69,9 +69,10 @@ export const HistoryItemList = ({
|
||||
getInfoPanelItemIcon,
|
||||
checkAndOpenLocationAction,
|
||||
}: HistoryItemListProps) => {
|
||||
const [isExpanded, setIsExpanded] = useState(
|
||||
1 + feed.related.length <= EXPANSION_THRESHOLD,
|
||||
);
|
||||
const totalItems = feed.related.length + 1;
|
||||
const isExpandable = totalItems > EXPANSION_THRESHOLD;
|
||||
const [isExpanded, setIsExpanded] = useState(!isExpandable);
|
||||
|
||||
const onExpand = () => setIsExpanded(true);
|
||||
|
||||
const items = [
|
||||
@ -151,7 +152,7 @@ export const HistoryItemList = ({
|
||||
</StyledHistoryBlockFile>
|
||||
)}
|
||||
|
||||
{!isExpanded && (
|
||||
{isExpandable && !isExpanded && (
|
||||
<StyledHistoryBlockExpandLink
|
||||
className="files-list-expand-link"
|
||||
onClick={onExpand}
|
||||
|
@ -96,6 +96,7 @@ const FilesMediaViewer = (props) => {
|
||||
fetchPublicRoom,
|
||||
isPublicRoom,
|
||||
openUrl,
|
||||
autoPlay,
|
||||
} = props;
|
||||
|
||||
const navigate = useNavigate();
|
||||
@ -285,6 +286,7 @@ const FilesMediaViewer = (props) => {
|
||||
files={files}
|
||||
getIcon={getIcon}
|
||||
visible={visible}
|
||||
autoPlay={autoPlay}
|
||||
playlist={playlist}
|
||||
prevMedia={prevMedia}
|
||||
nextMedia={nextMedia}
|
||||
@ -379,6 +381,7 @@ export default inject(
|
||||
nextMedia,
|
||||
prevMedia,
|
||||
changeUrl,
|
||||
autoPlay,
|
||||
} = mediaViewerDataStore;
|
||||
const { deleteItemAction } = filesActionsStore;
|
||||
const { getIcon, extsImagePreviewed, extsMediaPreviewed } =
|
||||
@ -423,6 +426,7 @@ export default inject(
|
||||
|
||||
return {
|
||||
files,
|
||||
autoPlay,
|
||||
playlist,
|
||||
currentPostionIndex,
|
||||
nextMedia,
|
||||
|
@ -42,6 +42,7 @@ const EmptyScreen = ({
|
||||
resetInsideGroupFilter,
|
||||
setIsLoading,
|
||||
theme,
|
||||
isEmptyGroup = false,
|
||||
}) => {
|
||||
const { t } = useTranslation(["People", "Common"]);
|
||||
const isPeopleAccounts = window.location.pathname.includes("accounts/people");
|
||||
@ -57,6 +58,17 @@ const EmptyScreen = ({
|
||||
const imageSrc = theme.isBase
|
||||
? EmptyScreenPersonSvgUrl
|
||||
: EmptyScreenPersonSvgDarkUrl;
|
||||
|
||||
if (isEmptyGroup) {
|
||||
return (
|
||||
<EmptyScreenContainer
|
||||
imageSrc={imageSrc}
|
||||
imageAlt="Empty Screen Filter image"
|
||||
headerText={title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<EmptyScreenContainer
|
||||
|
@ -85,6 +85,7 @@ const PeopleRowContainer = ({
|
||||
infoPanelVisible,
|
||||
withPaging,
|
||||
currentDeviceType,
|
||||
insideGroupIsFiltered,
|
||||
}) => {
|
||||
useViewEffect({
|
||||
view: accountsViewAs,
|
||||
@ -113,7 +114,7 @@ const PeopleRowContainer = ({
|
||||
))}
|
||||
</StyledRowContainer>
|
||||
) : (
|
||||
<EmptyScreen />
|
||||
<EmptyScreen isEmptyGroup={!insideGroupIsFiltered} />
|
||||
);
|
||||
};
|
||||
|
||||
@ -126,7 +127,7 @@ export default inject(({ peopleStore, filesStore, settingsStore }) => {
|
||||
} = peopleStore;
|
||||
const { theme, withPaging, currentDeviceType } = settingsStore;
|
||||
const { isVisible: infoPanelVisible } = infoPanelStore;
|
||||
const { currentGroup } = peopleStore.groupsStore;
|
||||
const { currentGroup, insideGroupIsFiltered } = peopleStore.groupsStore;
|
||||
const { peopleList } = usersStore;
|
||||
|
||||
return {
|
||||
@ -138,5 +139,6 @@ export default inject(({ peopleStore, filesStore, settingsStore }) => {
|
||||
infoPanelVisible,
|
||||
withPaging,
|
||||
currentDeviceType,
|
||||
insideGroupIsFiltered,
|
||||
};
|
||||
})(observer(PeopleRowContainer));
|
||||
|
@ -157,6 +157,7 @@ const Table = ({
|
||||
insideGroupIsLoading,
|
||||
fetchMoreInsideGroupUsers,
|
||||
insideGroupFilterTotal,
|
||||
insideGroupIsFiltered,
|
||||
hasMoreInsideGroupUsers,
|
||||
}) => {
|
||||
const ref = useRef(null);
|
||||
@ -177,7 +178,7 @@ const Table = ({
|
||||
const isEmptyPage = !insideGroupIsLoading && peopleList.length === 0;
|
||||
|
||||
return isEmptyPage ? (
|
||||
<EmptyScreen />
|
||||
<EmptyScreen isEmptyGroup={!insideGroupIsFiltered} />
|
||||
) : (
|
||||
<StyledTableContainer useReactWindow={!withPaging} forwardedRef={ref}>
|
||||
<TableHeader
|
||||
@ -261,6 +262,7 @@ export default inject(
|
||||
const {
|
||||
insideGroupIsLoading,
|
||||
insideGroupFilterTotal,
|
||||
insideGroupIsFiltered,
|
||||
hasMoreInsideGroupUsers,
|
||||
fetchMoreInsideGroupUsers,
|
||||
} = peopleStore.groupsStore;
|
||||
@ -286,6 +288,7 @@ export default inject(
|
||||
insideGroupIsLoading,
|
||||
fetchMoreInsideGroupUsers,
|
||||
insideGroupFilterTotal,
|
||||
insideGroupIsFiltered,
|
||||
hasMoreInsideGroupUsers,
|
||||
};
|
||||
},
|
||||
|
@ -160,6 +160,7 @@ const PureHome = (props) => {
|
||||
getFolderModel,
|
||||
scrollToTop,
|
||||
isEmptyGroups,
|
||||
isCurrentGroupEmpty,
|
||||
wsCreatedPDFForm,
|
||||
disableUploadPanelOpen,
|
||||
} = props;
|
||||
@ -176,7 +177,11 @@ const PureHome = (props) => {
|
||||
const isPeopleAccounts = location.pathname.includes("accounts/people");
|
||||
const isGroupsAccounts =
|
||||
location.pathname.includes("accounts/groups") && !groupId;
|
||||
const isAccountsEmptyFilter = isGroupsAccounts && isEmptyGroups;
|
||||
const isInsideGroup =
|
||||
location.pathname.includes("accounts/groups") && groupId;
|
||||
const isAccountsEmptyFilter =
|
||||
(isGroupsAccounts && isEmptyGroups) ||
|
||||
(isInsideGroup && isCurrentGroupEmpty);
|
||||
|
||||
const { onDrop } = useFiles({
|
||||
t,
|
||||
@ -574,6 +579,7 @@ export default inject(
|
||||
fetchGroup,
|
||||
groups,
|
||||
groupsIsFiltered,
|
||||
isCurrentGroupEmpty,
|
||||
} = groupsStore;
|
||||
const isEmptyGroups =
|
||||
!groupsIsFiltered &&
|
||||
@ -692,6 +698,7 @@ export default inject(
|
||||
getFolderModel,
|
||||
scrollToTop,
|
||||
isEmptyGroups,
|
||||
isCurrentGroupEmpty,
|
||||
wsCreatedPDFForm,
|
||||
};
|
||||
},
|
||||
|
@ -26,7 +26,8 @@
|
||||
|
||||
import React, { useRef } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { Box } from "@docspace/shared/components/box";
|
||||
import { TextInput } from "@docspace/shared/components/text-input";
|
||||
@ -39,6 +40,8 @@ import { FieldContainer } from "@docspace/shared/components/field-container";
|
||||
import AccessSelector from "SRC_DIR/components/AccessSelector";
|
||||
import { isMobile } from "@docspace/shared/utils";
|
||||
import LdapFieldComponent from "./LdapFieldComponent";
|
||||
import { Link } from "@docspace/shared/components/link";
|
||||
import { globalColors } from "@docspace/shared/themes";
|
||||
|
||||
const FIRST_NAME = "firstName",
|
||||
SECOND_NAME = "secondName",
|
||||
@ -68,10 +71,14 @@ const AttributeMapping = (props) => {
|
||||
|
||||
isLdapEnabled,
|
||||
isUIDisabled,
|
||||
|
||||
isDefaultUsersQuotaSet,
|
||||
} = props;
|
||||
|
||||
const { t } = useTranslation("Ldap");
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const inputsRef = useRef();
|
||||
|
||||
const onChangeValue = (e) => {
|
||||
@ -100,6 +107,10 @@ const AttributeMapping = (props) => {
|
||||
setUserType(option.access);
|
||||
};
|
||||
|
||||
const goToStarageManagement = () => {
|
||||
navigate("/portal-settings/management/disk-space");
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="ldap_attribute-mapping-text">
|
||||
@ -202,9 +213,32 @@ const AttributeMapping = (props) => {
|
||||
onChange={onChangeValue}
|
||||
value={userQuotaLimit}
|
||||
scale
|
||||
isDisabled={!isLdapEnabled || isUIDisabled}
|
||||
isDisabled={
|
||||
!isDefaultUsersQuotaSet || !isLdapEnabled || isUIDisabled
|
||||
}
|
||||
tabIndex={11}
|
||||
/>
|
||||
{!isDefaultUsersQuotaSet && (
|
||||
<Text
|
||||
as={"span"}
|
||||
fontWeight={400}
|
||||
fontSize="12px"
|
||||
lineHeight="16px"
|
||||
>
|
||||
<Trans
|
||||
t={t}
|
||||
i18nKey="LdapQuotaInfo"
|
||||
ns="Ldap"
|
||||
components={[
|
||||
<Link
|
||||
type="action"
|
||||
color={globalColors.link}
|
||||
onClick={goToStarageManagement}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
</Text>
|
||||
)}
|
||||
</FieldContainer>
|
||||
</Box>
|
||||
<Box marginProp="24px 0 24px 0">
|
||||
@ -250,7 +284,7 @@ const AttributeMapping = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ ldapStore }) => {
|
||||
export default inject(({ ldapStore, currentQuotaStore }) => {
|
||||
const {
|
||||
setMail,
|
||||
setFirstName,
|
||||
@ -274,6 +308,8 @@ export default inject(({ ldapStore }) => {
|
||||
userType,
|
||||
} = requiredSettings;
|
||||
|
||||
const { isDefaultUsersQuotaSet } = currentQuotaStore;
|
||||
|
||||
return {
|
||||
setFirstName,
|
||||
setSecondName,
|
||||
@ -292,5 +328,7 @@ export default inject(({ ldapStore }) => {
|
||||
errors,
|
||||
isLdapEnabled,
|
||||
isUIDisabled,
|
||||
|
||||
isDefaultUsersQuotaSet,
|
||||
};
|
||||
})(observer(AttributeMapping));
|
||||
|
@ -32,6 +32,7 @@ import { HelpButton } from "@docspace/shared/components/help-button";
|
||||
import { FieldContainer } from "@docspace/shared/components/field-container";
|
||||
import { ToggleButton } from "@docspace/shared/components/toggle-button";
|
||||
import LdapFieldComponent from "./LdapFieldComponent";
|
||||
import { InputSize, InputType } from "@docspace/shared/components/text-input";
|
||||
|
||||
const LOGIN = "login",
|
||||
PASSWORD = "password";
|
||||
@ -109,6 +110,7 @@ const AuthenticationContainer = ({
|
||||
isRequired
|
||||
>
|
||||
<LdapFieldComponent
|
||||
isPassword
|
||||
name={PASSWORD}
|
||||
type="password"
|
||||
hasError={errors.password}
|
||||
@ -117,6 +119,11 @@ const AuthenticationContainer = ({
|
||||
isDisabled={!isLdapEnabled || isUIDisabled || !authentication}
|
||||
scale
|
||||
tabIndex={19}
|
||||
simpleView
|
||||
size={InputSize.small}
|
||||
autoComplete="current-password"
|
||||
inputType={InputType.password}
|
||||
isDisableTooltip
|
||||
/>
|
||||
</FieldContainer>
|
||||
</Box>
|
||||
|
@ -28,6 +28,7 @@ import React from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { TextInput } from "@docspace/shared/components/text-input";
|
||||
import { Textarea } from "@docspace/shared/components/textarea";
|
||||
import { PasswordInput } from "@docspace/shared/components/password-input";
|
||||
|
||||
const LdapFieldComponent = (props) => {
|
||||
const {
|
||||
@ -37,6 +38,7 @@ const LdapFieldComponent = (props) => {
|
||||
setErrorField,
|
||||
name,
|
||||
onChange,
|
||||
isPassword,
|
||||
...prop
|
||||
} = props;
|
||||
|
||||
@ -68,6 +70,17 @@ const LdapFieldComponent = (props) => {
|
||||
if (isTextArea)
|
||||
return <Textarea name={name} onChange={onChangeFn} {...prop} />;
|
||||
|
||||
if (isPassword)
|
||||
return (
|
||||
<PasswordInput
|
||||
name={name}
|
||||
onBlur={onBlur}
|
||||
onFocus={onFocus}
|
||||
onChange={onChangeFn}
|
||||
{...prop}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<TextInput
|
||||
name={name}
|
||||
|
@ -41,13 +41,11 @@ const SubmitResetButtons = (props) => {
|
||||
resetForm,
|
||||
confirmationResetModal,
|
||||
isSubmitLoading,
|
||||
hasErrors,
|
||||
hasChanges,
|
||||
isLoadingXml,
|
||||
enableSso,
|
||||
isSSOAvailable,
|
||||
closeResetModal,
|
||||
confirmReset,
|
||||
isDisabledSaveButton,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
@ -62,9 +60,7 @@ const SubmitResetButtons = (props) => {
|
||||
displaySettings={true}
|
||||
hasScroll={true}
|
||||
isSaving={isSubmitLoading}
|
||||
saveButtonDisabled={
|
||||
!enableSso || hasErrors || !hasChanges || isLoadingXml
|
||||
}
|
||||
saveButtonDisabled={isDisabledSaveButton}
|
||||
disableRestoreToDefault={
|
||||
isSubmitLoading || isLoadingXml || !isSSOAvailable
|
||||
}
|
||||
@ -90,12 +86,10 @@ export default inject(({ ssoStore, currentQuotaStore }) => {
|
||||
resetForm,
|
||||
confirmationResetModal,
|
||||
isSubmitLoading,
|
||||
hasErrors,
|
||||
hasChanges,
|
||||
isLoadingXml,
|
||||
enableSso,
|
||||
closeResetModal,
|
||||
confirmReset,
|
||||
isDisabledSaveButton,
|
||||
} = ssoStore;
|
||||
const { isSSOAvailable } = currentQuotaStore;
|
||||
|
||||
@ -106,12 +100,10 @@ export default inject(({ ssoStore, currentQuotaStore }) => {
|
||||
resetForm,
|
||||
confirmationResetModal,
|
||||
isSubmitLoading,
|
||||
hasErrors,
|
||||
hasChanges,
|
||||
isLoadingXml,
|
||||
enableSso,
|
||||
isSSOAvailable,
|
||||
closeResetModal,
|
||||
confirmReset,
|
||||
isDisabledSaveButton,
|
||||
};
|
||||
})(observer(SubmitResetButtons));
|
||||
|
@ -51,16 +51,6 @@ const StyledSsoPage = styled.div`
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: auto;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
overflow: visible;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.xml-input {
|
||||
.field-label-icon {
|
||||
margin-bottom: 8px;
|
||||
|
@ -2476,7 +2476,15 @@ class FilesActionStore {
|
||||
? getObjectByLocation(shareWebUrl)?.share
|
||||
: "";
|
||||
|
||||
return openDocEditor(id, false, shareKey);
|
||||
const isPDF = item.fileExst === ".pdf";
|
||||
|
||||
const canEditForm =
|
||||
isPDF &&
|
||||
item.isPDFForm &&
|
||||
item.security?.EditForm &&
|
||||
!item.startFilling;
|
||||
|
||||
return openDocEditor(id, false, shareKey, canEditForm);
|
||||
}
|
||||
|
||||
if (isMediaOrImage) {
|
||||
|
@ -152,6 +152,24 @@ class GroupsStore {
|
||||
return false;
|
||||
}
|
||||
|
||||
get insideGroupIsFiltered() {
|
||||
return (
|
||||
this.insideGroupFilter.activationStatus ||
|
||||
this.insideGroupFilter.employeeStatus ||
|
||||
this.insideGroupFilter.payments ||
|
||||
this.insideGroupFilter.search ||
|
||||
this.insideGroupFilter.role ||
|
||||
this.insideGroupFilter.accountLoginType
|
||||
);
|
||||
}
|
||||
|
||||
get isCurrentGroupEmpty() {
|
||||
return (
|
||||
!this.insideGroupIsFiltered &&
|
||||
this.peopleStore.usersStore.peopleList.length === 0
|
||||
);
|
||||
}
|
||||
|
||||
// Inside Group Filter
|
||||
|
||||
setInsideGroupFilter = (filter) => {
|
||||
@ -282,6 +300,7 @@ class GroupsStore {
|
||||
filter,
|
||||
updateFilter = false,
|
||||
withFilterLocalStorage = false,
|
||||
updateCurrentGroup = false,
|
||||
) => {
|
||||
this.setInsideGroupLoading(true);
|
||||
|
||||
@ -309,7 +328,7 @@ class GroupsStore {
|
||||
|
||||
requests.push(api.people.getUserList(filterData));
|
||||
|
||||
if (groupId !== this.currentGroup?.id) {
|
||||
if (updateCurrentGroup || groupId !== this.currentGroup?.id) {
|
||||
requests.push(groupsApi.getGroupById(groupId));
|
||||
}
|
||||
|
||||
@ -329,6 +348,18 @@ class GroupsStore {
|
||||
return Promise.resolve(filteredMembersRes.items);
|
||||
};
|
||||
|
||||
refreshInsideGroup = async () => {
|
||||
if (!this.currentGroup) return;
|
||||
|
||||
await this.fetchGroup(
|
||||
this.currentGroup.id,
|
||||
this.insideGroupFilter,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
get hasMoreInsideGroupUsers() {
|
||||
return (
|
||||
this.peopleStore.usersStore.users.length < this.insideGroupFilter.total
|
||||
@ -662,10 +693,12 @@ class GroupsStore {
|
||||
}
|
||||
|
||||
if (getIsInsideGroup() && this.currentGroup?.id === groupId) {
|
||||
const filter = this.insideGroupFilter.clone();
|
||||
|
||||
this.setCurrentGroup(res);
|
||||
const members = await api.people.getUserList(
|
||||
this.insideGroupFilter.clone(),
|
||||
);
|
||||
const members = await api.people.getUserList(filter);
|
||||
filter.total = members.total;
|
||||
this.setInsideGroupFilter(filter);
|
||||
this.peopleStore.usersStore.setUsers(members.items);
|
||||
this.setInsideGroupTempTitle(res.name);
|
||||
}
|
||||
|
@ -47,6 +47,8 @@ class MediaViewerDataStore {
|
||||
|
||||
publicRoomStore;
|
||||
|
||||
autoPlay = true;
|
||||
|
||||
id = null;
|
||||
visible = false;
|
||||
previewFile = null;
|
||||
@ -60,9 +62,14 @@ class MediaViewerDataStore {
|
||||
this.publicRoomStore = publicRoomStore;
|
||||
}
|
||||
|
||||
setAutoPlay = (value) => {
|
||||
this.autoPlay = value;
|
||||
};
|
||||
|
||||
setMediaViewerData = (mediaData) => {
|
||||
this.id = mediaData.id;
|
||||
this.visible = mediaData.visible;
|
||||
this.setAutoPlay(true);
|
||||
|
||||
if (!mediaData.visible) this.setCurrentItem(null);
|
||||
};
|
||||
@ -109,6 +116,7 @@ class MediaViewerDataStore {
|
||||
)
|
||||
return;
|
||||
|
||||
this.setAutoPlay(false);
|
||||
this.previewFile = file;
|
||||
this.id = file.id;
|
||||
this.visible = visible;
|
||||
@ -167,6 +175,9 @@ class MediaViewerDataStore {
|
||||
if (postionIndex === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setAutoPlay(false);
|
||||
|
||||
const currentFileId = this.playlist[postionIndex].fileId;
|
||||
|
||||
const targetFile = files.find((item) => item.id === currentFileId);
|
||||
@ -187,6 +198,8 @@ class MediaViewerDataStore {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setAutoPlay(false);
|
||||
|
||||
const currentFileId = this.playlist[currentPlaylistPos].fileId;
|
||||
|
||||
const targetFile = files.find((item) => item.id === currentFileId);
|
||||
|
@ -946,6 +946,33 @@ class SsoFormStore {
|
||||
);
|
||||
}
|
||||
|
||||
get isDisabledSaveButton() {
|
||||
return (
|
||||
!this.enableSso ||
|
||||
this.hasErrors ||
|
||||
!this.hasChanges ||
|
||||
this.isLoadingXml ||
|
||||
this.isRequiredFieldsEmpty
|
||||
);
|
||||
}
|
||||
|
||||
get isRequiredFieldsEmpty() {
|
||||
return (
|
||||
this.entityId.trim().length === 0 ||
|
||||
(this.ssoBinding === BINDING_POST &&
|
||||
this.ssoUrlPost.trim().length === 0) ||
|
||||
(this.sloBinding === BINDING_POST &&
|
||||
this.sloUrlPost.trim().length === 0) ||
|
||||
(this.ssoBinding === BINDING_REDIRECT &&
|
||||
this.ssoUrlRedirect.trim().length === 0) ||
|
||||
(this.sloBinding === BINDING_REDIRECT &&
|
||||
this.sloUrlRedirect.trim().length === 0) ||
|
||||
this.firstName.trim().length === 0 ||
|
||||
this.lastName.trim().length === 0 ||
|
||||
this.email.trim().length === 0
|
||||
);
|
||||
}
|
||||
|
||||
scrollToField = () => {
|
||||
for (let key in this) {
|
||||
if (key.includes("HasError") && this[key] !== false) {
|
||||
|
@ -149,9 +149,14 @@ class UsersStore {
|
||||
return Promise.resolve(result);
|
||||
};
|
||||
|
||||
removeUser = async (userId, filter) => {
|
||||
removeUser = async (userId, filter, isInsideGroup) => {
|
||||
const { refreshInsideGroup } = this.peopleStore.groupsStore;
|
||||
|
||||
await api.people.deleteUsers(userId);
|
||||
await this.getUsersList(filter, true);
|
||||
|
||||
isInsideGroup
|
||||
? await refreshInsideGroup()
|
||||
: await this.getUsersList(filter, true);
|
||||
};
|
||||
|
||||
get needResetUserSelection() {
|
||||
|
@ -64,6 +64,7 @@ const MediaViewer = (props: MediaViewerProps): JSX.Element | undefined => {
|
||||
pluginContextMenuItems,
|
||||
currentDeviceType,
|
||||
isPublicFile = false,
|
||||
autoPlay = false,
|
||||
|
||||
t,
|
||||
getIcon,
|
||||
@ -453,6 +454,7 @@ const MediaViewer = (props: MediaViewerProps): JSX.Element | undefined => {
|
||||
playlistPos={playlistPos}
|
||||
isPublicFile={isPublicFile}
|
||||
isPreviewFile={isPreviewFile}
|
||||
autoPlay={autoPlay}
|
||||
currentDeviceType={currentDeviceType}
|
||||
onClose={onClose}
|
||||
onPrevClick={prevMedia}
|
||||
|
@ -91,6 +91,9 @@ export interface MediaViewerProps {
|
||||
playlistPos: number;
|
||||
/** Indicates if the current file is a preview. */
|
||||
isPreviewFile?: boolean;
|
||||
|
||||
autoPlay?: boolean;
|
||||
|
||||
isPublicFile?: boolean;
|
||||
/** List of playlists. */
|
||||
playlist: PlaylistType[];
|
||||
|
@ -38,7 +38,7 @@ interface ViewerProps {
|
||||
visible: boolean;
|
||||
isImage: boolean;
|
||||
isPdf: boolean;
|
||||
|
||||
autoPlay: boolean;
|
||||
playlist: PlaylistType[];
|
||||
|
||||
audioIcon: string;
|
||||
|
@ -59,6 +59,7 @@ export const Viewer = (props: ViewerProps) => {
|
||||
fileUrl,
|
||||
toolbar,
|
||||
playlist,
|
||||
autoPlay,
|
||||
audioIcon,
|
||||
errorTitle,
|
||||
targetFile,
|
||||
@ -277,6 +278,7 @@ export const Viewer = (props: ViewerProps) => {
|
||||
<ViewerPlayer
|
||||
isError={isError}
|
||||
src={fileUrl}
|
||||
autoPlay={autoPlay}
|
||||
devices={devices}
|
||||
isAudio={isAudio}
|
||||
isVideo={isVideo}
|
||||
|
@ -39,6 +39,7 @@ interface ViewerPlayerProps {
|
||||
isFullScreen: boolean;
|
||||
panelVisible: boolean;
|
||||
isPreviewFile?: boolean;
|
||||
autoPlay: boolean;
|
||||
isOpenContextMenu: boolean;
|
||||
isThirdParty?: boolean;
|
||||
mobileDetails: JSX.Element;
|
||||
|
@ -81,6 +81,7 @@ export const ViewerPlayer = ({
|
||||
isVideo,
|
||||
isError,
|
||||
devices,
|
||||
autoPlay,
|
||||
audioIcon,
|
||||
errorTitle,
|
||||
isLastImage,
|
||||
@ -643,6 +644,7 @@ export const ViewerPlayer = ({
|
||||
playsInline
|
||||
ref={videoRef}
|
||||
hidden={isAudio}
|
||||
autoPlay={autoPlay}
|
||||
preload="metadata"
|
||||
style={omit(style, ["x", "y"])}
|
||||
src={thumbnailSrc ? src : `${src}#t=0.001`}
|
||||
|
@ -35,6 +35,7 @@ interface ViewerWrapperProps {
|
||||
targetFile?: TFile;
|
||||
playlistPos: number;
|
||||
userAccess?: boolean;
|
||||
autoPlay: boolean;
|
||||
playlist: PlaylistType[];
|
||||
currentDeviceType?: DeviceType;
|
||||
|
||||
|
@ -57,6 +57,7 @@ const ViewerWrapper = memo(
|
||||
isPreviewFile,
|
||||
currentDeviceType,
|
||||
isPublicFile,
|
||||
autoPlay,
|
||||
|
||||
onClose,
|
||||
onNextClick,
|
||||
@ -167,6 +168,7 @@ const ViewerWrapper = memo(
|
||||
visible={visible}
|
||||
isImage={isImage}
|
||||
toolbar={toolbar}
|
||||
autoPlay={autoPlay}
|
||||
playlist={playlist}
|
||||
audioIcon={audioIcon}
|
||||
errorTitle={errorTitle}
|
||||
|
Loading…
Reference in New Issue
Block a user