Removed packages/common

This commit is contained in:
Alexey Safronov 2024-02-22 20:19:23 +04:00
parent 0e7055ae30
commit fa6c400f69
53 changed files with 44 additions and 2997 deletions

View File

@ -2,32 +2,28 @@
"folders": [
{
"name": "🌐 root",
"path": "."
"path": ".",
},
{
"name": "🚀 @docspace/client",
"path": "packages/client"
"path": "packages/client",
},
{
"name": "🔑 @docspace/login",
"path": "packages/login"
"path": "packages/login",
},
{
"name": "📄 @docspace/editor",
"path": "packages/editor"
"path": "packages/editor",
},
{
"name": "🗂 @docspace/management",
"path": "packages/management"
},
{
"name": "📦 @docspace/common",
"path": "packages/common"
"path": "packages/management",
},
{
"name": "📦 @docspace/shared",
"path": "packages/shared"
}
"path": "packages/shared",
},
],
"settings": {
"window.zoomLevel": 0,
@ -42,10 +38,10 @@
"🚀 @docspace/client",
"📄 @docspace/editor",
"📦 @docspace/common",
"🗂 @docspace/management"
"🗂 @docspace/management",
],
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"VsCodeTaskButtons.tasks": [
{
@ -54,55 +50,55 @@
{
"label": "Docker : Build-EE",
"task": "Backend | build EE",
"tooltip": "🛠️ Start the \"backend docker build EE\" task"
"tooltip": "🛠️ Start the \"backend docker build EE\" task",
},
{
"label": "Docker : ReBuild-EE",
"task": "Backend | rebuild EE",
"tooltip": "🛠️ Start the \"backend docker rebuild EE\" task"
"tooltip": "🛠️ Start the \"backend docker rebuild EE\" task",
},
{
"label": "Docker : Build-CE",
"task": "Backend | build CE",
"tooltip": "🛠️ Start the \"backend docker build CE\" task"
"tooltip": "🛠️ Start the \"backend docker build CE\" task",
},
{
"label": "Docker : Build-SAAS + dnsmasq",
"task": "Backend | build SAAS + dnsmasq",
"tooltip": "🛠️ Start the \"backend docker build SAAS + dnsmasq\" task"
"tooltip": "🛠️ Start the \"backend docker build SAAS + dnsmasq\" task",
},
{
"label": "Docker : ReBuild-SAAS + dnsmasq",
"task": "Backend | rebuild SAAS + dnsmasq",
"tooltip": "🛠️ Start the \"backend docker rebuild SAAS + dnsmasq\" task"
"tooltip": "🛠️ Start the \"backend docker rebuild SAAS + dnsmasq\" task",
},
{
"label": "Docker : Build-EE + dnsmasq",
"task": "Backend | build EE + dnsmasq",
"tooltip": "🛠️ Start the \"backend docker build EE + dnsmasq\" task"
"tooltip": "🛠️ Start the \"backend docker build EE + dnsmasq\" task",
},
{
"label": "Docker : Clear",
"task": "Backend | clear",
"tooltip": "🛠️ Start the \"backend docker clear\" task"
"tooltip": "🛠️ Start the \"backend docker clear\" task",
},
{
"label": "Docker : Stop",
"task": "Backend | stop",
"tooltip": "🛠️ Start the \"backend docker stop\" task"
"tooltip": "🛠️ Start the \"backend docker stop\" task",
},
{
"label": "Docker : Start",
"task": "Backend | start",
"tooltip": "🛠️ Start the \"backend docker start\" task"
"tooltip": "🛠️ Start the \"backend docker start\" task",
},
{
"label": "Docker : Restart",
"task": "Backend | restart",
"tooltip": "🛠️ Start the \"backend docker restart\" task"
}
"tooltip": "🛠️ Start the \"backend docker restart\" task",
},
],
"tooltip": "🛠️ Server tasks"
"tooltip": "🛠️ Server tasks",
},
{
"label": "Client",
@ -110,55 +106,55 @@
{
"label": "Install",
"task": "Frontend | install",
"tooltip": "🛠️ Start the \"frontend install packages\" task"
"tooltip": "🛠️ Start the \"frontend install packages\" task",
},
{
"label": "Update yarn.lock",
"task": "Frontend | update yarn.lock",
"tooltip": "🛠️ Start the \"frontend update yarn.lock\" task"
"tooltip": "🛠️ Start the \"frontend update yarn.lock\" task",
},
{
"label": "Build",
"task": "Frontend | build",
"tooltip": "🛠️ Start the \"frontend build\" task"
"tooltip": "🛠️ Start the \"frontend build\" task",
},
{
"label": "Build and start prod",
"task": "Frontend | build-and-start-prod",
"tooltip": "🛠️ Start the \"frontend build and start production\" task"
"tooltip": "🛠️ Start the \"frontend build and start production\" task",
},
{
"label": "Start",
"task": "Frontend | start",
"tooltip": "🛠️ Start the \"frontend start\" task"
"tooltip": "🛠️ Start the \"frontend start\" task",
},
{
"label": "Start prod",
"task": "Frontend | start-prod",
"tooltip": "🛠️ Start the \"frontend start production\" task"
"tooltip": "🛠️ Start the \"frontend start production\" task",
},
{
"label": "Start storybook",
"task": "Frontend | storybook",
"tooltip": "🛠️ Start the \"frontend start storybook\" task"
"tooltip": "🛠️ Start the \"frontend start storybook\" task",
},
{
"label": "Start storybook prod",
"task": "Frontend | storybook prod",
"tooltip": "🛠️ Start the \"frontend start storybook\" task"
"tooltip": "🛠️ Start the \"frontend start storybook\" task",
},
{
"label": "Lint",
"task": "Frontend | Eslint",
"tooltip": "🛠️ Start the \"frontend start storybook\" task"
"tooltip": "🛠️ Start the \"frontend start storybook\" task",
},
{
"label": "Lint:fix",
"task": "Frontend | Eslint:fix",
"tooltip": "🛠️ Start the \"frontend start storybook\" task"
}
"tooltip": "🛠️ Start the \"frontend start storybook\" task",
},
],
"tooltip": "🛠️ Client tasks"
"tooltip": "🛠️ Client tasks",
},
{
"label": "Tests",
@ -166,27 +162,27 @@
{
"label": "translations",
"task": "Test | frontend-translations",
"tooltip": "🛠️ Start the \"frontend translation tests\" task"
"tooltip": "🛠️ Start the \"frontend translation tests\" task",
},
{
"label": "spellcheck",
"task": "Test | frontend-translations-spellcheck",
"tooltip": "🛠️ Start the \"frontend translation spellcheck tests\" task"
"tooltip": "🛠️ Start the \"frontend translation spellcheck tests\" task",
},
{
"label": "spellcheck-force-save",
"task": "Test | frontend-translations-spellcheck-force-save",
"tooltip": "🛠️ Start the \"frontend translation spellcheck tests\" task"
"tooltip": "🛠️ Start the \"frontend translation spellcheck tests\" task",
},
{
"label": "unit",
"task": "Test | Jest:unit",
"tooltip": "🛠️ Start the \"Test | Jest:unit\" task"
}
"tooltip": "🛠️ Start the \"Test | Jest:unit\" task",
},
],
"tooltip": "🛠️ Client tests tasks",
},
],
"tooltip": "🛠️ Client tests tasks"
}
]
},
"extensions": {
"recommendations": [
@ -199,7 +195,7 @@
"formulahendry.auto-complete-tag",
"formulahendry.auto-rename-tag",
"mrmlnc.vscode-duplicate",
"ms-python.python"
]
}
"ms-python.python",
],
},
}

View File

@ -1,7 +0,0 @@
module.exports = [
'>0.25%',
'not ie 11',
'not op_mini all',
'not dead',
'Firefox ESR',
];

View File

@ -1,208 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import styled, { css } from "styled-components";
import { isMobile } from "react-device-detect";
import { tablet, mobile } from "@docspace/shared/utils";
import { Base } from "@docspace/shared/themes";
import Selector from "./sub-components/Selector";
import { Backdrop } from "@docspace/shared/components/backdrop";
import CrossIcon from "PUBLIC_DIR/images/cross.react.svg";
const StyledBlock = styled.div`
position: fixed;
top: 0;
${({ theme }) =>
theme.interfaceDirection === "rtl" ? `left: 0;` : `right: 0;`}
width: 480px;
max-width: 100%;
height: 100%;
z-index: 400;
display: flex;
flex-direction: column;
background: ${(props) => props.theme.filterInput.filter.background};
@media ${tablet} {
max-width: calc(100% - 69px);
}
${isMobile &&
css`
max-width: calc(100% - 69px);
`}
@media ${mobile} {
bottom: 0;
top: unset;
height: calc(100% - 64px);
width: 100%;
max-width: 100%;
}
.people-selector {
height: 100%;
width: 100%;
.selector-wrapper,
.column-options {
width: 100%;
}
}
`;
StyledBlock.defaultProps = { theme: Base };
const StyledControlContainer = styled.div`
display: flex;
width: 17px;
height: 17px;
position: absolute;
border-radius: 100px;
cursor: pointer;
align-items: center;
justify-content: center;
z-index: 450;
top: 18px;
${({ theme }) =>
theme.interfaceDirection === "rtl" ? `right: -27px;` : `left: -27px;`}
${isMobile &&
css`
top: 18px;
`}
@media ${mobile} {
top: -27px;
${({ theme }) =>
theme.interfaceDirection === "rtl"
? css`
left: 10px;
right: unset;
`
: css`
right: 10px;
left: unset;
`}
}
`;
StyledControlContainer.defaultProps = { theme: Base };
const StyledCrossIcon = styled(CrossIcon)`
width: 17px;
height: 17px;
z-index: 455;
path {
fill: ${(props) => props.theme.catalog.control.fill};
}
`;
StyledCrossIcon.defaultProps = { theme: Base };
class AdvancedSelector extends React.Component {
constructor(props) {
super(props);
this.ref = React.createRef();
}
onClose = (e) => {
//console.log("onClose");
//this.setState({ isOpen: false });
this.props.onCancel && this.props.onCancel(e);
};
render() {
const { isOpen, id, className, style, withoutAside } = this.props;
return (
<>
{isOpen && (
<div id={id} className={className} style={style}>
{withoutAside ? (
<Selector {...this.props} />
) : (
<>
<Backdrop
onClick={this.onClose}
visible={isOpen}
zIndex={310}
isAside={true}
/>
<StyledBlock>
<Selector {...this.props} />
<StyledControlContainer onClick={this.onClose}>
<StyledCrossIcon />
</StyledControlContainer>
</StyledBlock>
</>
)}
</div>
)}
</>
);
}
}
AdvancedSelector.propTypes = {
id: PropTypes.string,
className: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
style: PropTypes.object,
options: PropTypes.array,
selectedOptions: PropTypes.array,
groups: PropTypes.array,
selectedGroups: PropTypes.array,
value: PropTypes.string,
placeholder: PropTypes.string,
selectAllLabel: PropTypes.string,
buttonLabel: PropTypes.string,
maxHeight: PropTypes.number,
isMultiSelect: PropTypes.bool,
isDisabled: PropTypes.bool,
selectedAll: PropTypes.bool,
isOpen: PropTypes.bool,
allowGroupSelection: PropTypes.bool,
allowCreation: PropTypes.bool,
allowAnyClickClose: PropTypes.bool,
hasNextPage: PropTypes.bool,
isNextPageLoading: PropTypes.bool,
withoutAside: PropTypes.bool,
onSearchChanged: PropTypes.func,
onSelect: PropTypes.func,
onGroupChange: PropTypes.func,
onCancel: PropTypes.func,
onAddNewClick: PropTypes.func,
loadNextPage: PropTypes.func,
isDefaultDisplayDropDown: PropTypes.bool,
};
AdvancedSelector.defaultProps = {
isMultiSelect: false,
size: "full",
buttonLabel: "Add members",
selectAllLabel: "Select all",
allowGroupSelection: false,
allowAnyClickClose: true,
options: [],
isDefaultDisplayDropDown: true,
};
export default AdvancedSelector;

View File

@ -1,258 +0,0 @@
/* eslint-disable react/prop-types */
import React from "react";
import { storiesOf } from "@storybook/react";
import { action } from "@storybook/addon-actions";
import {
withKnobs,
text,
number,
boolean,
select,
} from "@storybook/addon-knobs/react";
import withReadme from "storybook-readme/with-readme";
import Readme from "./README.md";
import AdvancedSelector2 from ".";
import Section from "../../../.storybook/decorators/section";
import { Button } from "@docspace/shared/components/button";
import equal from "fast-deep-equal/react";
import UserTooltip from "@docspace/client/src/components/PeopleSelector/UserTooltip";
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
const sizes = ["compact", "full"];
const displayTypes = ["dropdown", "aside", "auto"];
class ADSelectorExample extends React.Component {
constructor(props) {
super(props);
const { isOpen, total } = props;
const groups = this.generateGroups();
const users = this.generateUsers(total, groups);
this.state = this.getDefaultState(isOpen, groups, users);
}
getDefaultState = (isOpen, groups, allOptions) => {
return {
isOpen: isOpen,
allOptions,
options: [],
groups,
hasNextPage: true,
isNextPageLoading: false,
};
};
generateGroups = () => {
return [
{
key: "group-administration",
label: "Administration",
total: 0,
},
{
key: "group-dev",
label: "Development",
total: 0,
},
{
key: "group-management",
label: "Management",
total: 0,
},
{
key: "group-marketing",
label: "Marketing",
total: 0,
},
{
key: "group-mobile",
label: "Mobile",
total: 0,
},
{
key: "group-support",
label: "Support",
total: 0,
},
{
key: "group-web",
label: "Web",
total: 0,
},
];
};
generateUsers = (count, groups) => {
return Array.from({ length: count }, (v, index) => {
const additional_group = groups[getRandomInt(0, 6)];
//groups[0].total++;
additional_group.total++;
return {
key: `user${index}`,
groups: [additional_group.key],
label: `Demo User ${index}`,
avatarUrl: ``,
position: `Demo`,
email: `demo@demo.demo`,
};
});
};
loadNextPage = ({ startIndex, searchValue, currentGroup }) => {
console.log(
`loadNextPage(startIndex=${startIndex}, searchValue="${searchValue}", currentGroup="${currentGroup}")`
);
this.setState({ isNextPageLoading: true }, () => {
setTimeout(() => {
const { options } = this.state;
let filtered = [...this.state.allOptions];
if (currentGroup) {
filtered = filtered.filter(
(o) => o.groups.indexOf(currentGroup) > -1
);
}
if (searchValue) {
filtered = filtered.filter((o) => o.label.indexOf(searchValue) > -1);
}
const newOptions = [...options].concat(
filtered.slice(startIndex, startIndex + 100)
);
this.setState({
hasNextPage: newOptions.length < filtered.length,
isNextPageLoading: false,
options: newOptions,
});
}, 1000);
});
};
componentDidUpdate(prevProps) {
const { total, options, isOpen } = this.props;
if (!equal(prevProps.options, options)) {
this.setState({
options: options,
});
}
if (isOpen !== prevProps.isOpen) {
this.setState({
isOpen: isOpen,
});
}
if (total !== prevProps.total) {
const groups = this.generateGroups();
const users = this.generateUsers(total, groups);
this.setState(this.getDefaultState(isOpen, groups, users));
}
}
toggle = () => {
this.setState({
isOpen: !this.state.isOpen,
});
};
render() {
const {
isOpen,
options,
groups,
selectedOptions,
selectedGroups,
hasNextPage,
isNextPageLoading,
} = this.state;
return (
<div style={{ position: "relative" }}>
<Button label="Toggle dropdown" onClick={this.toggle} />
<AdvancedSelector2
options={options}
groups={groups}
hasNextPage={hasNextPage}
isNextPageLoading={isNextPageLoading}
loadNextPage={this.loadNextPage}
size={select("size", sizes, "full")}
displayType={select("displayType", displayTypes, "auto")}
selectedOptions={selectedOptions}
selectedGroups={selectedGroups}
isOpen={isOpen}
isMultiSelect={boolean("isMultiSelect", true)}
isDisabled={boolean("isDisabled", false)}
searchPlaceHolderLabel={text(
"searchPlaceHolderLabel",
"Search users"
)}
selectButtonLabel={text("selectButtonLabel", "Add members")}
selectAllLabel={text("selectAllLabel", "Select all")}
groupsHeaderLabel={text("groupsHeaderLabel", "Groups")}
emptySearchOptionsLabel={text(
"emptySearchOptionsLabel",
"There are no users with such name"
)}
emptyOptionsLabel={text("emptyOptionsLabel", "There are no users")}
loadingLabel={text("loadingLabel", "Loading... Please wait...")}
onSelect={(selectedOptions) => {
action("onSelect")(selectedOptions);
this.toggle();
}}
onSearchChanged={(value) => {
action("onSearchChanged")(value);
this.setState({ options: [], hasNextPage: true });
}}
onGroupChanged={(group) => {
action("onGroupChanged")(group);
this.setState({ options: [], hasNextPage: true });
}}
onCancel={() =>
this.setState({
isOpen: false,
})
}
getOptionTooltipContent={(index) => {
if (!index) return null;
const user = options[+index];
if (!user) return null;
// console.log("onOptionTooltipShow", index, user);
return (
<UserTooltip
avatarUrl={user.avatarUrl}
label={user.label}
email={user.email}
position={user.position}
/>
);
}}
/>
</div>
);
}
}
storiesOf("Components|AdvancedSelector", module)
.addDecorator(withKnobs)
.addDecorator(withReadme(Readme))
.addParameters({ options: { addonPanelInRight: false } })
.add("base", () => {
return (
<Section>
<ADSelectorExample
isOpen={boolean("isOpen", true)}
total={number("Users count", 10000)}
/>
</Section>
);
});

View File

@ -1,47 +0,0 @@
# AdvancedSelector
## Usage
```js
import AdvancedSelector from "@docspace/common/components/AdvancedSelector";
```
#### Description
Required to select some advanced data.
#### Usage
```js
let options = [{ key: "self", label: "Me" }];
options = [
...options,
...[...Array(100).keys()].map((index) => {
return {
key: `user${index}`,
label: `User ${index + 1} of ${optionsCount}`,
};
}),
];
<AdvancedSelector
placeholder="Search users"
onSearchChanged={(e) => console.log(e.target.value)}
options={options}
isMultiSelect={false}
buttonLabel="Add members"
onSelect={(selectedOptions) => console.log("onSelect", selectedOptions)}
/>;
```
#### Properties
| Props | Type | Required | Values | Default | Description |
| ----------------- | ------------------ | :------: | ------ | ------- | ----------- |
| `placeholder` | `string` | - | | | |
| `options` | `array of objects` | - | | | |
| `isMultiSelect` | `bool` | - | - | | |
| `buttonLabel` | `string` | - | - | | |
| `onSearchChanged` | `func` | - | - | | |
| `onSelect` | `func` | - | - | | |

View File

@ -1,2 +0,0 @@
import AdvancedSelector from "./AdvancedSelector";
export default AdvancedSelector;

View File

@ -1,50 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import { Button } from "@docspace/shared/components/button";
import StyledFooter from "./StyledFooter";
const Footer = (props) => {
const {
selectButtonLabel,
isDisabled,
onClick,
isVisible,
className,
embeddedComponent,
selectedLength,
showCounter,
} = props;
return (
<StyledFooter
withEmbeddedComponent={embeddedComponent}
isVisible={isVisible}
className={className}
>
<Button
className="add_members_btn"
primary={true}
size="normal"
label={`${selectButtonLabel} ${
selectedLength && showCounter ? `(${selectedLength})` : ""
}`}
scale={true}
isDisabled={isDisabled}
onClick={onClick}
/>
{embeddedComponent && embeddedComponent}
</StyledFooter>
);
};
Footer.propTypes = {
className: PropTypes.string,
selectButtonLabel: PropTypes.string,
isDisabled: PropTypes.bool,
isVisible: PropTypes.bool,
onClick: PropTypes.func,
comboBoxOptions: PropTypes.any,
embeddedComponent: PropTypes.any,
};
export default Footer;

View File

@ -1,62 +0,0 @@
import React from "react";
import { Avatar } from "@docspace/shared/components/avatar";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
const Group = ({ data, style, index }) => {
const { groupList, isMultiSelect, onGroupClick } = data;
const { label, avatarUrl, total, selectedCount } = groupList[index];
const isIndeterminate = selectedCount > 0 && selectedCount !== total;
const isChecked = total !== 0 && total === selectedCount;
let groupLabel = label;
if (isMultiSelect && selectedCount > 0) {
groupLabel = `${label} (${selectedCount})`;
}
const onGroupClickAction = React.useCallback(() => {
onGroupClick && onGroupClick(index);
}, []);
return (
<div
style={style}
className="row-option"
name={`selector-row-option-${index}`}
onClick={onGroupClickAction}
>
<div className="option-info">
<Avatar
className="option-avatar"
role="user"
size="min"
source={avatarUrl}
userName={label}
/>
<Text
className="option-text option-text__group"
truncate={true}
noSelect={true}
fontSize="14px"
>
{groupLabel}
</Text>
</div>
{isMultiSelect && (
<Checkbox
value={`${index}`}
isChecked={isChecked}
isIndeterminate={isIndeterminate}
className="option-checkbox"
/>
)}
</div>
);
};
export default React.memo(Group);

View File

@ -1,59 +0,0 @@
import React from "react";
import { Avatar } from "@docspace/shared/components/avatar";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
const GroupHeader = ({
avatarUrl,
label,
selectedCount,
isMultiSelect,
onSelectAll,
isIndeterminate,
isChecked,
...rest
}) => {
const [groupLabel, setGroupLabel] = React.useState(label);
React.useEffect(() => {
if (isMultiSelect) {
selectedCount > 0
? setGroupLabel(`${label} (${selectedCount})`)
: setGroupLabel(`${label}`);
}
}, [selectedCount, isMultiSelect, label]);
return (
<>
<div className="row-option row-header">
<div className="option-info">
<Avatar
className="option-avatar"
role="user"
size="min"
source={avatarUrl}
userName={label}
/>
<Text
className="option-text option-text__header"
truncate={true}
noSelect={true}
fontSize="14px"
>
{groupLabel}
</Text>
</div>
{isMultiSelect && (
<Checkbox
isIndeterminate={isIndeterminate}
isChecked={isChecked}
onChange={onSelectAll}
className="option-checkbox"
/>
)}
</div>
</>
);
};
export default React.memo(GroupHeader);

View File

@ -1,28 +0,0 @@
import React from "react";
import { FixedSizeList as List } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";
import { CustomScrollbarsVirtualList } from "@docspace/shared/components/scrollbar";
import Group from "./Group";
const GroupList = ({ groupList, onGroupClick, isMultiSelect }) => {
return (
<AutoSizer>
{({ width, height }) => (
<List
className="options-list"
height={height - 8}
width={width + 8}
itemCount={groupList.length}
itemData={{ groupList, onGroupClick, isMultiSelect }}
itemSize={48}
outerElementType={CustomScrollbarsVirtualList}
>
{Group}
</List>
)}
</AutoSizer>
);
};
export default React.memo(GroupList);

View File

@ -1,25 +0,0 @@
import React from "react";
import { Heading } from "@docspace/shared/components/heading";
import { IconButton } from "@docspace/shared/components/icon-button";
import ArrowPathReactSvgUrl from "PUBLIC_DIR/images/arrow.path.react.svg?url";
const Header = ({ headerLabel, onArrowClickAction }) => {
return (
<div className="header">
<IconButton
iconName={ArrowPathReactSvgUrl}
size="17"
isFill={true}
className="arrow-button"
onClick={onArrowClickAction}
/>
<Heading size="medium" truncate={true}>
{headerLabel.replace("()", "")}
</Heading>
</div>
);
};
export default React.memo(Header);

View File

@ -1,97 +0,0 @@
import React from "react";
import { Avatar } from "@docspace/shared/components/avatar";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
import Loaders from "../../Loaders";
const Option = ({
style,
isMultiSelect,
index,
isChecked,
avatarUrl,
label,
keyProp,
onOptionChange,
onLinkClick,
isLoader,
countLoaderRows,
}) => {
const onOptionChangeAction = React.useCallback(() => {
onOptionChange && onOptionChange(index, isChecked);
}, [onOptionChange, index, isChecked]);
const onLinkClickAction = React.useCallback(() => {
onLinkClick && onLinkClick(index);
}, [onLinkClick, index]);
return isLoader ? (
<div style={style}>
<div key="loader" className="option-loader">
<Loaders.ListLoader withoutFirstRectangle count={countLoaderRows} />
</div>
</div>
) : isMultiSelect ? (
<div
style={style}
className="row-option"
value={`${index}`}
name={`selector-row-option-${index}`}
onClick={onOptionChangeAction}
>
<div className="option-info">
<Avatar
className="option-avatar"
role="user"
size="min"
source={avatarUrl}
userName={label}
/>
<Text
className="option-text"
truncate={true}
noSelect={true}
fontSize="14px"
>
{label}
</Text>
</div>
<Checkbox
id={keyProp}
value={`${index}`}
isChecked={isChecked}
className="option-checkbox"
/>
</div>
) : (
<div
key={keyProp}
style={style}
className="row-option"
data-index={index}
name={`selector-row-option-${index}`}
onClick={onLinkClickAction}
>
<div className="option-info">
<Avatar
className="option-avatar"
role="user"
size="min"
source={avatarUrl}
userName={label}
/>
<Text
className="option-text"
truncate={true}
noSelect={true}
fontSize="14px"
>
{label}
</Text>
</div>
</div>
);
};
export default React.memo(Option);

View File

@ -1,93 +0,0 @@
import React from "react";
import { FixedSizeList as List } from "react-window";
import InfiniteLoader from "react-window-infinite-loader";
import AutoSizer from "react-virtualized-auto-sizer";
import { CustomScrollbarsVirtualList } from "@docspace/shared/components/scrollbar";
import Option from "./Option";
const OptionList = ({
listOptionsRef,
options,
isOptionChecked,
isMultiSelect,
onOptionChange,
onLinkClick,
isItemLoaded,
itemCount,
loadMoreItems,
isFirstLoad,
}) => {
const renderOption = React.useCallback(
({ index, style }) => {
const isLoaded = isItemLoaded(index);
if (!isLoaded) {
if (!isFirstLoad) {
return (
<div style={style}>
<Option isLoader={true} countLoaderRows={2} />
</div>
);
}
return <Option isLoader={true} />;
}
const option = options[index];
const isChecked = isOptionChecked(option);
return (
<Option
index={index}
style={style}
{...option}
isChecked={isChecked}
onOptionChange={onOptionChange}
onLinkClick={onLinkClick}
isMultiSelect={isMultiSelect}
/>
);
},
[
options,
isMultiSelect,
isItemLoaded,
isOptionChecked,
onOptionChange,
onLinkClick,
]
);
return (
<AutoSizer>
{({ width, height }) => (
<InfiniteLoader
ref={listOptionsRef}
isItemLoaded={isItemLoaded}
itemCount={itemCount}
loadMoreItems={loadMoreItems}
>
{({ onItemsRendered, ref }) => (
<List
className="options-list"
height={height - 73}
itemCount={itemCount}
itemSize={48}
onItemsRendered={onItemsRendered}
ref={ref}
width={width + 8}
outerElementType={CustomScrollbarsVirtualList}
>
{renderOption}
</List>
)}
</InfiniteLoader>
)}
</AutoSizer>
);
};
export default React.memo(OptionList);

View File

@ -1,29 +0,0 @@
import React from "react";
import { SearchInput } from "@docspace/shared/components/search-input";
const Search = ({
isDisabled,
searchPlaceHolderLabel,
searchValue,
onSearchChange,
onSearchReset,
}) => {
return (
<div className="header-options">
<SearchInput
className="options_searcher"
isDisabled={isDisabled}
size="base"
scale={true}
isNeedFilter={false}
placeholder={searchPlaceHolderLabel}
value={searchValue}
onChange={onSearchChange}
onClearSearch={onSearchReset}
/>
</div>
);
};
export default React.memo(Search);

View File

@ -1,447 +0,0 @@
import React, { useRef, useState, useEffect, useCallback } from "react";
import PropTypes from "prop-types";
import Header from "./Header";
import Search from "./Search";
import GroupList from "./GroupList";
import GroupHeader from "./GroupHeader";
import OptionList from "./OptionList";
import Option from "./Option";
import Footer from "./Footer";
import { Text } from "@docspace/shared/components/text";
import { Tooltip } from "@docspace/shared/components/tooltip";
import StyledSelector from "./StyledSelector";
const convertGroups = (items) => {
if (!items) return [];
const wrappedGroups = items.map(convertGroup);
return wrappedGroups;
};
const convertGroup = (group) => {
return {
key: group.key,
label: `${group.label} (${group.total})`,
total: group.total,
selectedCount: 0,
};
};
const getCurrentGroup = (items) => {
const currentGroup = items.length > 0 ? items[0] : {};
return currentGroup;
};
const Selector = (props) => {
const {
groups,
isDisabled,
isMultiSelect,
hasNextPage,
options,
isNextPageLoading,
loadNextPage,
selectedOptions,
selectedGroups,
searchPlaceHolderLabel,
emptySearchOptionsLabel,
emptyOptionsLabel,
loadingLabel,
onSelect,
getOptionTooltipContent,
onSearchChanged,
onGroupChanged,
size,
embeddedComponent,
showCounter,
onArrowClick,
headerLabel,
total,
isFirstLoad,
} = props;
const listOptionsRef = useRef(null);
useEffect(() => {
Object.keys(currentGroup).length === 0 &&
setCurrentGroup(getCurrentGroup(convertGroups(groups)));
resetCache();
}, [searchValue, currentGroup, hasNextPage]);
const resetCache = useCallback(() => {
if (listOptionsRef && listOptionsRef.current) {
listOptionsRef.current.resetloadMoreItemsCache(true);
}
}, [listOptionsRef]);
const [selectedOptionList, setSelectedOptionList] = useState(
selectedOptions || []
);
const [searchValue, setSearchValue] = useState("");
const [groupList, setGroupList] = useState([]);
const [currentGroup, setCurrentGroup] = useState(
getCurrentGroup(convertGroups(groups))
);
const [groupHeader, setGroupHeader] = useState(null);
useEffect(() => {
if (groups.length === 0) return;
const newGroupList = [...groups];
if (
groups.length === 1 &&
selectedOptions &&
selectedOptions.length === 0
) {
return setGroupHeader(newGroupList[0]);
}
if (selectedOptions && selectedOptions.length === 0) {
return setGroupList(newGroupList);
}
if (selectedOptions) {
newGroupList[0].selectedCount = selectedOptions.length;
if (groups.length === 1) return setGroupHeader(newGroupList[0]);
selectedOptions.forEach((option) => {
option?.groups?.forEach((group) => {
const groupIndex = newGroupList.findIndex(
(newGroup) => group === newGroup.id
);
if (groupIndex > -1) {
newGroupList[groupIndex].selectedCount =
newGroupList[groupIndex].selectedCount + 1;
}
});
});
}
if (groups.length === 1) return setGroupHeader(newGroupList[0]);
setGroupList(newGroupList);
}, [groups, selectedOptions]);
useEffect(() => {
if (total) {
setGroupHeader({ ...groupHeader, total: total });
const newGroupList = groupList;
if (newGroupList.length > 0) {
newGroupList.find((group) => group.key === groupHeader.key).total =
total;
}
setGroupList(newGroupList);
}
}, [total]);
const onSearchChange = useCallback(
(value) => {
setSearchValue(value);
onSearchChanged && onSearchChanged(value);
},
[onSearchChanged]
);
const onSearchReset = useCallback(() => {
onSearchChanged && onSearchChange("");
}, [onSearchChanged]);
// Every row is loaded except for our loading indicator row.
const isItemLoaded = useCallback(
(index) => {
return !hasNextPage || index < options.length;
},
[hasNextPage, options]
);
const onOptionChange = useCallback(
(idx, isChecked) => {
const indexList = Array.isArray(idx) ? idx : [idx];
let newSelected = selectedOptionList;
let newGroupList = groupList;
let newGroupHeader = { ...groupHeader };
indexList.forEach((index) => {
newGroupHeader.selectedCount = isChecked
? newGroupHeader.selectedCount - 1
: newGroupHeader.selectedCount + 1;
const option = options[index];
newSelected = !isChecked
? [option, ...newSelected]
: newSelected.filter((el) => el.key !== option.key);
if (!option.groups) {
setSelectedOptionList(newSelected);
setGroupHeader(newGroupHeader);
return;
}
if (newGroupList.length) {
newGroupList[0].selectedCount = isChecked
? newGroupList[0].selectedCount - 1
: newGroupList[0].selectedCount + 1;
option.groups.forEach((group) => {
const groupIndex = newGroupList.findIndex(
(item) => item.key === group
);
if (groupIndex > 0) {
newGroupList[groupIndex].selectedCount = isChecked
? newGroupList[groupIndex].selectedCount - 1
: newGroupList[groupIndex].selectedCount + 1;
}
});
}
});
setSelectedOptionList(newSelected);
setGroupList(newGroupList);
setGroupHeader(newGroupHeader);
},
[options, groupList, selectedOptionList, groupHeader]
);
const isOptionChecked = useCallback(
(option) => {
const checked = selectedOptionList.find(
(item) => item.key === option.key
);
return !!checked;
},
[selectedOptionList]
);
const onSelectOptions = (items) => {
onSelect && onSelect(items);
};
const onAddClick = useCallback(() => {
onSelectOptions(selectedOptionList);
}, [selectedOptionList]);
const onLinkClick = useCallback(
(index) => {
const option = options[index];
if (!option) return;
onSelectOptions([option]);
},
[options]
);
// If there are more items to be loaded then add an extra row to hold a loading indicator.
// Only load 1 page of items at a time.
// Pass an empty callback to InfiniteLoader in case it asks us to load more than once.
const loadMoreItems = useCallback(
(startIndex) => {
if (isNextPageLoading) return;
const options = {
startIndex: startIndex || 0,
searchValue: searchValue,
currentGroup: currentGroup ? currentGroup.key : null,
};
loadNextPage && loadNextPage(options);
},
[isNextPageLoading, searchValue, currentGroup, options]
);
const onSelectAll = useCallback(() => {
const currentSelectedOption = [];
selectedOptionList.forEach((selectedOption) => {
options.forEach((option, idx) => {
if (option.key === selectedOption.key) currentSelectedOption.push(idx);
});
});
if (currentSelectedOption.length > 0) {
return onOptionChange(currentSelectedOption, true);
}
onOptionChange(
options.map((item, index) => index),
false
);
}, [onOptionChange, selectedOptionList, options]);
const onGroupClick = useCallback(
(index) => {
const group = groupList[index];
setGroupHeader({ ...group });
onGroupChanged && onGroupChanged(group);
setCurrentGroup(group);
},
[groupList, onGroupChanged]
);
const onArrowClickAction = useCallback(() => {
if (groupHeader && groups.length !== 1) {
setGroupHeader(null);
onGroupChanged && onGroupChanged([]);
setCurrentGroup([]);
return;
}
onArrowClick && onArrowClick();
}, [groups, groupHeader && groupHeader.label, onArrowClick, onGroupChanged]);
const renderGroupsList = useCallback(() => {
if (groupList.length === 0) {
return <Option isLoader={true} />;
}
return (
<GroupList
groupList={groupList}
isMultiSelect={isMultiSelect}
onGroupClick={onGroupClick}
/>
);
}, [isMultiSelect, groupList, onGroupClick]);
const itemCount = hasNextPage ? options.length + 1 : options.length;
const hasSelected = selectedOptionList.length > 0;
return (
<StyledSelector
isMultiSelect={isMultiSelect}
hasSelected={hasSelected}
className="selector-wrapper"
>
<Header
headerLabel={headerLabel}
onArrowClickAction={onArrowClickAction}
/>
<div style={{ height: "100%" }} className="column-options" size={size}>
<Search
isDisabled={isDisabled}
placeholder={searchPlaceHolderLabel}
value={searchValue}
onSearchChange={onSearchChange}
onClearSearch={onSearchReset}
/>
<div style={{ width: "100%", height: "100%" }} className="body-options">
{!groupHeader && !searchValue && groups ? (
renderGroupsList()
) : (
<>
{!searchValue && (
<>
<GroupHeader
{...groupHeader}
onSelectAll={onSelectAll}
isMultiSelect={isMultiSelect}
isIndeterminate={
groupHeader.selectedCount > 0 &&
groupHeader.selectedCount !== groupHeader.total
}
isChecked={
groupHeader.total !== 0 &&
groupHeader.total === groupHeader.selectedCount
}
/>
<div className="option-separator"></div>
</>
)}
{!hasNextPage && itemCount === 0 ? (
<div className="row-option">
<Text>
{!searchValue ? emptyOptionsLabel : emptySearchOptionsLabel}
</Text>
</div>
) : (
<OptionList
listOptionsRef={listOptionsRef}
options={options}
itemCount={itemCount}
isMultiSelect={isMultiSelect}
onOptionChange={onOptionChange}
onLinkClick={onLinkClick}
isItemLoaded={isItemLoaded}
isOptionChecked={isOptionChecked}
loadMoreItems={loadMoreItems}
isFirstLoad={isFirstLoad}
/>
)}
</>
)}
{getOptionTooltipContent && (
<Tooltip
id="user"
offsetRight={90}
getContent={getOptionTooltipContent}
/>
)}
</div>
</div>
<Footer
className="footer"
selectButtonLabel={headerLabel}
showCounter={showCounter}
isDisabled={isDisabled}
isVisible={isMultiSelect && hasSelected}
onClick={onAddClick}
embeddedComponent={embeddedComponent}
selectedLength={selectedOptionList.length}
/>
</StyledSelector>
);
};
Selector.propTypes = {
options: PropTypes.array,
groups: PropTypes.array,
hasNextPage: PropTypes.bool,
isNextPageLoading: PropTypes.bool,
loadNextPage: PropTypes.func,
isDisabled: PropTypes.bool,
isMultiSelect: PropTypes.bool,
allowGroupSelection: PropTypes.bool,
isFirstLoad: PropTypes.bool,
selectButtonLabel: PropTypes.string,
selectAllLabel: PropTypes.string,
searchPlaceHolderLabel: PropTypes.string,
groupsHeaderLabel: PropTypes.string,
emptySearchOptionsLabel: PropTypes.string,
emptyOptionsLabel: PropTypes.string,
loadingLabel: PropTypes.string,
selectedOptions: PropTypes.array,
selectedGroups: PropTypes.array,
onSelect: PropTypes.func,
onSearchChanged: PropTypes.func,
onGroupChanged: PropTypes.func,
getOptionTooltipContent: PropTypes.func,
embeddedComponent: PropTypes.any,
};
export default React.memo(Selector);

View File

@ -1,38 +0,0 @@
import styled, { css } from "styled-components";
import Base from "../../../../components/themes/base";
const StyledFooter = styled.div`
box-sizing: border-box;
border-top: ${(props) => props.theme.advancedSelector.footerBorder};
padding: 16px;
height: 69px;
display: flex;
align-items: center;
${(props) =>
props.withEmbeddedComponent &&
css`
display: flex;
`}
${(props) =>
!props.isVisible &&
css`
display: none;
`}
button {
min-height: 40px;
}
.embedded_combo-box {
.combo-button {
min-height: 42px;
}
}
`;
StyledFooter.defaultProps = { theme: Base };
export default StyledFooter;

View File

@ -1,212 +0,0 @@
import styled, { css } from "styled-components";
import Base from "@docspace/shared/themes/base";
/* eslint-disable no-unused-vars */
/* eslint-disable react/prop-types */
/* eslint-enable react/prop-types */
/* eslint-enable no-unused-vars */
const StyledSelector = styled.div`
display: grid;
height: 100%;
grid-template-columns: 1fr;
${(props) =>
props.isMultiSelect && props.hasSelected
? css`
grid-template-rows: 53px 1fr 69px;
grid-template-areas: "header" "column-options" "footer";
`
: css`
grid-template-rows: 53px 1fr;
grid-template-areas: "header" "column-options";
`}
.header {
grid-area: header;
height: 53px;
min-height: 53px;
padding: 0 16px;
margin: 0;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: start;
.arrow-button {
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `margin-left: 12px;`
: `margin-right: 12px;`}
}
svg {
cursor: pointer;
}
}
.column-options {
grid-area: column-options;
box-sizing: border-box;
display: grid;
padding: 0;
grid-row-gap: 2px;
overflow: hidden;
grid-template-columns: 1fr;
grid-template-rows: 30px 1fr;
grid-template-areas: "header-options" "body-options";
.header-options {
grid-area: header-options;
padding: 0 16px;
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `margin-left: 0px !important;`
: `margin-right: 0px !important;`}
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 30px;
grid-template-areas: "options_searcher";
.options_searcher {
grid-area: options_searcher;
}
.options_searcher {
div:first-child {
:hover {
border-color: ${(props) =>
props.theme.advancedSelector.searcher.hoverBorderColor};
}
:focus,
:focus-within {
border-color: ${(props) =>
props.theme.advancedSelector.searcher.focusBorderColor};
}
& > input::placeholder {
color: ${(props) =>
props.theme.advancedSelector.searcher.placeholderColor};
}
}
}
}
.body-options {
grid-area: body-options;
margin-top: 8px;
.options-list {
div:nth-child(3) {
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `left: 10px !important;`
: `right: 10px !important;`}
}
}
.option-loader {
width: 100%;
height: 100%;
margin-top: 16px;
}
.row-option {
box-sizing: border-box;
height: 48px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
&:hover {
background-color: ${(props) =>
props.theme.advancedSelector.hoverBackgroundColor};
}
.option-info {
width: calc(100% - 32px);
display: flex;
align-items: center;
justify-content: start;
}
.option-avatar {
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `margin-left: 12px;`
: `margin-right: 12px;`}
min-width: 32px;
max-width: 32px;
}
.option-text {
max-width: 100%;
line-height: 16px;
}
.option-text__group {
width: auto;
border-bottom: ${(props) =>
props.theme.toggleContent.hoverBorderBottom};
}
.option-text__header {
font-weight: 600;
}
.option-checkbox {
margin-left: 8px;
margin-right: 8px;
min-width: 16px;
max-width: 16px;
}
}
.option-separator {
height: 1px;
background: ${(props) =>
props.theme.advancedSelector.selectedBackgroundColor};
margin: 8px 16px;
}
.row-header {
cursor: auto;
.option-checkbox {
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `margin-left: 0 !important;`
: `margin-right: 0 !important;`}
}
:hover {
background: none;
}
}
}
}
.footer {
grid-area: footer;
}
`;
StyledSelector.defaultProps = { theme: Base };
export default StyledSelector;

View File

@ -1,31 +0,0 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Loader } from "@docspace/shared/components/loader";
import Section from "../Section";
export class ExternalRedirect extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
const { to } = this.props;
to && window.location.replace(to);
}
render() {
return (
<Section>
<Section.SectionBody>
<Loader className="pageLoader" type="rombs" size="40px" />
</Section.SectionBody>
</Section>
);
}
}
ExternalRedirect.propTypes = {
to: PropTypes.string,
};
export default ExternalRedirect;

View File

@ -1 +0,0 @@
export default from "./ExternalRedirect";

View File

@ -1,50 +0,0 @@
import React from "react";
import { RectangleSkeleton } from "@docspace/shared/skeletons";
import StyledDialogAsideLoader from "./StyledDialogAsideLoader";
import { Aside } from "@docspace/shared/components/aside";
import { Backdrop } from "@docspace/shared/components/backdrop";
const DialogAsideLoader = ({
isPanel,
withoutAside,
withFooterBorder = false,
}) => {
const zIndex = 310;
const renderClearDialogAsideLoader = () => {
return (
<StyledDialogAsideLoader
withFooterBorder={withFooterBorder}
isPanel={isPanel}
visible
>
<div className="dialog-loader-header">
<RectangleSkeleton height="29px" />
</div>
<div className="dialog-loader-body">
<RectangleSkeleton height="200px" />
</div>
<div className="dialog-loader-footer">
<RectangleSkeleton height="40px" />
<RectangleSkeleton height="40px" />
</div>
</StyledDialogAsideLoader>
);
};
return withoutAside ? (
renderClearDialogAsideLoader()
) : (
<>
<Backdrop visible isAside zIndex={zIndex} />
<StyledDialogAsideLoader visible isPanel={isPanel}>
<Aside className="dialog-aside-loader" visible zIndex={zIndex}>
{renderClearDialogAsideLoader()}
</Aside>
</StyledDialogAsideLoader>
</>
);
};
export default DialogAsideLoader;

View File

@ -1,63 +0,0 @@
import styled, { css } from "styled-components";
const StyledDialogAsideLoader = styled.div`
${(props) =>
props.isPanel
? css`
.dialog-loader-header {
padding: 12px 16px;
height: 53px;
border-bottom: ${(props) =>
`1px solid ${props.theme.modalDialog.headerBorderColor}`};
box-sizing: border-box;
}
.dialog-loader-body {
padding: 16px;
}
.dialog-loader-footer {
padding: 12px 16px;
position: fixed;
bottom: 0;
height: 71px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
box-sizing: border-box;
border-top: ${(props) =>
`1px solid ${props.theme.modalDialog.headerBorderColor}`};
}
`
: css`
.dialog-loader-header {
border-bottom: ${(props) =>
`1px solid ${props.theme.modalDialog.headerBorderColor}`};
padding: 12px 16px;
}
.dialog-loader-body {
padding: 16px;
}
.dialog-loader-footer {
${(props) =>
props.withFooterBorder &&
`border-top: 1px solid ${props.theme.modalDialog.headerBorderColor}`};
padding: 16px;
position: fixed;
bottom: 0;
width: calc(100% - 32px);
}
`}
`;
export default StyledDialogAsideLoader;

View File

@ -1 +0,0 @@
export default from "./DialogAsideLoader";

View File

@ -1,22 +0,0 @@
import React from "react";
import { RectangleSkeleton } from "@docspace/shared/skeletons";
import StyledDialogLoader from "./StyledDialogLoader";
const DialogLoader = ({ isLarge, withFooterBorder }) => {
return (
<StyledDialogLoader withFooterBorder={withFooterBorder} isLarge={isLarge}>
<div className="dialog-loader-header">
<RectangleSkeleton height="29px" />
</div>
<div className="dialog-loader-body">
<RectangleSkeleton height={isLarge ? "175px" : "73px"} />
</div>
<div className="dialog-loader-footer">
<RectangleSkeleton height="40px" />
<RectangleSkeleton height="40px" />
</div>
</StyledDialogLoader>
);
};
export default DialogLoader;

View File

@ -1,34 +0,0 @@
import { Base } from "@docspace/shared/themes";
import styled from "styled-components";
import { mobile } from "@docspace/shared/utils";
const StyledDialogLoader = styled.div`
height: auto;
width: ${(props) => (props.isLarge ? "520px" : "400px")};
@media ${mobile} {
width: 100%;
}
.dialog-loader-header {
border-bottom: ${(props) =>
`1px solid ${props.theme.modalDialog.headerBorderColor}`};
padding: 12px 16px;
}
.dialog-loader-body {
padding: 12px 16px 8px;
}
.dialog-loader-footer {
${(props) =>
props.withFooterBorder &&
`border-top: 1px solid ${props.theme.modalDialog.headerBorderColor}`};
display: flex;
gap: 10px;
padding: 16px;
}
`;
StyledDialogLoader.defaultProps = { theme: Base };
export default StyledDialogLoader;

View File

@ -1 +0,0 @@
export default from "./DialogLoader";

View File

@ -1,47 +0,0 @@
import React, { useEffect, useState } from "react";
import { RowsSkeleton } from "@docspace/shared/skeletons";
import { TilesSkeleton } from "@docspace/shared/skeletons/tiles";
import { isMobile, isTablet } from "@docspace/shared/utils";
const EmptyContainerLoader = ({ viewAs, style, ...rest }) => {
const [viewMobile, setViewMobile] = useState(false);
const [viewTablet, setViewTablet] = useState(false);
useEffect(() => {
onCheckView();
window.addEventListener("resize", onCheckView);
return () => window.removeEventListener("resize", onCheckView);
}, []);
const onCheckView = () => {
if (isMobile()) {
setViewMobile(true);
} else {
setViewMobile(false);
}
if (isTablet()) {
setViewTablet(true);
} else {
setViewTablet(false);
}
};
return (
<div {...rest} style={{ display: "contents", style }}>
{viewAs === "tile" ? (
!viewMobile && !viewTablet ? (
<TilesSkeleton filesCount={7} />
) : (
<TilesSkeleton />
)
) : (
<RowsSkeleton count={(viewMobile && 8) || (viewTablet && 12) || 9} />
)}
</div>
);
};
export default EmptyContainerLoader;

View File

@ -1 +0,0 @@
export default from "./EmptyContainerLoader";

View File

@ -1,93 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import { StyledGroup, StyledLastRow, StyledSpacer } from "./StyledGroupLoader";
import { RectangleSkeleton } from "@docspace/shared/skeletons";
const GroupLoader = ({ id, className, style, ...rest }) => {
const {
title,
borderRadius,
backgroundColor,
foregroundColor,
backgroundOpacity,
foregroundOpacity,
speed,
animate,
} = rest;
return (
<StyledGroup id={id} className={className} style={style}>
<RectangleSkeleton
title={title}
borderRadius={borderRadius}
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}
backgroundOpacity={backgroundOpacity}
foregroundOpacity={foregroundOpacity}
speed={speed}
animate={animate}
/>
<RectangleSkeleton
title={title}
borderRadius={borderRadius}
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}
backgroundOpacity={backgroundOpacity}
foregroundOpacity={foregroundOpacity}
speed={speed}
animate={animate}
/>
<RectangleSkeleton
title={title}
borderRadius={borderRadius}
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}
backgroundOpacity={backgroundOpacity}
foregroundOpacity={foregroundOpacity}
speed={speed}
animate={animate}
/>
<StyledSpacer />
<StyledLastRow>
<RectangleSkeleton
title={title}
width="100"
height="36"
borderRadius={borderRadius}
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}
backgroundOpacity={backgroundOpacity}
foregroundOpacity={foregroundOpacity}
speed={speed}
animate={animate}
/>
<RectangleSkeleton
title={title}
width="100"
height="36"
borderRadius={borderRadius}
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}
backgroundOpacity={backgroundOpacity}
foregroundOpacity={foregroundOpacity}
speed={speed}
animate={animate}
/>
</StyledLastRow>
</StyledGroup>
);
};
GroupLoader.propTypes = {
id: PropTypes.string,
className: PropTypes.string,
style: PropTypes.object,
};
GroupLoader.defaultProps = {
id: undefined,
className: undefined,
style: undefined,
};
export default GroupLoader;

View File

@ -1,40 +0,0 @@
import React from "react";
import { storiesOf } from "@storybook/react";
import {
withKnobs,
boolean,
text,
color,
number,
} from "@storybook/addon-knobs/react";
import Section from "../../../../.storybook/decorators/section";
import Loaders from "..";
import { LOADER_STYLE } from "@docspace/shared/constants";
import withReadme from "storybook-readme/with-readme";
import Readme from "./README.md";
storiesOf("Components|Loaders", module)
.addDecorator(withKnobs)
.addDecorator(withReadme(Readme))
.add("group loader", () => (
<Section>
<h1>Group Loader</h1>
<Loaders.Group
title={text("title", LOADER_STYLE.title)}
borderRadius={text("borderRadius", "3")}
backgroundColor={color("backgroundColor", LOADER_STYLE.backgroundColor)}
foregroundColor={color("foregroundColor", LOADER_STYLE.foregroundColor)}
backgroundOpacity={number(
"backgroundOpacity",
LOADER_STYLE.backgroundOpacity
)}
foregroundOpacity={number(
"foregroundOpacity",
LOADER_STYLE.foregroundOpacity
)}
speed={number("speed", LOADER_STYLE.speed)}
animate={boolean("animate", LOADER_STYLE.animate)}
/>
</Section>
));

View File

@ -1,26 +0,0 @@
# Group Loader
Component that displays group loader
### Usage
```js
import Loaders from "@docspace/common/components/Loaders";
```
```jsx
<Loaders.Group />
```
### Properties
| Props | Type | Required | Values | Default | Description |
| ------------------- | :------: | :------: | :----: | :-------: | ------------------------------------------------ |
| `title` | `string` | - | - | `` | It's used to describe what element it is. |
| `borderRadius` | `string` | - | - | `3` | Sets the corners rounding |
| `backgroundColor` | `string` | - | - | `#000000` | Used as background of animation |
| `foregroundColor` | `string` | - | - | `#000000` | Used as the foreground of animation |
| `backgroundOpacity` | `number` | - | - | 0.2 | Background opacity (0 = transparent, 1 = opaque) |
| `foregroundOpacity` | `number` | - | - | 0.15 | Animation opacity (0 = transparent, 1 = opaque) |
| `speed` | `number` | - | - | 2 | Animation speed in seconds |
| `animate` | `bool` | - | - | true | Opt-out of animations |

View File

@ -1,27 +0,0 @@
import styled from "styled-components";
import { mobile } from "@docspace/shared/utils";
const StyledGroup = styled.div`
width: 400px;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
grid-row-gap: 14px;
@media ${mobile} {
width: 100%;
}
`;
const StyledLastRow = styled.div`
display: grid;
grid-template-columns: 100px 100px;
grid-template-rows: 1fr;
grid-column-gap: 8px;
`;
const StyledSpacer = styled.div`
margin-top: 32px;
`;
export { StyledGroup, StyledLastRow, StyledSpacer };

View File

@ -1 +0,0 @@
export default from "./GroupLoader";

View File

@ -1,31 +0,0 @@
import styled from "styled-components";
import { desktop } from "@docspace/shared/utils";
const StyledTreeFolder = styled.div`
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `padding-left: 16px;`
: `padding-right: 16px;`}
`;
const StyledLoader = styled.div`
width: 100%;
display: grid;
grid-template-columns: 8px 16px 1fr;
grid-template-rows: 1fr;
grid-column-gap: 6px;
margin-bottom: 8px;
box-sizing: border-box;
.tree-node-loader_additional-rectangle {
padding-top: 4px;
}
${(props) =>
props.paddingLeft &&
(props.theme.interfaceDirection === "rtl"
? `padding-right: ${props.paddingLeft}`
: `padding-left: ${props.paddingLeft}`)};
`;
export { StyledLoader, StyledTreeFolder };

View File

@ -1,51 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import { StyledTreeFolder, StyledLoader } from "./StyledTreeFolder";
import TreeNodeLoader from "../TreeNodeLoader";
const NewTreeFolderLoader = ({ id, className, style, ...rest }) => {
return (
<StyledTreeFolder id={id} className={className} style={style}>
<StyledLoader>
<TreeNodeLoader {...rest} withRectangle />
</StyledLoader>
<StyledLoader paddingLeft={"16px"}>
<TreeNodeLoader {...rest} withRectangle />
</StyledLoader>
<StyledLoader paddingLeft={"32px"}>
<TreeNodeLoader {...rest} withRectangle />
</StyledLoader>
<StyledLoader paddingLeft={"32px"}>
<TreeNodeLoader {...rest} withRectangle />
</StyledLoader>
<StyledLoader paddingLeft={"32px"}>
<TreeNodeLoader {...rest} withRectangle />
</StyledLoader>
<StyledLoader>
<TreeNodeLoader {...rest} withRectangle />
</StyledLoader>
<StyledLoader paddingLeft={"16px"}>
<TreeNodeLoader {...rest} withRectangle />
</StyledLoader>
<StyledLoader paddingLeft={"16px"}>
<TreeNodeLoader {...rest} withRectangle />
</StyledLoader>
</StyledTreeFolder>
);
};
NewTreeFolderLoader.propTypes = {
id: PropTypes.string,
className: PropTypes.string,
style: PropTypes.object,
};
NewTreeFolderLoader.defaultProps = {
id: undefined,
className: undefined,
style: undefined,
};
export default NewTreeFolderLoader;

View File

@ -1,159 +0,0 @@
import styled, { css } from "styled-components";
import { Base } from "@docspace/shared/themes";
const StyledContainer = styled.div`
width: 100%;
display: flex;
flex-direction: column;
`;
const StyledHeader = styled.div`
width: 100%;
padding: ${(props) => (props.isPersonal ? "0px 16px 12px" : "12px 16px")};
${(props) =>
props.isPersonal &&
(props.theme.interfaceDirection === "rtl"
? css`
margin-right: -12px;
margin-left: 12px;
`
: css`
margin-left: -12px;
margin-right: 12px;
`)}
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
border-bottom: ${(props) => props.theme.filesPanels.sharing.borderBottom};
`;
StyledHeader.defaultProps = { theme: Base };
const StyledExternalLink = styled.div`
width: 100%;
display: flex;
flex-direction: column;
padding: ${(props) => (props.isPersonal ? "20px 4px" : "20px 16px")};
box-sizing: border-box;
border-bottom: ${(props) =>
props.isPersonal ? "none" : props.theme.filesPanels.sharing.borderBottom};
.rectangle-loader {
margin-bottom: 16px;
}
`;
StyledExternalLink.defaultProps = { theme: Base };
const StyledInternalLink = styled.div`
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 16px;
box-sizing: border-box;
`;
const StyledOwner = styled.div`
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 16px;
box-sizing: border-box;
margin-bottom: 16px;
.owner-info {
display: flex;
align-items: center;
svg:first-child {
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `margin-left: 12px;`
: `margin-right: 12px;`}
}
}
`;
const StyledBody = styled.div`
width: 100%;
display: flex;
flex-direction: column;
div:nth-child(3) {
margin-bottom: 16px;
}
`;
const StyledItem = styled.div`
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 8px 16px;
.item-info {
display: flex;
align-items: center;
svg:first-child {
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `margin-left: 12px;`
: `margin-right: 12px;`}
}
}
`;
const StyledButtons = styled.div`
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 4px;
svg:first-child {
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `margin-left: 8px;`
: `margin-right: 8px;`}
}
`;
export {
StyledContainer,
StyledHeader,
StyledExternalLink,
StyledInternalLink,
StyledOwner,
StyledBody,
StyledItem,
StyledButtons,
};

View File

@ -1,138 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import {
StyledContainer,
StyledHeader,
StyledExternalLink,
StyledInternalLink,
StyledOwner,
StyledBody,
StyledItem,
} from "./StyledSharingPanel";
import { RectangleSkeleton } from "@docspace/shared/skeletons";
const SharingPanelLoader = ({ id, className, style, ...rest }) => {
return (
<StyledContainer>
<StyledHeader>
<RectangleSkeleton width={"283px"} height={"29px"} />
<RectangleSkeleton width={"48px"} height={"29px"} />
</StyledHeader>
<StyledExternalLink>
<RectangleSkeleton
className="rectangle-loader"
width={"146px"}
height={"22px"}
/>
<RectangleSkeleton
className="rectangle-loader"
width={"448px"}
height={"32px"}
/>
<RectangleSkeleton width={"184px"} height={"20px"} />
</StyledExternalLink>
<StyledInternalLink>
<RectangleSkeleton width={"99px"} height={"22px"} />
<RectangleSkeleton width={"30px"} height={"22px"} />
</StyledInternalLink>
<StyledOwner>
<div className="owner-info">
<RectangleSkeleton
width={"32px"}
height={"32px"}
borderRadius={"1000px"}
/>
<RectangleSkeleton width={"91px"} height={"16px"} />
</div>
<RectangleSkeleton width={"91px"} height={"16px"} />
</StyledOwner>
<StyledBody>
<StyledItem>
<div className="item-info">
<RectangleSkeleton
width={"32px"}
height={"32px"}
borderRadius={"1000px"}
/>
<RectangleSkeleton width={"91px"} height={"16px"} />
</div>
<RectangleSkeleton width={"45px"} height={"32px"} />
</StyledItem>
<StyledItem>
<div className="item-info">
<RectangleSkeleton
width={"32px"}
height={"32px"}
borderRadius={"1000px"}
/>
<RectangleSkeleton width={"91px"} height={"16px"} />
</div>
<RectangleSkeleton width={"45px"} height={"32px"} />
</StyledItem>
<StyledItem>
<div className="item-info">
<RectangleSkeleton
width={"32px"}
height={"32px"}
borderRadius={"1000px"}
/>
<RectangleSkeleton width={"91px"} height={"16px"} />
</div>
<RectangleSkeleton width={"45px"} height={"32px"} />
</StyledItem>
<StyledItem>
<div className="item-info">
<RectangleSkeleton
width={"32px"}
height={"32px"}
borderRadius={"1000px"}
/>
<RectangleSkeleton width={"91px"} height={"16px"} />
</div>
<RectangleSkeleton width={"45px"} height={"32px"} />
</StyledItem>
<StyledItem>
<div className="item-info">
<RectangleSkeleton
width={"32px"}
height={"32px"}
borderRadius={"1000px"}
/>
<RectangleSkeleton width={"91px"} height={"16px"} />
</div>
<RectangleSkeleton width={"45px"} height={"32px"} />
</StyledItem>
<StyledItem>
<div className="item-info">
<RectangleSkeleton
width={"32px"}
height={"32px"}
borderRadius={"1000px"}
/>
<RectangleSkeleton width={"91px"} height={"16px"} />
</div>
<RectangleSkeleton width={"45px"} height={"32px"} />
</StyledItem>
</StyledBody>
</StyledContainer>
);
};
SharingPanelLoader.propTypes = {
id: PropTypes.string,
className: PropTypes.string,
style: PropTypes.object,
};
SharingPanelLoader.defaultProps = {
id: undefined,
className: undefined,
style: undefined,
};
export default SharingPanelLoader;

View File

@ -1,66 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import {
StyledContainer,
StyledHeader,
StyledExternalLink,
StyledInternalLink,
StyledOwner,
StyledBody,
StyledItem,
StyledButtons,
} from "./StyledSharingPanel";
import { RectangleSkeleton } from "@docspace/shared/skeletons";
const SharingPanelLoaderModal = ({
id,
className,
style,
isShared,
...rest
}) => {
return (
<StyledContainer>
<StyledHeader isPersonal={true}>
<RectangleSkeleton width={"283px"} height={"16px"} />
</StyledHeader>
<StyledExternalLink isPersonal={true}>
<RectangleSkeleton
className="rectangle-loader"
width={"146px"}
height={"22px"}
/>
{isShared && (
<>
<RectangleSkeleton
className="rectangle-loader"
width={"368px"}
height={"32px"}
/>
<RectangleSkeleton width={"184px"} height={"20px"} />
</>
)}
</StyledExternalLink>
<StyledButtons>
<RectangleSkeleton width={"100%"} height={"40px"} />
<RectangleSkeleton width={"100%"} height={"40px"} />
</StyledButtons>
</StyledContainer>
);
};
SharingPanelLoaderModal.propTypes = {
id: PropTypes.string,
className: PropTypes.string,
style: PropTypes.object,
};
SharingPanelLoaderModal.defaultProps = {
id: undefined,
className: undefined,
style: undefined,
};
export default SharingPanelLoaderModal;

View File

@ -1,21 +0,0 @@
import React from "react";
import ContentLoader from "react-content-loader";
import { LOADER_STYLE } from "@docspace/shared/constants";
const TextLoader = (props) => (
<ContentLoader
speed={2}
width={174}
height={23}
viewBox="0 0 174 23"
backgroundColor={LOADER_STYLE.backgroundColor}
foregroundColor={LOADER_STYLE.foregroundColor}
backgroundOpacity={LOADER_STYLE.backgroundOpacity}
foregroundOpacity={LOADER_STYLE.foregroundOpacity}
{...props}
>
<rect x="0" y="0" rx="0" ry="0" width="174" height="23" />
</ContentLoader>
);
export default TextLoader;

View File

@ -1,26 +0,0 @@
# Tree Folder Loader
Component that displays tree folder loader
### Usage
```js
import Loaders from "@docspace/common/components/Loaders";
```
```jsx
<Loaders.TreeFolders />
```
### Properties
| Props | Type | Required | Values | Default | Description |
| ------------------- | :------: | :------: | :----: | :-------: | ------------------------------------------------ |
| `title` | `string` | - | - | `` | It's used to describe what element it is. |
| `borderRadius` | `string` | - | - | `3` | Sets the corners rounding |
| `backgroundColor` | `string` | - | - | `#000000` | Used as background of animation |
| `foregroundColor` | `string` | - | - | `#000000` | Used as the foreground of animation |
| `backgroundOpacity` | `number` | - | - | 0.2 | Background opacity (0 = transparent, 1 = opaque) |
| `foregroundOpacity` | `number` | - | - | 0.15 | Animation opacity (0 = transparent, 1 = opaque) |
| `speed` | `number` | - | - | 2 | Animation speed in seconds |
| `animate` | `bool` | - | - | true | Opt-out of animations |

View File

@ -1,27 +0,0 @@
import styled from "styled-components";
import { desktop } from "@docspace/shared/utils";
const StyledTreeFolder = styled.div`
width: 100%;
display: grid;
grid-template-columns: 8px 1fr;
grid-template-rows: 1fr;
grid-column-gap: 6px;
margin-bottom: 24px;
`;
const StyledContainer = styled.div`
margin-top: 48px;
width: 100%;
`;
const StyledBox = styled.div`
@media ${desktop} {
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `margin-left: 8px;`
: `margin-right: 8px;`}
}
`;
export { StyledTreeFolder, StyledContainer, StyledBox };

View File

@ -1,71 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import {
StyledTreeFolder,
StyledContainer,
StyledBox,
} from "./StyledTreeFolderLoader";
import { RectangleSkeleton } from "@docspace/shared/skeletons";
import TreeNodeLoader from "../TreeNodeLoader";
const TreeFolderLoader = ({ id, className, style, ...rest }) => {
const {
title,
borderRadius,
backgroundColor,
foregroundColor,
backgroundOpacity,
foregroundOpacity,
speed,
animate,
} = rest;
return (
<StyledBox id={id} className={className} style={style}>
<StyledTreeFolder>
<TreeNodeLoader {...rest} />
<TreeNodeLoader {...rest} />
<TreeNodeLoader {...rest} />
</StyledTreeFolder>
<StyledTreeFolder>
<TreeNodeLoader {...rest} />
<TreeNodeLoader {...rest} />
<TreeNodeLoader {...rest} />
</StyledTreeFolder>
<StyledTreeFolder>
<TreeNodeLoader {...rest} />
</StyledTreeFolder>
<StyledContainer>
<RectangleSkeleton
title={title}
width="100%"
height="48"
borderRadius={borderRadius}
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}
backgroundOpacity={backgroundOpacity}
foregroundOpacity={foregroundOpacity}
speed={speed}
animate={animate}
/>
</StyledContainer>
</StyledBox>
);
};
TreeFolderLoader.propTypes = {
id: PropTypes.string,
className: PropTypes.string,
style: PropTypes.object,
};
TreeFolderLoader.defaultProps = {
id: undefined,
className: undefined,
style: undefined,
};
export default TreeFolderLoader;

View File

@ -1,40 +0,0 @@
import React from "react";
import { storiesOf } from "@storybook/react";
import {
withKnobs,
text,
boolean,
color,
number,
} from "@storybook/addon-knobs/react";
import Section from "../../../../.storybook/decorators/section";
import Loaders from "..";
import { LOADER_STYLE } from "@docspace/shared/constants";
import withReadme from "storybook-readme/with-readme";
import Readme from "./README.md";
storiesOf("Components|Loaders", module)
.addDecorator(withKnobs)
.addDecorator(withReadme(Readme))
.add("tree folder loader", () => (
<Section>
<h1>Tree Folder Loader</h1>
<Loaders.TreeFolders
title={text("title", LOADER_STYLE.title)}
borderRadius={text("borderRadius", "3")}
backgroundColor={color("backgroundColor", LOADER_STYLE.backgroundColor)}
foregroundColor={color("foregroundColor", LOADER_STYLE.foregroundColor)}
backgroundOpacity={number(
"backgroundOpacity",
LOADER_STYLE.backgroundOpacity
)}
foregroundOpacity={number(
"foregroundOpacity",
LOADER_STYLE.foregroundOpacity
)}
speed={number("speed", LOADER_STYLE.speed)}
animate={boolean("animate", LOADER_STYLE.animate)}
/>
</Section>
));

View File

@ -1 +0,0 @@
export default from "./TreeFolderLoader";

View File

@ -1,62 +0,0 @@
import React from "react";
import { RectangleSkeleton } from "@docspace/shared/skeletons";
import { CircleSkeleton } from "@docspace/shared/skeletons";
const TreeNodeLoader = ({
title,
borderRadius,
backgroundColor,
foregroundColor,
backgroundOpacity,
foregroundOpacity,
speed,
animate,
withRectangle = false,
}) => {
return (
<>
<CircleSkeleton
title={title}
height="32"
radius="3"
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}
backgroundOpacity={backgroundOpacity}
foregroundOpacity={foregroundOpacity}
speed={speed}
animate={animate}
/>
{withRectangle && (
<RectangleSkeleton
title={title}
width="16"
height="16"
borderRadius={borderRadius}
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}
backgroundOpacity={backgroundOpacity}
foregroundOpacity={foregroundOpacity}
speed={speed}
animate={animate}
className="tree-node-loader_additional-rectangle"
/>
)}
<RectangleSkeleton
title={title}
width="100%"
height="24"
borderRadius={borderRadius}
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}
backgroundOpacity={backgroundOpacity}
foregroundOpacity={foregroundOpacity}
speed={speed}
animate={animate}
/>
</>
);
};
export default TreeNodeLoader;

View File

@ -1 +0,0 @@
export default from "./TreeNodeLoader";

View File

@ -1,12 +0,0 @@
import styled from "styled-components";
const StyledTreeSettingsLoader = styled.div`
width: 90%;
display: grid;
grid-template-columns: 8px 1fr;
grid-template-rows: 1fr;
grid-column-gap: 6px;
margin: 24px 0;
`;
export default StyledTreeSettingsLoader;

View File

@ -1,28 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import StyledTreeSettingsLoader from "./StyledTreeSettingsLoader";
import TreeNodeLoader from "../TreeNodeLoader";
const TreeSettingsLoader = ({ id, className, style, ...rest }) => {
return (
<div id={id} className={className} style={style}>
<StyledTreeSettingsLoader>
<TreeNodeLoader {...rest} />
</StyledTreeSettingsLoader>
</div>
);
};
TreeSettingsLoader.propTypes = {
id: PropTypes.string,
className: PropTypes.string,
style: PropTypes.object,
};
TreeSettingsLoader.defaultProps = {
id: undefined,
className: undefined,
style: undefined,
};
export default TreeSettingsLoader;

View File

@ -1 +0,0 @@
export default from "./TreeSettingsLoader";

View File

@ -1,31 +0,0 @@
import TreeFolders from "./TreeFolderLoader";
import NewTreeFolders from "./NewTreeFolderLoader";
import TreeSettingsLoader from "./TreeSettingsLoader";
import Text from "./TextLoader";
import Group from "./GroupLoader";
import DialogLoader from "./DialogLoader";
import DialogAsideLoader from "./DialogAsideLoader";
import SharingPanelLoader from "./SharingPanelLoader";
import SharingPanelLoaderModal from "./SharingPanelLoader/modal";
import EmptyContainerLoader from "./EmptyContainerLoader/EmptyContainerLoader";
export default {
TreeFolders,
TreeSettingsLoader,
Text,
Group,
DialogLoader,
DialogAsideLoader,
NewTreeFolders,
SharingPanelLoader,
SharingPanelLoaderModal,
EmptyContainerLoader,
};

View File

@ -1,6 +0,0 @@
export { default as PublicRoute } from "./PublicRoute";
export { default as ExternalRedirect } from "./ExternalRedirect";
export { default as AdvancedSelector } from "./AdvancedSelector";
export { default as Section } from "./Section";
export { default as FilterInput } from "./FilterInput";
export { default as SystemThemeDetector } from "./SystemThemeDetector";

View File

@ -1,20 +0,0 @@
type TFuncType = (key: string) => string;
type HTMLElementEvent<T extends HTMLElement> = Event & {
target: T;
};
interface IProvider {
linked: boolean;
provider: string;
url: string;
}
type ProvidersType = IProvider[];
interface Window {
zESettings?: any;
zE?: {
apply: Function;
};
}

View File

@ -1,7 +0,0 @@
export { default as api } from "./api";
export { default as store } from "./store";
export { default as history } from "./history";
export * from "./components";
export * as constants from "./constants";
export * as utils from "./utils";
export * from "./desktop";

View File

@ -1,50 +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": {
"@welldone-software/why-did-you-render": "^6.2.3"
}
}