Merge branch 'feature/workspaces' of github.com:ONLYOFFICE/AppServer into feature/workspaces
This commit is contained in:
commit
9362f3cd2d
@ -7,6 +7,7 @@ import {
|
||||
StyledAlertIcon,
|
||||
StyledCircleWrap,
|
||||
StyledCircle,
|
||||
IconBox,
|
||||
} from "./StyledFloatingButton";
|
||||
|
||||
import ButtonUploadIcon from "../../../../public/images/button.upload.react.svg";
|
||||
@ -40,18 +41,19 @@ const FloatingButton = ({ id, className, style, ...rest }) => {
|
||||
</div>
|
||||
|
||||
<StyledFloatingButton>
|
||||
{icon == "upload" ? (
|
||||
<ButtonUploadIcon />
|
||||
) : icon == "file" ? (
|
||||
<ButtonFileIcon />
|
||||
) : icon == "trash" ? (
|
||||
<ButtonTrashIcon />
|
||||
) : icon == "move" ? (
|
||||
<ButtonMoveIcon />
|
||||
) : (
|
||||
<ButtonDuplicateIcon />
|
||||
)}
|
||||
|
||||
<IconBox>
|
||||
{icon == "upload" ? (
|
||||
<ButtonUploadIcon />
|
||||
) : icon == "file" ? (
|
||||
<ButtonFileIcon />
|
||||
) : icon == "trash" ? (
|
||||
<ButtonTrashIcon />
|
||||
) : icon == "move" ? (
|
||||
<ButtonMoveIcon />
|
||||
) : (
|
||||
<ButtonDuplicateIcon />
|
||||
)}
|
||||
</IconBox>
|
||||
<StyledAlertIcon>
|
||||
{alert ? <StyledButtonAlertIcon size="medium" /> : <></>}
|
||||
</StyledAlertIcon>
|
||||
|
@ -55,12 +55,15 @@ const StyledFloatingButton = styled.div`
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.13);
|
||||
line-height: 46px;
|
||||
text-align: center;
|
||||
margin: 3px;
|
||||
position: absolute;
|
||||
`;
|
||||
|
||||
const IconBox = styled.div`
|
||||
padding-top: 12px;
|
||||
`;
|
||||
|
||||
const StyledAlertIcon = styled.div`
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
@ -74,4 +77,5 @@ export {
|
||||
StyledCircle,
|
||||
StyledFloatingButton,
|
||||
StyledAlertIcon,
|
||||
IconBox,
|
||||
};
|
||||
|
@ -33,6 +33,21 @@ module.exports = {
|
||||
"../loader/*.stories.@(js|mdx)",
|
||||
"../main-button/*.stories.@(js|mdx)",
|
||||
"../modal-dialog/*.stories.@(js|mdx)",
|
||||
"../paging/*.stories.@(js|mdx)",
|
||||
"../password-input/*.stories.@(js|mdx)",
|
||||
"../progress-bar/*.stories.@(js|mdx)",
|
||||
"../radio-button/*.stories.@(js|mdx)",
|
||||
"../radio-button-group/*.stories.@(js|mdx)",
|
||||
"../request-loader/*.stories.@(js|mdx)",
|
||||
"../row/*.stories.@(js|mdx)",
|
||||
"../row-container/*.stories.@(js|mdx)",
|
||||
"../row-content/*.stories.@(js|mdx)",
|
||||
"../save-cancel-buttons/*.stories.@(js|mdx)",
|
||||
"../scrollbar/*.stories.@(js|mdx)",
|
||||
"../search-input/*.stories.@(js|mdx)",
|
||||
"../selected-item/*.stories.@(js|mdx)",
|
||||
"../selector-add-button/*.stories.@(js|mdx)",
|
||||
"../social-button/*.stories.@(js|mdx)",
|
||||
],
|
||||
addons: [
|
||||
"@storybook/addon-links",
|
||||
|
@ -1,4 +0,0 @@
|
||||
import Enzyme from "enzyme";
|
||||
import Adapter from "enzyme-adapter-react-16";
|
||||
|
||||
Enzyme.configure({ adapter: new Adapter() });
|
@ -56,18 +56,6 @@
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-values": "^0.3.3",
|
||||
"rollup": "^1.32.1",
|
||||
"rollup-plugin-babel": "^4.4.0",
|
||||
"rollup-plugin-cleanup": "^3.2.1",
|
||||
"rollup-plugin-commonjs": "^10.1.0",
|
||||
"rollup-plugin-copy": "^3.3.0",
|
||||
"rollup-plugin-generate-package-json": "^3.2.0",
|
||||
"rollup-plugin-json": "^4.0.0",
|
||||
"rollup-plugin-node-resolve": "^5.2.0",
|
||||
"rollup-plugin-peer-deps-external": "^2.2.4",
|
||||
"rollup-plugin-postcss": "^2.9.0",
|
||||
"rollup-plugin-replace": "^2.2.0",
|
||||
"rollup-plugin-url": "^3.0.1",
|
||||
"storybook-readme": "^5.0.9",
|
||||
"styled-components": "^5.2.1",
|
||||
"svg-inline-loader": "^0.8.2"
|
||||
|
@ -89,29 +89,37 @@ const Paging = (props) => {
|
||||
};
|
||||
|
||||
Paging.propTypes = {
|
||||
/** Label for previous button */
|
||||
previousLabel: PropTypes.string,
|
||||
/** Label for next button */
|
||||
nextLabel: PropTypes.string,
|
||||
|
||||
/** Action for previous button */
|
||||
previousAction: PropTypes.func,
|
||||
/** Action for next button */
|
||||
nextAction: PropTypes.func,
|
||||
|
||||
/** Set previous button disabled */
|
||||
disablePrevious: PropTypes.bool,
|
||||
/** Set next button disabled */
|
||||
disableNext: PropTypes.bool,
|
||||
disableHover: PropTypes.bool,
|
||||
|
||||
/** Initial value for pageItems */
|
||||
selectedPageItem: PropTypes.object,
|
||||
/** Initial value for countItems */
|
||||
selectedCountItem: PropTypes.object,
|
||||
|
||||
onSelectPage: PropTypes.func,
|
||||
onSelectCount: PropTypes.func,
|
||||
|
||||
/** Paging combo box items */
|
||||
pageItems: PropTypes.array,
|
||||
/** Items per page combo box items */
|
||||
countItems: PropTypes.array,
|
||||
|
||||
/** Indicates opening direction of combo box */
|
||||
openDirection: PropTypes.oneOf(["bottom", "top"]),
|
||||
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
|
||||
showCountItem: PropTypes.bool.isRequired,
|
||||
|
@ -1,73 +1,134 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import {
|
||||
withKnobs,
|
||||
text,
|
||||
boolean,
|
||||
select,
|
||||
number,
|
||||
} from "@storybook/addon-knobs/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import Paging from ".";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Paging from "./";
|
||||
|
||||
storiesOf("Components|Paging", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("base", () => {
|
||||
const createPageItems = (count) => {
|
||||
let pageItems = [];
|
||||
for (let i = 1; i <= count; i++) {
|
||||
pageItems.push({
|
||||
key: i,
|
||||
label: i + " of " + count,
|
||||
});
|
||||
}
|
||||
return pageItems;
|
||||
};
|
||||
|
||||
const countItems = [
|
||||
{
|
||||
key: 25,
|
||||
label: "25 per page",
|
||||
export default {
|
||||
title: "Components/Paging",
|
||||
component: Paging,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: "Paging is used to navigate med content pages",
|
||||
},
|
||||
{
|
||||
key: 50,
|
||||
label: "50 per page",
|
||||
},
|
||||
{
|
||||
key: 100,
|
||||
label: "100 per page",
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
onSelectPage: { action: "onSelectPage" },
|
||||
onSelectCount: { action: "onSelectCount" },
|
||||
previousAction: { action: "onPrevious" },
|
||||
nextAction: { action: "onNext" },
|
||||
selectedCount: {
|
||||
control: { type: "select", options: [25, 50, 100] },
|
||||
description: "Property for story",
|
||||
},
|
||||
pageCount: { description: "Property for story" },
|
||||
displayItems: { description: "Property for story" },
|
||||
displayCount: { description: "Property for story" },
|
||||
},
|
||||
};
|
||||
|
||||
const displayItems = boolean("Display pageItems", true);
|
||||
const displayCount = boolean("Display countItems", true);
|
||||
const selectedCount = select("selectedCount", [25, 50, 100], 100);
|
||||
const pageCount = number("Count of pages", 10);
|
||||
const pageItems = createPageItems(pageCount);
|
||||
const selectedPageItem = pageItems[0];
|
||||
const selectedCountItem = countItems[0];
|
||||
const createPageItems = (count) => {
|
||||
let pageItems = [];
|
||||
for (let i = 1; i <= count; i++) {
|
||||
pageItems.push({
|
||||
key: i,
|
||||
label: i + " of " + count,
|
||||
});
|
||||
}
|
||||
return pageItems;
|
||||
};
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<Paging
|
||||
previousLabel={text("previousLabel", "Previous")}
|
||||
nextLabel={text("nextLabel", "Next")}
|
||||
pageItems={displayItems ? pageItems : undefined}
|
||||
selectedPageItem={selectedPageItem}
|
||||
selectedCountItem={selectedCountItem}
|
||||
countItems={displayCount ? countItems : undefined}
|
||||
disablePrevious={boolean("disablePrevious", false)}
|
||||
disableNext={boolean("disableNext", false)}
|
||||
previousAction={() => console.log("Prev")}
|
||||
nextAction={() => console.log("Next")}
|
||||
openDirection="bottom"
|
||||
selectedCount={selectedCount}
|
||||
onSelectPage={(a) => console.log(a)}
|
||||
onSelectCount={(a) => console.log(a)}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
const countItems = [
|
||||
{
|
||||
key: 25,
|
||||
label: "25 per page",
|
||||
},
|
||||
{
|
||||
key: 50,
|
||||
label: "50 per page",
|
||||
},
|
||||
{
|
||||
key: 100,
|
||||
label: "100 per page",
|
||||
},
|
||||
];
|
||||
|
||||
const selectedCountPageHandler = (count) => {
|
||||
return countItems.filter((item) => {
|
||||
if (item.key === count) {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const Template = ({
|
||||
pageCount,
|
||||
displayItems,
|
||||
displayCount,
|
||||
nextAction,
|
||||
previousAction,
|
||||
onSelectPage,
|
||||
onSelectCount,
|
||||
selectedCount,
|
||||
...args
|
||||
}) => {
|
||||
const pageItems = createPageItems(pageCount);
|
||||
const [selectedPageItem, setSelectedPageItems] = useState(pageItems[0]);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedPageItems(pageItems[0]);
|
||||
}, [pageCount]);
|
||||
|
||||
const onSelectPageNextHandler = () => {
|
||||
const currentPage = pageItems.filter(
|
||||
(item) => item.key === selectedPageItem.key + 1
|
||||
);
|
||||
if (currentPage[0]) setSelectedPageItems(currentPage[0]);
|
||||
};
|
||||
|
||||
const onSelectPagePrevHandler = () => {
|
||||
const currentPage = pageItems.filter(
|
||||
(item) => item.key === selectedPageItem.key - 1
|
||||
);
|
||||
if (currentPage[0]) setSelectedPageItems(currentPage[0]);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ height: "100px" }}>
|
||||
<Paging
|
||||
{...args}
|
||||
pageItems={displayItems ? pageItems : null}
|
||||
countItems={displayCount ? countItems : null}
|
||||
previousAction={() => {
|
||||
previousAction("Prev");
|
||||
onSelectPagePrevHandler();
|
||||
}}
|
||||
nextAction={() => {
|
||||
onSelectPageNextHandler();
|
||||
nextAction("Next");
|
||||
}}
|
||||
onSelectPage={(a) => onSelectPage(a)}
|
||||
onSelectCount={(a) => onSelectCount(a)}
|
||||
selectedPageItem={selectedPageItem}
|
||||
selectedCountItem={selectedCountPageHandler(selectedCount)[0]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
previousLabel: "Previous",
|
||||
nextLabel: "Next",
|
||||
displayItems: true,
|
||||
displayCount: true,
|
||||
disablePrevious: false,
|
||||
disableNext: false,
|
||||
openDirection: "bottom",
|
||||
selectedCount: 100,
|
||||
pageCount: 10,
|
||||
selectedCountItem: {
|
||||
key: 100,
|
||||
label: "100 per page",
|
||||
},
|
||||
selectedPageItem: { key: 1, label: "1 of 10" },
|
||||
};
|
||||
|
@ -48,11 +48,13 @@ class PasswordInput extends React.Component {
|
||||
};
|
||||
|
||||
onBlur = (e) => {
|
||||
e.persist();
|
||||
this.hideTooltip();
|
||||
if (this.props.onBlur) this.props.onBlur(e);
|
||||
};
|
||||
|
||||
onKeyDown = (e) => {
|
||||
e.persist();
|
||||
if (this.props.onKeyDown) this.props.onKeyDown(e);
|
||||
};
|
||||
|
||||
@ -469,52 +471,73 @@ class PasswordInput extends React.Component {
|
||||
}
|
||||
|
||||
PasswordInput.propTypes = {
|
||||
/** Allows you to set the component id */
|
||||
id: PropTypes.string,
|
||||
/** Allows you to set the component auto-complete */
|
||||
autoComplete: PropTypes.string,
|
||||
/** It is necessary for correct display of values inside input */
|
||||
inputType: PropTypes.oneOf(["text", "password"]),
|
||||
/** Input name */
|
||||
inputName: PropTypes.string,
|
||||
/** Required to associate password field with email field */
|
||||
emailInputName: PropTypes.string,
|
||||
/** Input value */
|
||||
inputValue: PropTypes.string,
|
||||
/** Will be triggered whenever an PasswordInput typing */
|
||||
onChange: PropTypes.func,
|
||||
onKeyDown: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
/** If you need to set input width manually */
|
||||
inputWidth: PropTypes.string,
|
||||
hasError: PropTypes.bool,
|
||||
hasWarning: PropTypes.bool,
|
||||
placeholder: PropTypes.string,
|
||||
tabIndex: PropTypes.number,
|
||||
maxLength: PropTypes.number,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
|
||||
/** Set input disabled */
|
||||
isDisabled: PropTypes.bool,
|
||||
size: PropTypes.oneOf(["base", "middle", "big", "huge", "large"]),
|
||||
scale: PropTypes.bool,
|
||||
|
||||
/** Allows to hide NewPasswordButton */
|
||||
hideNewPasswordButton: PropTypes.bool,
|
||||
/** Allows to hide Tooltip */
|
||||
isDisableTooltip: PropTypes.bool,
|
||||
/** Allows to show text Tooltip */
|
||||
isTextTooltipVisible: PropTypes.bool,
|
||||
|
||||
/** Translation of text for copying email data and password */
|
||||
clipActionResource: PropTypes.string,
|
||||
/** Text translation email to copy */
|
||||
clipEmailResource: PropTypes.string,
|
||||
/** Text translation password to copy */
|
||||
clipPasswordResource: PropTypes.string,
|
||||
/** Text translation copy action to copy */
|
||||
clipCopiedResource: PropTypes.string,
|
||||
|
||||
/** Text translation tooltip */
|
||||
tooltipPasswordTitle: PropTypes.string,
|
||||
/** Password text translation is long tooltip */
|
||||
tooltipPasswordLength: PropTypes.string,
|
||||
/** Digit text translation tooltip */
|
||||
tooltipPasswordDigits: PropTypes.string,
|
||||
/** Capital text translation tooltip */
|
||||
tooltipPasswordCapital: PropTypes.string,
|
||||
/** Special text translation tooltip */
|
||||
tooltipPasswordSpecial: PropTypes.string,
|
||||
|
||||
/** Set of special characters for password generator and validator */
|
||||
generatorSpecial: PropTypes.string,
|
||||
NewPasswordButtonVisible: PropTypes.bool,
|
||||
/** Set of settings for password generator and validator */
|
||||
passwordSettings: PropTypes.object.isRequired,
|
||||
|
||||
/** Will be triggered whenever an PasswordInput typing, return bool value */
|
||||
onValidateInput: PropTypes.func,
|
||||
/** Will be triggered if you press copy button, return formatted value */
|
||||
onCopyToClipboard: PropTypes.func,
|
||||
|
||||
tooltipOffsetLeft: PropTypes.number,
|
||||
|
||||
/** Set simple view of password input (without tooltips, password progress bar and several additional buttons (copy and generate password) */
|
||||
simpleView: PropTypes.bool,
|
||||
};
|
||||
|
||||
|
@ -1,83 +1,97 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import { StringValue } from "react-values";
|
||||
import { withKnobs, boolean } from "@storybook/addon-knobs/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import PasswordInput from ".";
|
||||
import TextInput from "../text-input";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
|
||||
storiesOf("Components|Input", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("password input", () => {
|
||||
const isDisabled = boolean("isDisabled", false);
|
||||
const settingsUpperCase = boolean("settingsUpperCase", false);
|
||||
const settingsDigits = boolean("settingsDigits", false);
|
||||
const settingsSpecSymbols = boolean("settingsSpecSymbols", false);
|
||||
const simpleView = boolean("simpleView", false);
|
||||
const hideNewPasswordButton = boolean("hideNewPasswordButton", false);
|
||||
const isDisableTooltip = boolean("isDisableTooltip", false);
|
||||
const isTextTooltipVisible = boolean("isTextTooltipVisible", false);
|
||||
const Template = ({
|
||||
settingMinLength,
|
||||
settingsUpperCase,
|
||||
settingsDigits,
|
||||
settingsSpecSymbols,
|
||||
tooltipPasswordLength,
|
||||
onChange,
|
||||
onValidateInput,
|
||||
onCopyToClipboard,
|
||||
...args
|
||||
}) => {
|
||||
const [value, setValue] = useState("");
|
||||
const [fakeSettings, setFakSettings] = useState();
|
||||
|
||||
const fakeSettings = {
|
||||
minLength: 6,
|
||||
useEffect(() => {
|
||||
setFakSettings({
|
||||
minLength: settingMinLength,
|
||||
upperCase: settingsUpperCase,
|
||||
digits: settingsDigits,
|
||||
specSymbols: settingsSpecSymbols,
|
||||
};
|
||||
});
|
||||
setValue("");
|
||||
}, [
|
||||
settingMinLength,
|
||||
settingsUpperCase,
|
||||
settingsDigits,
|
||||
settingsSpecSymbols,
|
||||
]);
|
||||
|
||||
const tooltipPasswordLength =
|
||||
"from " + fakeSettings.minLength + " to 30 characters";
|
||||
const onChangeHandler = (e) => {
|
||||
onChange(e.currentTarget.value);
|
||||
setValue(e.currentTarget.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<div style={{ height: "110px" }}></div>
|
||||
<TextInput
|
||||
name="demoEmailInput"
|
||||
size="base"
|
||||
isDisabled={isDisabled}
|
||||
isReadOnly={true}
|
||||
scale={true}
|
||||
value="demo@gmail.com"
|
||||
/>
|
||||
<br />
|
||||
<StringValue>
|
||||
{({ value, set }) => (
|
||||
<PasswordInput
|
||||
simpleView={simpleView}
|
||||
inputName="demoPasswordInput"
|
||||
emailInputName="demoEmailInput"
|
||||
inputValue={value}
|
||||
onChange={(e) => {
|
||||
set(e.target.value);
|
||||
}}
|
||||
clipActionResource="Copy e-mail and password"
|
||||
clipEmailResource="E-mail: "
|
||||
clipPasswordResource="Password: "
|
||||
clipCopiedResource="Copied"
|
||||
hideNewPasswordButton={hideNewPasswordButton}
|
||||
isDisableTooltip={isDisableTooltip}
|
||||
isTextTooltipVisible={isTextTooltipVisible}
|
||||
tooltipPasswordTitle="Password must contain:"
|
||||
tooltipPasswordLength={tooltipPasswordLength}
|
||||
tooltipPasswordDigits="digits"
|
||||
tooltipPasswordCapital="capital letters"
|
||||
tooltipPasswordSpecial="special characters (!@#$%^&*)"
|
||||
generatorSpecial="!@#$%^&*"
|
||||
passwordSettings={fakeSettings}
|
||||
isDisabled={isDisabled}
|
||||
placeholder="password"
|
||||
maxLength={30}
|
||||
onValidateInput={(a) => console.log(a)}
|
||||
onCopyToClipboard={(b) =>
|
||||
console.log("Data " + b + " copied to clipboard")
|
||||
}
|
||||
//tooltipOffsetLeft={150}
|
||||
/>
|
||||
)}
|
||||
</StringValue>
|
||||
</Section>
|
||||
);
|
||||
});
|
||||
const onValidateInputHandler = (e) => {
|
||||
onValidateInput(e);
|
||||
};
|
||||
|
||||
const onCopyToClipboardHandler = (e) => {
|
||||
onCopyToClipboard(`Data ${e} copied to clipboard`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ height: "110px", display: "grid", gridGap: "24px" }}>
|
||||
<TextInput
|
||||
name="demoEmailInput"
|
||||
size="base"
|
||||
isDisabled={args.isDisabled}
|
||||
isReadOnly={true}
|
||||
scale={true}
|
||||
value="demo@gmail.com"
|
||||
/>
|
||||
|
||||
<PasswordInput
|
||||
{...args}
|
||||
inputValue={value}
|
||||
onChange={onChangeHandler}
|
||||
tooltipPasswordLength={`${tooltipPasswordLength} ${settingMinLength}`}
|
||||
passwordSettings={fakeSettings}
|
||||
onValidateInput={onValidateInputHandler}
|
||||
onCopyToClipboard={onCopyToClipboardHandler}
|
||||
tooltipOffsetLeft={150}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const basic = Template.bind({});
|
||||
basic.args = {
|
||||
isDisabled: false,
|
||||
settingMinLength: 6,
|
||||
settingsUpperCase: false,
|
||||
settingsDigits: false,
|
||||
settingsSpecSymbols: false,
|
||||
simpleView: false,
|
||||
inputName: "demoPasswordInput",
|
||||
emailInputName: "demoEmailInput",
|
||||
hideNewPasswordButton: false,
|
||||
isDisableTooltip: false,
|
||||
isTextTooltipVisible: false,
|
||||
clipActionResource: "Copy e-mail and password",
|
||||
clipEmailResource: "E-mail: ",
|
||||
clipPasswordResource: "Password: ",
|
||||
clipCopiedResource: "Copied",
|
||||
tooltipPasswordTitle: "Password must contain:",
|
||||
tooltipPasswordLength: "minimum length: ",
|
||||
tooltipPasswordDigits: "digits",
|
||||
tooltipPasswordCapital: "capital letters",
|
||||
tooltipPasswordSpecial: "special characters (!@#$%^&*)",
|
||||
generatorSpecial: "!@#$%^&*",
|
||||
placeholder: "password",
|
||||
maxLength: 30,
|
||||
};
|
||||
|
@ -0,0 +1,63 @@
|
||||
import { Meta, Story, ArgsTable, Canvas } from "@storybook/addon-docs/blocks";
|
||||
|
||||
import PasswordInput from "./";
|
||||
import * as stories from "./password-input.stories.js";
|
||||
import InputBlock from "../input-block";
|
||||
|
||||
<Meta
|
||||
title="Components/PasswordInput"
|
||||
component={PasswordInput}
|
||||
subcomponents={{ InputBlock }}
|
||||
argTypes={{
|
||||
onChange: { action: "onChange" },
|
||||
onValidateInput: { action: "onValidateInput" },
|
||||
onCopyToClipboard: { action: "onCopyToClipboard" },
|
||||
onKeyDown: { onKeyDown: "onKeyDown" },
|
||||
}}
|
||||
/>
|
||||
|
||||
# PasswordInput
|
||||
|
||||
Password entry field with advanced capabilities for displaying, validation of correspondence and generation based on settings
|
||||
|
||||
<Canvas>
|
||||
<Story story={stories.basic} name="Default" />
|
||||
</Canvas>
|
||||
|
||||
### Properties
|
||||
|
||||
You can apply all the parameters of the InputBlock component to the component.
|
||||
|
||||
<ArgsTable story="Default" />
|
||||
|
||||
## Description
|
||||
|
||||
#### Object with settings:
|
||||
|
||||
```js
|
||||
{
|
||||
minLength: 6,
|
||||
upperCase: false,
|
||||
digits: false,
|
||||
specSymbols: false
|
||||
}
|
||||
```
|
||||
|
||||
Check for compliance with settings is carried out on fly. As you type in required number of characters, progress bar will fill up and when all conditions are met, the color will change from red to green.
|
||||
|
||||
Depending on screen width of device, input will change location of elements.
|
||||
|
||||
When setting focus to input, tooltip will be shown with progress in fulfilling conditions specified in settings. When unfocused, tooltip disappears.
|
||||
|
||||
When button is pressed, copy data will be copied to clipboard and copy action will be blocked for 2 seconds. In future, the button is unlocked.
|
||||
|
||||
If emailInputName parameter value is empty, copy action will be disabled.
|
||||
|
||||
#### passwordSettings properties
|
||||
|
||||
| Props | Type | Required | Values | Default | Description |
|
||||
| ------------- | :------: | :------: | :----: | :-----: | ------------------------------- |
|
||||
| `digits` | `bool` | ✅ | - | - | Must contain digits |
|
||||
| `minLength` | `number` | ✅ | - | - | Minimum password length |
|
||||
| `specSymbols` | `bool` | ✅ | - | - | Must contain special characters |
|
||||
| `upperCase` | `bool` | ✅ | - | - | Must contain uppercase letters |
|
@ -3,8 +3,7 @@ import PropTypes from "prop-types";
|
||||
|
||||
import DropDown from "../drop-down";
|
||||
import Link from "./link";
|
||||
import StyledProgressBar from "./styled-progress-bar"
|
||||
|
||||
import StyledProgressBar from "./styled-progress-bar";
|
||||
|
||||
const ProgressBar = (props) => {
|
||||
const { percent, label, dropDownContent, ...rest } = props;
|
||||
@ -62,8 +61,11 @@ const ProgressBar = (props) => {
|
||||
};
|
||||
|
||||
ProgressBar.propTypes = {
|
||||
/** Progress value. */
|
||||
percent: PropTypes.number.isRequired,
|
||||
/** Text in progress-bar. */
|
||||
label: PropTypes.string,
|
||||
/** Drop-down content. */
|
||||
dropDownContent: PropTypes.any,
|
||||
};
|
||||
|
||||
|
@ -1,18 +1,25 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import { withKnobs, number, text } from "@storybook/addon-knobs/react";
|
||||
import ProgressBar from "./";
|
||||
|
||||
storiesOf("Components|ProgressBar", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("base", () => (
|
||||
<ProgressBar
|
||||
style={{ marginTop: 16 }}
|
||||
label={text("label", "Uploading files: 20 of 100")}
|
||||
percent={number("value", 20)}
|
||||
dropDownContent={text("dropDownContent", "You content here")}
|
||||
/>
|
||||
));
|
||||
export default {
|
||||
title: "Components/ProgressBar",
|
||||
component: ProgressBar,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A container that displays a process or operation as a progress bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args) => {
|
||||
return <ProgressBar {...args} style={{ marginTop: 16 }} />;
|
||||
};
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
label: "Uploading files: 20 of 100",
|
||||
percent: 20,
|
||||
dropDownContent: "You content here",
|
||||
};
|
||||
|
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.97 12.91L1 6.94L2.94 5L6.97 9.03L13 3L14.94 4.94L6.97 12.91Z" fill="black"/>
|
||||
</svg>
|
After Width: | Height: | Size: 192 B |
@ -60,9 +60,13 @@ class RadioButtonGroup extends React.Component {
|
||||
}
|
||||
|
||||
RadioButtonGroup.propTypes = {
|
||||
/** Disabling all radiobutton in group */
|
||||
isDisabled: PropTypes.bool,
|
||||
/** Used as HTML `name` property for `<input>` tag. Used for identification RadioButtonGroup */
|
||||
name: PropTypes.string.isRequired,
|
||||
/** Allow you to handle clicking events on `<RadioButton />` component */
|
||||
onClick: PropTypes.func,
|
||||
/** Array of objects, contains props for each `<RadioButton />` component */
|
||||
options: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
value: PropTypes.string.isRequired,
|
||||
@ -70,14 +74,24 @@ RadioButtonGroup.propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
})
|
||||
).isRequired,
|
||||
/** Value of the selected radiobutton */
|
||||
selected: PropTypes.string.isRequired,
|
||||
/** Margin between radiobutton. If orientation `horizontal`, it is `margin-left`(apply for all radiobuttons,
|
||||
* except first), if orientation `vertical`, it is `margin-bottom`(apply for all radiobuttons, except last) */
|
||||
spacing: PropTypes.string,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Position of radiobuttons */
|
||||
orientation: PropTypes.oneOf(["horizontal", "vertical"]),
|
||||
/** Width of RadioButtonGroup container */
|
||||
width: PropTypes.string,
|
||||
/** Font size of link */
|
||||
fontSize: PropTypes.string,
|
||||
/** Font weight of link */
|
||||
fontWeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
};
|
||||
|
||||
|
@ -1,79 +1,100 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import RadioButtonGroup from ".";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import { withKnobs, text, boolean, select } from "@storybook/addon-knobs/react";
|
||||
import Readme from "./README.md";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import { optionsKnob as options } from "@storybook/addon-knobs";
|
||||
import RadioButtonGroup from "./";
|
||||
|
||||
storiesOf("Components|Input", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("radio button group", () => {
|
||||
const orientation = ["horizontal", "vertical"];
|
||||
const values = ["first", "second", "third"];
|
||||
const valuesMultiSelect = {
|
||||
radio1: "radio1",
|
||||
radio2: "radio2",
|
||||
radio3: "radio3",
|
||||
};
|
||||
export default {
|
||||
title: "Components/RadioButtonGroup",
|
||||
component: RadioButtonGroup,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: "RadioButtonGroup allow you to add group radiobutton",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
options: {
|
||||
control: {
|
||||
type: "multi-select",
|
||||
options: ["radio1", "radio2", "radio3"],
|
||||
},
|
||||
},
|
||||
onClick: {
|
||||
cation: "onClick",
|
||||
},
|
||||
labelFirst: {
|
||||
description: "Label for 1st radiobutton (only storybook)",
|
||||
control: "text",
|
||||
},
|
||||
labelSecond: {
|
||||
description: "Label for 2nd radiobutton (only storybook)",
|
||||
control: "text",
|
||||
},
|
||||
labelThird: {
|
||||
description: "Label for 3rd radiobutton (only storybook)",
|
||||
control: "text",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const optionsMultiSelect = options(
|
||||
"options",
|
||||
valuesMultiSelect,
|
||||
["radio1", "radio2"],
|
||||
{
|
||||
display: "multi-select",
|
||||
}
|
||||
);
|
||||
|
||||
let children = [];
|
||||
optionsMultiSelect.forEach(function (item) {
|
||||
const Template = ({
|
||||
options,
|
||||
onClick,
|
||||
labelFirst,
|
||||
labelSecond,
|
||||
labelThird,
|
||||
...args
|
||||
}) => {
|
||||
const values = ["first", "second", "third"];
|
||||
const updateOptions = (options) => {
|
||||
const updatedOptions = options.map((item) => {
|
||||
switch (item) {
|
||||
case "radio1":
|
||||
children.push({
|
||||
return {
|
||||
value: values[0],
|
||||
label: text("label 1", "First radiobtn"),
|
||||
});
|
||||
break;
|
||||
label: labelFirst,
|
||||
};
|
||||
case "radio2":
|
||||
children.push({
|
||||
return {
|
||||
value: values[1],
|
||||
label: text("label 2", "Second radiobtn"),
|
||||
});
|
||||
break;
|
||||
label: labelSecond,
|
||||
};
|
||||
case "radio3":
|
||||
children.push({
|
||||
return {
|
||||
value: values[2],
|
||||
label: text("label 3", "Third radiobtn"),
|
||||
});
|
||||
break;
|
||||
label: labelThird,
|
||||
};
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
return updatedOptions;
|
||||
};
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<>
|
||||
<RadioButtonGroup
|
||||
onClick={(e) => {
|
||||
action("onChange")(e);
|
||||
console.log("Value of selected radiobutton: ", e.target.value);
|
||||
}}
|
||||
orientation={select("orientation", orientation, "horizontal")}
|
||||
width={text("width", "100%")}
|
||||
isDisabled={boolean("isDisabled", false)}
|
||||
fontSize={text("fontSize", "13px")}
|
||||
fontWeight={text("fontWeight", "400")}
|
||||
selected={values[0]}
|
||||
spacing={text("spacing", "15px")}
|
||||
name={text("name", "group")}
|
||||
options={children}
|
||||
/>
|
||||
</>
|
||||
</Section>
|
||||
);
|
||||
});
|
||||
const updatedOptions = updateOptions(options);
|
||||
|
||||
return (
|
||||
<RadioButtonGroup
|
||||
{...args}
|
||||
options={updatedOptions}
|
||||
selected={updatedOptions[0].value}
|
||||
onClick={(e) => {
|
||||
onClick(e);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
orientation: "horizontal",
|
||||
width: "100%",
|
||||
isDisabled: false,
|
||||
fontSize: "13px",
|
||||
fontWeight: "400",
|
||||
spacing: "15px",
|
||||
name: "group",
|
||||
options: ["radio1", "radio3"],
|
||||
labelFirst: "First radiobtn",
|
||||
labelSecond: "Second radiobtn",
|
||||
labelThird: "Third radiobtn",
|
||||
};
|
||||
|
@ -78,19 +78,34 @@ class RadioButton extends React.Component {
|
||||
}
|
||||
|
||||
RadioButton.propTypes = {
|
||||
/** Used as HTML `checked` property for each `<input>` tag */
|
||||
isChecked: PropTypes.bool,
|
||||
/** Used as HTML `disabled` property for each `<input>` tag */
|
||||
isDisabled: PropTypes.bool,
|
||||
/** Name of the radiobutton. If missed, `value` will be used */
|
||||
label: PropTypes.string,
|
||||
/** Font size of link */
|
||||
fontSize: PropTypes.string,
|
||||
/** Font weight of link */
|
||||
fontWeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
/** Used as HTML `name` property for `<input>` tag. */
|
||||
name: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func,
|
||||
/** Allow you to handle clicking events on component */
|
||||
onClick: PropTypes.func,
|
||||
/** Used as HTML `value` property for `<input>` tag. Used for identification each radiobutton */
|
||||
value: PropTypes.string.isRequired,
|
||||
/** Margin between radiobutton. If orientation `horizontal`,
|
||||
* it is `margin-left`(apply for all radiobuttons, except first),
|
||||
* if orientation `vertical`, it is `margin-bottom`(apply for all radiobuttons, except last) */
|
||||
spacing: PropTypes.string,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Position of radiobuttons */
|
||||
orientation: PropTypes.oneOf(["horizontal", "vertical"]),
|
||||
};
|
||||
|
||||
|
@ -1,33 +1,40 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import RadioButton from ".";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import { withKnobs, text, boolean } from "@storybook/addon-knobs/react";
|
||||
import Readme from "./README.md";
|
||||
|
||||
storiesOf("Components|Input", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("radio button", () => {
|
||||
return (
|
||||
<Section>
|
||||
<RadioButton
|
||||
value={text("value", "value")}
|
||||
name={text("name", "name")}
|
||||
label={text("label", "Label")}
|
||||
fontSize={text("fontSize", "13px")}
|
||||
fontWeight={text("fontWeight", "400")}
|
||||
isDisabled={boolean("isDisabled", false)}
|
||||
isChecked={boolean("isChecked", false)}
|
||||
onClick={(e) => {
|
||||
window.__STORYBOOK_ADDONS.channel.emit("storybookjs/knobs/change", {
|
||||
name: "isChecked",
|
||||
value: e.target.checked,
|
||||
});
|
||||
console.log("onChange", e);
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
});
|
||||
export default {
|
||||
title: "Components/RadioButton",
|
||||
component: RadioButton,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: { component: "RadioButton allow you to add radiobutton" },
|
||||
},
|
||||
},
|
||||
argTypes: {},
|
||||
};
|
||||
|
||||
const Template = ({ isChecked, ...args }) => {
|
||||
const [checked, setIsChecked] = useState(isChecked);
|
||||
|
||||
useEffect(() => {
|
||||
setIsChecked(isChecked);
|
||||
}, [isChecked]);
|
||||
|
||||
const onChangeHandler = (e) => {
|
||||
setIsChecked(e.target.checked);
|
||||
};
|
||||
|
||||
return (
|
||||
<RadioButton {...args} isChecked={checked} onChange={onChangeHandler} />
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
value: "value",
|
||||
name: "name",
|
||||
label: "Label",
|
||||
fontSize: "13px",
|
||||
fontWeight: "400",
|
||||
isDisabled: false,
|
||||
isChecked: false,
|
||||
};
|
||||
|
@ -24,15 +24,25 @@ const RequestLoader = (props) => {
|
||||
};
|
||||
|
||||
RequestLoader.propTypes = {
|
||||
/** Visibility */
|
||||
visible: PropTypes.bool,
|
||||
/** CSS z-index */
|
||||
zIndex: PropTypes.number,
|
||||
/** Svg height and width value */
|
||||
loaderSize: PropTypes.string,
|
||||
/** Svg color */
|
||||
loaderColor: PropTypes.string,
|
||||
/** Svg aria-label and text label */
|
||||
label: PropTypes.string,
|
||||
/** Text label font size */
|
||||
fontSize: PropTypes.string,
|
||||
/** Text label font color */
|
||||
fontColor: PropTypes.string,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
};
|
||||
|
||||
|
@ -1,30 +1,34 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import {
|
||||
withKnobs,
|
||||
boolean,
|
||||
number,
|
||||
text,
|
||||
color,
|
||||
} from "@storybook/addon-knobs/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import RequestLoader from ".";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import RequestLoader from "./";
|
||||
|
||||
storiesOf("Components|Loaders", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("request-loader", () => (
|
||||
<Section>
|
||||
<RequestLoader
|
||||
visible={boolean("visible", true)}
|
||||
zIndex={number("zIndex", 256)}
|
||||
loaderSize={text("loaderSize", "16px")}
|
||||
loaderColor={color("loaderColor", "#999")}
|
||||
label={text("label", "Loading... Please wait...")}
|
||||
fontSize={text("fontSize", "12px")}
|
||||
fontColor={color("fontColor", "#999")}
|
||||
/>
|
||||
</Section>
|
||||
));
|
||||
export default {
|
||||
title: "Components/Loaders",
|
||||
component: RequestLoader,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"equestLoader component is used for displaying loading actions on a page",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
loaderColor: { control: "color" },
|
||||
fontColor: { control: "color" },
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args) => {
|
||||
return <RequestLoader {...args} />;
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
visible: true,
|
||||
zIndex: 256,
|
||||
loaderSize: "16px",
|
||||
loaderColor: "#999",
|
||||
label: "Loading... Please wait...",
|
||||
fontSize: "12px",
|
||||
fontColor: "#999",
|
||||
};
|
||||
|
@ -103,12 +103,19 @@ class RowContainer extends React.PureComponent {
|
||||
}
|
||||
|
||||
RowContainer.propTypes = {
|
||||
/** Height of one Row element. Required for scroll to work properly */
|
||||
itemHeight: PropTypes.number,
|
||||
/** Allows you to set fixed block height for Row */
|
||||
manualHeight: PropTypes.string,
|
||||
/** Child elements */
|
||||
children: PropTypes.any.isRequired,
|
||||
/** Use react-window for efficiently rendering large lists */
|
||||
useReactWindow: PropTypes.bool,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
};
|
||||
|
||||
|
@ -1,20 +1,28 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import RowContainer from ".";
|
||||
import Row from "../row";
|
||||
import RowContent from "../row-content";
|
||||
import Avatar from "../avatar";
|
||||
import Link from "../link";
|
||||
import SendClockIcon from "../../../../../public/images/send.clock.react.svg";
|
||||
import CatalogSpamIcon from "../../../../../public/images/catalog.spam.react.svg";
|
||||
import SendClockIcon from "../public/static/images/send.clock.react.svg";
|
||||
import CatalogSpamIcon from "../public/static/images/catalog.spam.react.svg";
|
||||
|
||||
export default {
|
||||
title: "Components/RowContainer",
|
||||
component: RowContainer,
|
||||
subcomponents: { Row, RowContent },
|
||||
parameters: {
|
||||
docs: { description: { component: "Container for Row component" } },
|
||||
},
|
||||
};
|
||||
|
||||
const getRndString = (n) =>
|
||||
Math.random()
|
||||
.toString(36)
|
||||
.substring(2, n + 2);
|
||||
|
||||
const getRndNumber = (a, b) => Math.floor(Math.random() * (b - a)) + a;
|
||||
|
||||
const getRndBool = () => Math.random() >= 0.5;
|
||||
|
||||
const fillFakeData = (n) => {
|
||||
@ -56,104 +64,93 @@ const fillFakeData = (n) => {
|
||||
|
||||
const fakeData = fillFakeData(20);
|
||||
|
||||
storiesOf("Components|RowContainer", module)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("base", () => {
|
||||
return (
|
||||
<Section>
|
||||
<RowContainer manualHeight="500px">
|
||||
{fakeData.map((user) => {
|
||||
const element = (
|
||||
<Avatar
|
||||
size="min"
|
||||
role={user.role}
|
||||
userName={user.userName}
|
||||
source={user.avatar}
|
||||
/>
|
||||
);
|
||||
const nameColor = user.status === "pending" ? "#A3A9AE" : "#333333";
|
||||
const sideInfoColor =
|
||||
user.status === "pending" ? "#D0D5DA" : "#A3A9AE";
|
||||
const Template = (args) => {
|
||||
return (
|
||||
<RowContainer {...args} manualHeight="500px">
|
||||
{fakeData.map((user) => {
|
||||
const element = (
|
||||
<Avatar
|
||||
size="min"
|
||||
role={user.role}
|
||||
userName={user.userName}
|
||||
source={user.avatar}
|
||||
/>
|
||||
);
|
||||
const nameColor = user.status === "pending" ? "#A3A9AE" : "#333333";
|
||||
const sideInfoColor = user.status === "pending" ? "#D0D5DA" : "#A3A9AE";
|
||||
|
||||
return (
|
||||
<Row
|
||||
key={user.id}
|
||||
status={user.status}
|
||||
checked={false}
|
||||
data={user}
|
||||
element={element}
|
||||
contextOptions={user.contextOptions}
|
||||
return (
|
||||
<Row
|
||||
key={user.id}
|
||||
status={user.status}
|
||||
checked={false}
|
||||
data={user}
|
||||
element={element}
|
||||
contextOptions={user.contextOptions}
|
||||
>
|
||||
<RowContent>
|
||||
<Link
|
||||
type="page"
|
||||
title={user.userName}
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color={nameColor}
|
||||
>
|
||||
<RowContent>
|
||||
<Link
|
||||
type="page"
|
||||
title={user.userName}
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color={nameColor}
|
||||
>
|
||||
{user.userName}
|
||||
</Link>
|
||||
<>
|
||||
{user.status === "pending" && (
|
||||
<SendClockIcon
|
||||
size="small"
|
||||
isfill={true}
|
||||
color="#3B72A7"
|
||||
/>
|
||||
)}
|
||||
{user.status === "disabled" && (
|
||||
<CatalogSpamIcon
|
||||
size="small"
|
||||
isfill={true}
|
||||
color="#3B72A7"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
{user.isHead ? (
|
||||
<Link
|
||||
containerWidth="120px"
|
||||
type="page"
|
||||
title="Head of department"
|
||||
fontSize="12px"
|
||||
color={sideInfoColor}
|
||||
>
|
||||
Head of department
|
||||
</Link>
|
||||
) : (
|
||||
<div></div>
|
||||
)}
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="action"
|
||||
title={user.department}
|
||||
fontSize="12px"
|
||||
color={sideInfoColor}
|
||||
>
|
||||
{user.department}
|
||||
</Link>
|
||||
<Link
|
||||
type="page"
|
||||
title={user.mobilePhone}
|
||||
fontSize="12px"
|
||||
color={sideInfoColor}
|
||||
>
|
||||
{user.mobilePhone}
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="180px"
|
||||
type="page"
|
||||
title={user.email}
|
||||
fontSize="12px"
|
||||
color={sideInfoColor}
|
||||
>
|
||||
{user.email}
|
||||
</Link>
|
||||
</RowContent>
|
||||
</Row>
|
||||
);
|
||||
})}
|
||||
</RowContainer>
|
||||
</Section>
|
||||
);
|
||||
});
|
||||
{user.userName}
|
||||
</Link>
|
||||
<>
|
||||
{user.status === "pending" && (
|
||||
<SendClockIcon size="small" isfill={true} color="#3B72A7" />
|
||||
)}
|
||||
{user.status === "disabled" && (
|
||||
<CatalogSpamIcon size="small" isfill={true} color="#3B72A7" />
|
||||
)}
|
||||
</>
|
||||
{user.isHead ? (
|
||||
<Link
|
||||
containerWidth="120px"
|
||||
type="page"
|
||||
title="Head of department"
|
||||
fontSize="12px"
|
||||
color={sideInfoColor}
|
||||
>
|
||||
Head of department
|
||||
</Link>
|
||||
) : (
|
||||
<div></div>
|
||||
)}
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="action"
|
||||
title={user.department}
|
||||
fontSize="12px"
|
||||
color={sideInfoColor}
|
||||
>
|
||||
{user.department}
|
||||
</Link>
|
||||
<Link
|
||||
type="page"
|
||||
title={user.mobilePhone}
|
||||
fontSize="12px"
|
||||
color={sideInfoColor}
|
||||
>
|
||||
{user.mobilePhone}
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="180px"
|
||||
type="page"
|
||||
title={user.email}
|
||||
fontSize="12px"
|
||||
color={sideInfoColor}
|
||||
>
|
||||
{user.email}
|
||||
</Link>
|
||||
</RowContent>
|
||||
</Row>
|
||||
);
|
||||
})}
|
||||
</RowContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
|
@ -113,12 +113,18 @@ const RowContent = (props) => {
|
||||
};
|
||||
|
||||
RowContent.propTypes = {
|
||||
/** Components displayed inside RowContent */
|
||||
children: PropTypes.node.isRequired,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** If you do not need SideElements */
|
||||
disableSideInfo: PropTypes.bool,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
/** Need for change side information color */
|
||||
sideColor: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
sectionWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
isMobile: PropTypes.bool,
|
||||
|
@ -1,287 +1,188 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import { BooleanValue } from "react-values";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import RowContent from ".";
|
||||
import React, { useState } from "react";
|
||||
import RowContent from "./";
|
||||
import Link from "../link";
|
||||
import Checkbox from "../checkbox";
|
||||
import SendClockIcon from "../../../../../public/images/send.clock.react.svg";
|
||||
import CatalogSpamIcon from "../../../../../public/images/catalog.spam.react.svg";
|
||||
storiesOf("Components|RowContent", module)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("base", () => {
|
||||
return (
|
||||
<Section>
|
||||
<h3>Base demo</h3>
|
||||
<div style={{ height: "16px" }}></div>
|
||||
<RowContent>
|
||||
<Link
|
||||
type="page"
|
||||
title="Demo"
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color="#333333"
|
||||
>
|
||||
Demo
|
||||
</Link>
|
||||
<>
|
||||
<SendClockIcon size="small" isfill={true} color="#3B72A7" />
|
||||
<CatalogSpamIcon size="small" isfill={true} color="#3B72A7" />
|
||||
</>
|
||||
<Link type="page" title="Demo" fontSize="12px" color="#A3A9AE">
|
||||
Demo
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="action"
|
||||
title="Demo"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
Demo
|
||||
</Link>
|
||||
<Link
|
||||
type="page"
|
||||
title="0 000 0000000"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
0 000 0000000
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="page"
|
||||
title="demo@demo.com"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
demo@demo.com
|
||||
</Link>
|
||||
</RowContent>
|
||||
<RowContent>
|
||||
<Link
|
||||
type="page"
|
||||
title="Demo Demo"
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color="#333333"
|
||||
>
|
||||
Demo Demo
|
||||
</Link>
|
||||
<>
|
||||
<CatalogSpamIcon size="small" isfill={true} color="#3B72A7" />
|
||||
</>
|
||||
<></>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="action"
|
||||
title="Demo Demo"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
Demo Demo
|
||||
</Link>
|
||||
<Link
|
||||
type="page"
|
||||
title="0 000 0000000"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
0 000 0000000
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="page"
|
||||
title="demo.demo@demo.com"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
demo.demo@demo.com
|
||||
</Link>
|
||||
</RowContent>
|
||||
<RowContent>
|
||||
<Link
|
||||
type="page"
|
||||
title="Demo Demo Demo"
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color="#333333"
|
||||
>
|
||||
Demo Demo Demo
|
||||
</Link>
|
||||
<></>
|
||||
<></>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="action"
|
||||
title="Demo Demo Demo"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
Demo Demo Demo
|
||||
</Link>
|
||||
<Link
|
||||
type="page"
|
||||
title="0 000 0000000"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
0 000 0000000
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="page"
|
||||
title="demo.demo.demo@demo.com"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
demo.demo.demo@demo.com
|
||||
</Link>
|
||||
</RowContent>
|
||||
<RowContent>
|
||||
<Link
|
||||
type="page"
|
||||
title="Demo Demo Demo Demo"
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color="#333333"
|
||||
>
|
||||
Demo Demo Demo Demo
|
||||
</Link>
|
||||
<>
|
||||
<SendClockIcon size="small" isfill={true} color="#3B72A7" />
|
||||
</>
|
||||
<Link type="page" title="Demo" fontSize="12px" color="#A3A9AE">
|
||||
Demo
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="action"
|
||||
title="Demo Demo Demo Demo"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
Demo Demo Demo Demo
|
||||
</Link>
|
||||
<Link
|
||||
type="page"
|
||||
title="0 000 0000000"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
0 000 0000000
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="page"
|
||||
title="demo.demo.demo.demo@demo.com"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
demo.demo.demo.demo@demo.com
|
||||
</Link>
|
||||
</RowContent>
|
||||
<div style={{ height: "36px" }}></div>
|
||||
<h3>Custom elements</h3>
|
||||
<div style={{ height: "16px" }}></div>
|
||||
<RowContent disableSideInfo={true}>
|
||||
<Link
|
||||
type="page"
|
||||
title="John Doe"
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color="#333333"
|
||||
>
|
||||
John Doe
|
||||
</Link>
|
||||
<></>
|
||||
<BooleanValue>
|
||||
{({ value, toggle }) => (
|
||||
<Checkbox
|
||||
id="1"
|
||||
name="sample"
|
||||
isChecked={value}
|
||||
onChange={(e) => {
|
||||
toggle(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</BooleanValue>
|
||||
<BooleanValue>
|
||||
{({ value, toggle }) => (
|
||||
<Checkbox
|
||||
id="2"
|
||||
name="sample"
|
||||
isChecked={value}
|
||||
onChange={(e) => {
|
||||
toggle(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</BooleanValue>
|
||||
<BooleanValue>
|
||||
{({ value, toggle }) => (
|
||||
<Checkbox
|
||||
id="3"
|
||||
name="sample"
|
||||
isChecked={value}
|
||||
onChange={(e) => {
|
||||
toggle(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</BooleanValue>
|
||||
<BooleanValue>
|
||||
{({ value, toggle }) => (
|
||||
<Checkbox
|
||||
id="4"
|
||||
name="sample"
|
||||
isChecked={value}
|
||||
onChange={(e) => {
|
||||
toggle(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</BooleanValue>
|
||||
<BooleanValue>
|
||||
{({ value, toggle }) => (
|
||||
<Checkbox
|
||||
id="5"
|
||||
name="sample"
|
||||
isChecked={value}
|
||||
onChange={(e) => {
|
||||
toggle(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</BooleanValue>
|
||||
<BooleanValue>
|
||||
{({ value, toggle }) => (
|
||||
<Checkbox
|
||||
id="6"
|
||||
name="sample"
|
||||
isChecked={value}
|
||||
onChange={(e) => {
|
||||
toggle(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</BooleanValue>
|
||||
<BooleanValue>
|
||||
{({ value, toggle }) => (
|
||||
<Checkbox
|
||||
id="7"
|
||||
name="sample"
|
||||
isChecked={value}
|
||||
onChange={(e) => {
|
||||
toggle(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</BooleanValue>
|
||||
</RowContent>
|
||||
</Section>
|
||||
);
|
||||
});
|
||||
import SendClockIcon from "../public/static/images/send.clock.react.svg";
|
||||
import CatalogSpamIcon from "../public/static/images/catalog.spam.react.svg";
|
||||
|
||||
const Template = (args) => {
|
||||
const [isChecked, setIsChecked] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<h3>Base demo</h3>
|
||||
<div style={{ height: "16px" }}></div>
|
||||
<RowContent {...args}>
|
||||
<Link
|
||||
type="page"
|
||||
title="Demo"
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color="#333333"
|
||||
>
|
||||
Demo
|
||||
</Link>
|
||||
<>
|
||||
<SendClockIcon size="small" isfill={true} color="#3B72A7" />
|
||||
<CatalogSpamIcon size="small" isfill={true} color="#3B72A7" />
|
||||
</>
|
||||
<Link type="page" title="Demo" fontSize="12px" color="#A3A9AE">
|
||||
Demo
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="action"
|
||||
title="Demo"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
Demo
|
||||
</Link>
|
||||
<Link type="page" title="0 000 0000000" fontSize="12px" color="#A3A9AE">
|
||||
0 000 0000000
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="page"
|
||||
title="demo@demo.com"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
demo@demo.com
|
||||
</Link>
|
||||
</RowContent>
|
||||
<RowContent>
|
||||
<Link
|
||||
type="page"
|
||||
title="Demo Demo"
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color="#333333"
|
||||
>
|
||||
Demo Demo
|
||||
</Link>
|
||||
<>
|
||||
<CatalogSpamIcon size="small" isfill={true} color="#3B72A7" />
|
||||
</>
|
||||
<></>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="action"
|
||||
title="Demo Demo"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
Demo Demo
|
||||
</Link>
|
||||
<Link type="page" title="0 000 0000000" fontSize="12px" color="#A3A9AE">
|
||||
0 000 0000000
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="page"
|
||||
title="demo.demo@demo.com"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
demo.demo@demo.com
|
||||
</Link>
|
||||
</RowContent>
|
||||
<RowContent>
|
||||
<Link
|
||||
type="page"
|
||||
title="Demo Demo Demo"
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color="#333333"
|
||||
>
|
||||
Demo Demo Demo
|
||||
</Link>
|
||||
<></>
|
||||
<></>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="action"
|
||||
title="Demo Demo Demo"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
Demo Demo Demo
|
||||
</Link>
|
||||
<Link type="page" title="0 000 0000000" fontSize="12px" color="#A3A9AE">
|
||||
0 000 0000000
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="page"
|
||||
title="demo.demo.demo@demo.com"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
demo.demo.demo@demo.com
|
||||
</Link>
|
||||
</RowContent>
|
||||
<RowContent>
|
||||
<Link
|
||||
type="page"
|
||||
title="Demo Demo Demo Demo"
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color="#333333"
|
||||
>
|
||||
Demo Demo Demo Demo
|
||||
</Link>
|
||||
<>
|
||||
<SendClockIcon size="small" isfill={true} color="#3B72A7" />
|
||||
</>
|
||||
<Link type="page" title="Demo" fontSize="12px" color="#A3A9AE">
|
||||
Demo
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="action"
|
||||
title="Demo Demo Demo Demo"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
Demo Demo Demo Demo
|
||||
</Link>
|
||||
<Link type="page" title="0 000 0000000" fontSize="12px" color="#A3A9AE">
|
||||
0 000 0000000
|
||||
</Link>
|
||||
<Link
|
||||
containerWidth="160px"
|
||||
type="page"
|
||||
title="demo.demo.demo.demo@demo.com"
|
||||
fontSize="12px"
|
||||
color="#A3A9AE"
|
||||
>
|
||||
demo.demo.demo.demo@demo.com
|
||||
</Link>
|
||||
</RowContent>
|
||||
<div style={{ height: "36px" }}></div>
|
||||
<h3>Custom elements</h3>
|
||||
<div style={{ height: "16px" }}></div>
|
||||
<RowContent disableSideInfo={true}>
|
||||
<Link
|
||||
type="page"
|
||||
title="John Doe"
|
||||
isBold={true}
|
||||
fontSize="15px"
|
||||
color="#333333"
|
||||
>
|
||||
John Doe
|
||||
</Link>
|
||||
<></>
|
||||
<Checkbox
|
||||
id="1"
|
||||
name="sample"
|
||||
isChecked={isChecked}
|
||||
onChange={(e) => {
|
||||
setIsChecked(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
</RowContent>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const basic = Template.bind({});
|
||||
|
@ -0,0 +1,28 @@
|
||||
import { Meta, Story, ArgsTable, Canvas } from "@storybook/addon-docs/blocks";
|
||||
|
||||
import RowContent from "./";
|
||||
import * as stories from "./row-content.stories.js";
|
||||
|
||||
<Meta title="Components/RowContent" component={RowContent} />
|
||||
|
||||
# RowContent
|
||||
|
||||
Required for formatted output of elements inside Row
|
||||
|
||||
<Canvas>
|
||||
<Story story={stories.basic} name="Default" />
|
||||
</Canvas>
|
||||
|
||||
<ArgsTable story="Default" />
|
||||
|
||||
## Description
|
||||
|
||||
To correctly display components inside RowContent, you must specify them in a certain order.
|
||||
|
||||
The first and second specified components will be interpreted as Main elements.
|
||||
First will be MainTitle and second MainIcons.
|
||||
All subsequent components will be located on the right and are considered SideElements.
|
||||
|
||||
**_Consider location of components in advance, since when viewing in tablet mode, the markup will shift SideElements to second line._**
|
||||
|
||||
Each not main child can take containerWidth property for task of width of child's container.
|
@ -125,19 +125,32 @@ class Row extends React.Component {
|
||||
}
|
||||
|
||||
Row.propTypes = {
|
||||
/** Required to host the Checkbox component. Its location is fixed and it is always the first.
|
||||
* If there is no value, the occupied space is distributed among the other child elements. */
|
||||
checked: PropTypes.bool,
|
||||
children: PropTypes.element,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
contentElement: PropTypes.any,
|
||||
/** Required for the width task of the ContextMenuButton component. */
|
||||
contextButtonSpacerWidth: PropTypes.string,
|
||||
/** Required to host the ContextMenuButton component. It is always located near the right border of the container,
|
||||
* regardless of the contents of the child elements. If there is no value, the occupied space is distributed among the other child elements. */
|
||||
contextOptions: PropTypes.array,
|
||||
/** Current row item information. */
|
||||
data: PropTypes.object,
|
||||
/** Required to host some component. It has a fixed order of location, if the Checkbox component is specified,
|
||||
* then it follows, otherwise it occupies the first position. If there is no value, the occupied space is distributed among the other child elements. */
|
||||
element: PropTypes.element,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
indeterminate: PropTypes.bool,
|
||||
/** shouldComponentUpdate function */
|
||||
needForUpdate: PropTypes.func,
|
||||
/** when selecting row element. Returns data value. */
|
||||
onSelect: PropTypes.func,
|
||||
selectItem: PropTypes.func,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
sectionWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
};
|
||||
|
@ -1,85 +1,109 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import { withKnobs, boolean, text, select } from "@storybook/addon-knobs/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import Row from ".";
|
||||
import Text from "../text";
|
||||
import Avatar from "../avatar";
|
||||
import ComboBox from "../combobox";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import CatalogFolderIcon from "../../../../../public/images/catalog.folder.react.svg";
|
||||
storiesOf("Components|Row", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("base", () => {
|
||||
const contextButton = boolean("contextButton", true);
|
||||
const checked = boolean("checkbox", true);
|
||||
const element = select("element", ["", "Avatar", "Icon", "ComboBox"], "");
|
||||
import CatalogFolderIcon from "../public/static/images/catalog.folder.react.svg";
|
||||
|
||||
const elementAvatar = (
|
||||
<Avatar size="min" role="user" userName="Demo Avatar" />
|
||||
);
|
||||
const elementIcon = <CatalogFolderIcon size="big" />;
|
||||
const elementComboBox = (
|
||||
<ComboBox
|
||||
options={[
|
||||
{
|
||||
key: 1,
|
||||
icon: "static/images/item.active.react.svg",
|
||||
label: "Open",
|
||||
},
|
||||
{ key: 2, icon: "CheckIcon", label: "Closed" },
|
||||
]}
|
||||
onSelect={(option) => console.log(option)}
|
||||
selectedOption={{
|
||||
key: 0,
|
||||
icon: "static/images/item.active.react.svg",
|
||||
label: "",
|
||||
}}
|
||||
scaled={false}
|
||||
size="content"
|
||||
isDisabled={false}
|
||||
/>
|
||||
);
|
||||
export default {
|
||||
title: "Components/Row",
|
||||
component: Row,
|
||||
parameters: {
|
||||
docs: { description: { component: "Displays content as row" } },
|
||||
},
|
||||
argTypes: {
|
||||
element: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["", "Avatar", "Icon", "ComboBox"],
|
||||
},
|
||||
},
|
||||
content: { control: "text" },
|
||||
onSelectComboBox: { action: "onSelectComboBox", table: { disable: true } },
|
||||
contextItemClick: { action: "contextItemClick", table: { disable: true } },
|
||||
checkbox: { description: "Disable checkbox" },
|
||||
},
|
||||
};
|
||||
|
||||
const checkedProps = checked ? { checked: false } : {};
|
||||
const getElementProps = (element) =>
|
||||
element === "Avatar"
|
||||
? { element: elementAvatar }
|
||||
: element === "Icon"
|
||||
? { element: elementIcon }
|
||||
: element === "ComboBox"
|
||||
? { element: elementComboBox }
|
||||
: {};
|
||||
const elementAvatar = <Avatar size="min" role="user" userName="Demo Avatar" />;
|
||||
const elementIcon = <CatalogFolderIcon size="big" />;
|
||||
|
||||
const elementProps = getElementProps(element);
|
||||
const renderElementComboBox = (onSelect) => (
|
||||
<ComboBox
|
||||
options={[
|
||||
{
|
||||
key: 1,
|
||||
icon: "static/images/item.active.react.svg",
|
||||
label: "Open",
|
||||
},
|
||||
{ key: 2, icon: "static/images/check.react.svg", label: "Closed" },
|
||||
]}
|
||||
onSelect={(option) => onSelect(option)}
|
||||
selectedOption={{
|
||||
key: 0,
|
||||
icon: "static/images/item.active.react.svg",
|
||||
label: "",
|
||||
}}
|
||||
scaled={false}
|
||||
size="content"
|
||||
isDisabled={false}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<Row
|
||||
key="1"
|
||||
{...checkedProps}
|
||||
{...elementProps}
|
||||
contextOptions={
|
||||
contextButton
|
||||
? [
|
||||
{
|
||||
key: "key1",
|
||||
label: "Edit",
|
||||
onClick: () => console.log("Context action: Edit"),
|
||||
},
|
||||
{
|
||||
key: "key2",
|
||||
label: "Delete",
|
||||
onClick: () => console.log("Context action: Delete"),
|
||||
},
|
||||
]
|
||||
: []
|
||||
}
|
||||
>
|
||||
<Text truncate={true}>{text("content", "Sample text")}</Text>
|
||||
</Row>
|
||||
</Section>
|
||||
);
|
||||
});
|
||||
const Template = ({
|
||||
element,
|
||||
contextButton,
|
||||
content,
|
||||
onSelectComboBox,
|
||||
contextItemClick,
|
||||
checkbox,
|
||||
checked,
|
||||
...args
|
||||
}) => {
|
||||
const getElementProps = (element) =>
|
||||
element === "Avatar"
|
||||
? { element: elementAvatar }
|
||||
: element === "Icon"
|
||||
? { element: elementIcon }
|
||||
: element === "ComboBox"
|
||||
? { element: renderElementComboBox(onSelectComboBox) }
|
||||
: {};
|
||||
|
||||
const elementProps = getElementProps(element);
|
||||
const checkedProps = checkbox ? { checked: checked } : {};
|
||||
return (
|
||||
<Row
|
||||
{...args}
|
||||
key="1"
|
||||
{...checkedProps}
|
||||
{...elementProps}
|
||||
contextOptions={
|
||||
contextButton
|
||||
? [
|
||||
{
|
||||
key: "key1",
|
||||
label: "Edit",
|
||||
onClick: () => contextItemClick("Context action: Edit"),
|
||||
},
|
||||
{
|
||||
key: "key2",
|
||||
label: "Delete",
|
||||
onClick: () => contextItemClick("Context action: Delete"),
|
||||
},
|
||||
]
|
||||
: []
|
||||
}
|
||||
>
|
||||
<Text truncate={true}>{content}</Text>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
contextButton: true,
|
||||
checked: true,
|
||||
element: "",
|
||||
content: "Sample text",
|
||||
checkbox: true,
|
||||
};
|
||||
|
@ -72,13 +72,21 @@ class SaveCancelButtons extends React.Component {
|
||||
}
|
||||
|
||||
SaveCancelButtons.propTypes = {
|
||||
/** Accepts css id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css class */
|
||||
className: PropTypes.string,
|
||||
/** Text reminding of unsaved changes */
|
||||
reminderTest: PropTypes.string,
|
||||
/** Save button label */
|
||||
saveButtonLabel: PropTypes.string,
|
||||
/** Cancel button label */
|
||||
cancelButtonLabel: PropTypes.string,
|
||||
/** What the save button will trigger when clicked */
|
||||
onSaveClick: PropTypes.func,
|
||||
/** What the cancel button will trigger when clicked */
|
||||
onCancelClick: PropTypes.func,
|
||||
/** Show message about unsaved changes (Only shown on desktops) */
|
||||
showReminder: PropTypes.bool,
|
||||
};
|
||||
|
||||
|
@ -1,26 +1,39 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import { text, boolean, withKnobs } from "@storybook/addon-knobs/react";
|
||||
import SaveCancelButtons from ".";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import SaveCancelButtons from "./";
|
||||
|
||||
storiesOf("Components|SaveCancelButtons", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("base", () => {
|
||||
return (
|
||||
<Section>
|
||||
<SaveCancelButtons
|
||||
onSaveClick={() => action("on Save button clicked")}
|
||||
onCancelClick={() => action("on Cancel button clicked")}
|
||||
showReminder={boolean("showReminder", false)}
|
||||
reminderTest={text("reminderTest", "You have unsaved changes")}
|
||||
saveButtonLabel={text("saveButtonLabel", "Save")}
|
||||
cancelButtonLabel={text("cancelButtonLabel", "Cancel")}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
});
|
||||
export default {
|
||||
title: "Components/SaveCancelButtons",
|
||||
component: SaveCancelButtons,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"Save and cancel buttons are located in the settings sections.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
onSaveClick: { action: "onSaveClick" },
|
||||
onCancelClick: { action: "onCancelClick" },
|
||||
},
|
||||
};
|
||||
|
||||
const Template = ({ onSaveClick, onCancelClick, ...args }) => {
|
||||
return (
|
||||
<div style={{ position: "relative", height: "60px" }}>
|
||||
<SaveCancelButtons
|
||||
{...args}
|
||||
onSaveClick={() => onSaveClick("on Save button clicked")}
|
||||
onCancelClick={() => onCancelClick("on Cancel button clicked")}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
showReminder: false,
|
||||
reminderTest: "You have unsaved changes",
|
||||
saveButtonLabel: "Save",
|
||||
cancelButtonLabel: "Cancel",
|
||||
};
|
||||
|
@ -103,9 +103,13 @@ const Scrollbar = React.forwardRef((props, ref) => {
|
||||
});
|
||||
|
||||
Scrollbar.propTypes = {
|
||||
/** Scrollbar style type */
|
||||
stype: PropTypes.string,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
};
|
||||
|
||||
|
@ -1,37 +1,42 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import { withKnobs, select } from "@storybook/addon-knobs/react";
|
||||
import Readme from "./README.md";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import Scrollbar from ".";
|
||||
import Scrollbar from "./";
|
||||
|
||||
const stypes = ["smallWhite", "smallBlack", "mediumBlack"];
|
||||
export default {
|
||||
title: "Components/Scrollbar",
|
||||
component: Scrollbar,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: "Scrollbar is used for displaying custom scrollbar",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
storiesOf("Components|Scrollbar", module)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.addDecorator(withKnobs)
|
||||
.add("base", () => (
|
||||
<Section>
|
||||
<Scrollbar
|
||||
stype={select("stype", stypes, "mediumBlack")}
|
||||
style={{ width: 300, height: 200 }}
|
||||
>
|
||||
================================================================ Lorem
|
||||
ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
|
||||
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit
|
||||
esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
|
||||
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim
|
||||
id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
||||
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
||||
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
|
||||
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit
|
||||
in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
||||
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
|
||||
officia deserunt mollit anim id est laborum.
|
||||
================================================================
|
||||
</Scrollbar>
|
||||
</Section>
|
||||
));
|
||||
const Template = (args) => {
|
||||
return (
|
||||
<Scrollbar {...args}>
|
||||
================================================================ Lorem
|
||||
ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
|
||||
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
|
||||
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
|
||||
non proident, sunt in culpa qui officia deserunt mollit anim id est
|
||||
laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
|
||||
minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
|
||||
ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
|
||||
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
|
||||
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
|
||||
est laborum.
|
||||
================================================================
|
||||
</Scrollbar>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
stype: "mediumBlack",
|
||||
style: { width: 300, height: 200 },
|
||||
};
|
||||
|
@ -107,20 +107,30 @@ class SearchInput extends React.Component {
|
||||
}
|
||||
|
||||
SearchInput.propTypes = {
|
||||
/** Used as HTML `id` property */
|
||||
id: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Supported size of the input fields. */
|
||||
size: PropTypes.oneOf(["base", "middle", "big", "huge"]),
|
||||
/** Value of the input */
|
||||
value: PropTypes.string,
|
||||
/** Indicates the input field has scale */
|
||||
scale: PropTypes.bool,
|
||||
/** Placeholder text for the input */
|
||||
placeholder: PropTypes.string,
|
||||
/** Called with the new value. Required when input is not read only. Parent should pass it back as `value` */
|
||||
onChange: PropTypes.func,
|
||||
onClearSearch: PropTypes.func,
|
||||
/** Indicates that the field cannot be used (e.g not authorized, or changes not saved) */
|
||||
isDisabled: PropTypes.bool,
|
||||
showClearButton: PropTypes.bool,
|
||||
refreshTimeout: PropTypes.number,
|
||||
autoRefresh: PropTypes.bool,
|
||||
/** Child elements */
|
||||
children: PropTypes.any,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
};
|
||||
|
||||
|
@ -1,60 +1,45 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import { StringValue } from "react-values";
|
||||
import { withKnobs, boolean, text, select } from "@storybook/addon-knobs/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import React, { useState } from "react";
|
||||
import SearchInput from ".";
|
||||
import Button from "../button";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
|
||||
const sizeOptions = ["base", "middle", "big", "huge"];
|
||||
export default {
|
||||
title: "Components/SearchInput",
|
||||
component: SearchInput,
|
||||
argTypes: {
|
||||
onChange: { action: "onChange" },
|
||||
},
|
||||
};
|
||||
|
||||
class SearchStory extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: "test1",
|
||||
};
|
||||
this.buttonClick = this.buttonClick.bind(this);
|
||||
}
|
||||
buttonClick() {
|
||||
this.setState({ value: "test" });
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Section>
|
||||
<StringValue
|
||||
onChange={(value) => {
|
||||
action("onChange")(value);
|
||||
}}
|
||||
>
|
||||
{({ value, set }) => (
|
||||
<Section>
|
||||
<div style={{ marginBottom: "20px" }}>
|
||||
<Button label="Change props" onClick={this.buttonClick} />
|
||||
</div>
|
||||
<SearchInput
|
||||
id={text("id", "")}
|
||||
isDisabled={boolean("isDisabled", false)}
|
||||
size={select("size", sizeOptions, "base")}
|
||||
scale={boolean("scale", false)}
|
||||
placeholder={text("placeholder", "Search")}
|
||||
value={value}
|
||||
onChange={(value) => {
|
||||
set(value);
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
)}
|
||||
</StringValue>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
}
|
||||
const Template = ({ value, onChange, ...args }) => {
|
||||
const [valueBtn, setValue] = useState("test1");
|
||||
const [searchValue, setSearchValue] = useState(value);
|
||||
|
||||
storiesOf("Components|Input", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("search", () => <SearchStory />);
|
||||
const onButtonHandler = () => {
|
||||
setValue("test");
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div style={{ marginBottom: "20px" }}>
|
||||
<Button label="Change props" onClick={onButtonHandler} />
|
||||
</div>
|
||||
<SearchInput
|
||||
{...args}
|
||||
value={searchValue}
|
||||
onChange={(value) => {
|
||||
onChange(value);
|
||||
setSearchValue(value);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
id: "",
|
||||
isDisabled: false,
|
||||
size: "base",
|
||||
scale: false,
|
||||
placeholder: "Search",
|
||||
value: "",
|
||||
};
|
||||
|
@ -1,80 +0,0 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import SelectedItem from ".";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import styled from "@emotion/styled";
|
||||
|
||||
function onClose(e) {
|
||||
console.log("onClose", e);
|
||||
}
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
padding: 0;
|
||||
display: grid;
|
||||
grid-gap: 10px;
|
||||
`;
|
||||
|
||||
const StyledContainerInline = styled.div`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 10px;
|
||||
|
||||
> * {
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
`;
|
||||
|
||||
storiesOf("Components|SelectedItem", module)
|
||||
.addParameters({ options: { showAddonPanel: false } })
|
||||
.add("all", () => {
|
||||
return (
|
||||
<Section>
|
||||
<StyledContainerInline>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={true}
|
||||
onClose={onClose}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={true}
|
||||
onClose={onClose}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={true}
|
||||
onClose={onClose}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={true}
|
||||
onClose={onClose}
|
||||
/>
|
||||
</StyledContainerInline>
|
||||
|
||||
<StyledContainer>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={false}
|
||||
onClose={onClose}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={false}
|
||||
onClose={onClose}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={false}
|
||||
onClose={onClose}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={false}
|
||||
onClose={onClose}
|
||||
/>
|
||||
</StyledContainer>
|
||||
</Section>
|
||||
);
|
||||
});
|
@ -39,12 +39,19 @@ const SelectedItem = (props) => {
|
||||
};
|
||||
|
||||
SelectedItem.propTypes = {
|
||||
/** Selected item text */
|
||||
text: PropTypes.string,
|
||||
/** Sets the 'display: inline-block' property */
|
||||
isInline: PropTypes.bool,
|
||||
/** What the selected item will trigger when clicked */
|
||||
onClose: PropTypes.func.isRequired,
|
||||
/** Tells when the button should present a disabled state */
|
||||
isDisabled: PropTypes.bool,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
};
|
||||
|
||||
|
@ -1,27 +1,95 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import { text, boolean, withKnobs } from "@storybook/addon-knobs/react";
|
||||
import SelectedItem from ".";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import styled from "styled-components";
|
||||
import SelectedItem from "./";
|
||||
|
||||
function onClose(e) {
|
||||
console.log("onClose", e);
|
||||
}
|
||||
export default {
|
||||
title: "Components/SelectedItem",
|
||||
component: SelectedItem,
|
||||
argTypes: {
|
||||
onClose: { action: "onClose" },
|
||||
},
|
||||
};
|
||||
const Template = ({ onClose, ...args }) => {
|
||||
return <SelectedItem {...args} onClose={(e) => onClose(e)} />;
|
||||
};
|
||||
|
||||
storiesOf("Components|SelectedItem", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("base", () => {
|
||||
return (
|
||||
<Section>
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
text: "Selected item",
|
||||
isInline: true,
|
||||
isDisabled: false,
|
||||
};
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
padding: 0;
|
||||
display: grid;
|
||||
grid-gap: 10px;
|
||||
`;
|
||||
|
||||
const StyledContainerInline = styled.div`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 10px;
|
||||
|
||||
> * {
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
`;
|
||||
|
||||
const AllTemplate = ({ onClose, ...args }) => {
|
||||
const onCloseHandler = (e) => {
|
||||
onClose(e);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<StyledContainerInline>
|
||||
<SelectedItem
|
||||
text={text("text", "Selected item")}
|
||||
isInline={boolean("isInline", true)}
|
||||
onClose={onClose}
|
||||
isDisabled={boolean("isDisabled", false)}
|
||||
text="Selected item"
|
||||
isInline={true}
|
||||
onClose={onCloseHandler}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
});
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={true}
|
||||
onClose={onCloseHandler}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={true}
|
||||
onClose={onCloseHandler}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={true}
|
||||
onClose={onCloseHandler}
|
||||
/>
|
||||
</StyledContainerInline>
|
||||
|
||||
<StyledContainer>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={false}
|
||||
onClose={onCloseHandler}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={false}
|
||||
onClose={onCloseHandler}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={false}
|
||||
onClose={onCloseHandler}
|
||||
/>
|
||||
<SelectedItem
|
||||
text="Selected item"
|
||||
isInline={false}
|
||||
onClose={onCloseHandler}
|
||||
/>
|
||||
</StyledContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const All = AllTemplate.bind({});
|
||||
|
@ -1,10 +1,9 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import StyledButton from "./styled-selector-add-button"
|
||||
import StyledButton from "./styled-selector-add-button";
|
||||
import IconButton from "../icon-button";
|
||||
|
||||
|
||||
const SelectorAddButton = (props) => {
|
||||
const { isDisabled, title, className, id, style } = props;
|
||||
|
||||
@ -34,11 +33,17 @@ const SelectorAddButton = (props) => {
|
||||
};
|
||||
|
||||
SelectorAddButton.propTypes = {
|
||||
/** Title text */
|
||||
title: PropTypes.string,
|
||||
/** What the button will trigger when clicked */
|
||||
onClick: PropTypes.func,
|
||||
/** Tells when the button should present a disabled state */
|
||||
isDisabled: PropTypes.bool,
|
||||
/** Attribute className */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
};
|
||||
|
||||
|
@ -1,25 +1,24 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import { text, boolean, withKnobs } from "@storybook/addon-knobs/react";
|
||||
import SelectorAddButton from ".";
|
||||
import Section from "../../../.storybook/decorators/section";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import SelectorAddButton from "./";
|
||||
|
||||
storiesOf("Components|SelectorAddButton", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("base", () => {
|
||||
const isDisabled = boolean("isDisabled", false);
|
||||
return (
|
||||
<Section>
|
||||
<SelectorAddButton
|
||||
isDisabled={isDisabled}
|
||||
title={text("text", "Add item")}
|
||||
onClick={(e) => {
|
||||
!isDisabled && console.log("onClose", e);
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
});
|
||||
export default {
|
||||
title: "Components/SelectorAddButton",
|
||||
component: SelectorAddButton,
|
||||
argTypes: { onClick: { action: "onClose" } },
|
||||
};
|
||||
|
||||
const Template = ({ onClick, ...args }) => {
|
||||
return (
|
||||
<SelectorAddButton
|
||||
onClick={(e) => {
|
||||
!args.isDisabled && onClick(e);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
isDisabled: false,
|
||||
title: "Add item",
|
||||
};
|
||||
|
@ -28,12 +28,19 @@ class SocialButton extends React.Component {
|
||||
}
|
||||
|
||||
SocialButton.propTypes = {
|
||||
/** Button text */
|
||||
label: PropTypes.string,
|
||||
/** Icon of button */
|
||||
iconName: PropTypes.string,
|
||||
/** Accepts tabindex prop*/
|
||||
tabIndex: PropTypes.number,
|
||||
/** Tells when the button should present a disabled state */
|
||||
isDisabled: PropTypes.bool,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
};
|
||||
|
||||
|
@ -1,33 +1,39 @@
|
||||
import React from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import { withKnobs, boolean, text, select } from "@storybook/addon-knobs/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import SocialButton from ".";
|
||||
import SocialButton from "./";
|
||||
|
||||
storiesOf("Components|Buttons|SocialButtons", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add("social button", () => {
|
||||
const socialNetworks = [
|
||||
"static/images/share.google.react.svg",
|
||||
"ShareFacebookIcon",
|
||||
"ShareTwitterIcon",
|
||||
"static/images/share.linkedin.react.svg",
|
||||
];
|
||||
const iconName = select(
|
||||
"iconName",
|
||||
["", ...socialNetworks],
|
||||
"static/images/share.google.react.svg"
|
||||
);
|
||||
export default {
|
||||
title: "Components/SocialButtons",
|
||||
component: SocialButton,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: "Button is used for sign up with help social networks",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
onClick: { action: "onClick" },
|
||||
iconName: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: [
|
||||
"static/images/share.google.react.svg",
|
||||
//"ShareFacebookIcon",
|
||||
//"ShareTwitterIcon",
|
||||
"static/images/share.linkedin.react.svg",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<SocialButton
|
||||
label={text("label", "Base SocialButton")}
|
||||
iconName={iconName}
|
||||
isDisabled={boolean("isDisabled", false)}
|
||||
onClick={action("clicked")}
|
||||
/>
|
||||
);
|
||||
});
|
||||
const Template = ({ onClick, ...args }) => {
|
||||
return <SocialButton {...args} onClick={() => onClick("clicked")} />;
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
label: "Base SocialButton",
|
||||
iconName: "static/images/share.google.react.svg",
|
||||
isDisabled: false,
|
||||
};
|
||||
|
@ -3,6 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"private": "true",
|
||||
"homepage": "/products/files",
|
||||
"title": "ONLYOFFICE",
|
||||
"scripts": {
|
||||
"start": "webpack-cli serve",
|
||||
"build": "webpack --mode production",
|
||||
@ -19,6 +20,7 @@
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"compression-webpack-plugin": "^7.1.2",
|
||||
"copy-webpack-plugin": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
|
@ -89,14 +89,14 @@
|
||||
height: 36px;
|
||||
}
|
||||
</style>
|
||||
<title>ONLYOFFICE</title>
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript> You need to enable JavaScript to run this app. </noscript>
|
||||
|
||||
<div class="ipl-progress-indicator" id="ipl-progress-indicator"></div>
|
||||
|
||||
<div id="temp-content" style="display: none">
|
||||
<div id="temp-content" style="display: none;">
|
||||
<header class="temp-header-container">
|
||||
<div id="burger-loader-svg" class="burger-loader-svg">
|
||||
<svg
|
||||
@ -111,7 +111,7 @@
|
||||
ry="3"
|
||||
width="24"
|
||||
height="24"
|
||||
style="fill: url('#fill0')"
|
||||
style="fill: url('#fill0');"
|
||||
></rect>
|
||||
<defs>
|
||||
<linearGradient id="fill0">
|
||||
@ -137,7 +137,7 @@
|
||||
ry="3"
|
||||
width="168"
|
||||
height="24"
|
||||
style="fill: url('#fill01')"
|
||||
style="fill: url('#fill01');"
|
||||
></rect>
|
||||
<defs>
|
||||
<linearGradient id="fill01">
|
||||
@ -165,7 +165,7 @@
|
||||
r="18"
|
||||
width="36"
|
||||
height="36"
|
||||
style="fill: url('#fill02')"
|
||||
style="fill: url('#fill02');"
|
||||
></circle>
|
||||
<defs>
|
||||
<linearGradient id="fill02">
|
||||
@ -195,7 +195,7 @@
|
||||
width="100%"
|
||||
height="100%"
|
||||
clip-path="url(#clip-path1)"
|
||||
style="fill: url('#fill1')"
|
||||
style="fill: url('#fill1');"
|
||||
></rect>
|
||||
<defs>
|
||||
<clipPath id="clip-path1">
|
||||
@ -225,7 +225,7 @@
|
||||
width="100%"
|
||||
height="100%"
|
||||
clip-path="url(#clip-path2)"
|
||||
style="fill: url('#fill2')"
|
||||
style="fill: url('#fill2');"
|
||||
></rect>
|
||||
<defs>
|
||||
<clipPath id="clip-path2">
|
||||
|
@ -52,7 +52,8 @@ class DeleteDialogComponent extends React.Component {
|
||||
deleteSelectedElem: t("DeleteSelectedElem"),
|
||||
};
|
||||
|
||||
deleteAction(translations);
|
||||
deleteAction(translations)
|
||||
.catch((err) => toastr.error(err));
|
||||
};
|
||||
|
||||
onChange = (event) => {
|
||||
|
@ -135,6 +135,7 @@ class DownloadDialogComponent extends React.Component {
|
||||
const {
|
||||
//onDownloadProgress,
|
||||
t,
|
||||
getDownloadProgress,
|
||||
setSecondaryProgressBarData,
|
||||
clearSecondaryProgressData,
|
||||
} = this.props;
|
||||
@ -154,7 +155,8 @@ class DownloadDialogComponent extends React.Component {
|
||||
downloadFormatFiles(fileConvertIds, folderIds)
|
||||
.then((res) => {
|
||||
this.onClose();
|
||||
this.props.getDownloadProgress(res[0], t("ArchivingData"));
|
||||
getDownloadProgress(res[0], t("ArchivingData"))
|
||||
.catch((err) => toastr.error(err));
|
||||
})
|
||||
.catch((err) => {
|
||||
setSecondaryProgressBarData({
|
||||
|
@ -9,7 +9,7 @@ import DragAndDrop from "@appserver/components/drag-and-drop";
|
||||
import Row from "@appserver/components/row";
|
||||
import FilesRowContent from "./FilesRowContent";
|
||||
import history from "@appserver/common/history";
|
||||
import toastr from "@appserver/components/toast";
|
||||
import toastr from "studio/toastr";
|
||||
import { FileAction } from "@appserver/common/constants";
|
||||
|
||||
const StyledSimpleFilesRow = styled(Row)`
|
||||
@ -81,6 +81,7 @@ const SimpleFilesRow = (props) => {
|
||||
homepage,
|
||||
isTabletView,
|
||||
actionId,
|
||||
selectedFolderId,
|
||||
|
||||
setSharingPanelVisible,
|
||||
setChangeOwnerPanelVisible,
|
||||
@ -103,6 +104,8 @@ const SimpleFilesRow = (props) => {
|
||||
selectRowAction,
|
||||
setThirdpartyInfo,
|
||||
setMediaViewerData,
|
||||
setDragging,
|
||||
startUpload,
|
||||
} = props;
|
||||
|
||||
const {
|
||||
@ -111,7 +114,6 @@ const SimpleFilesRow = (props) => {
|
||||
fileExst,
|
||||
shared,
|
||||
access,
|
||||
value,
|
||||
contextOptions,
|
||||
icon,
|
||||
providerKey,
|
||||
@ -122,6 +124,9 @@ const SimpleFilesRow = (props) => {
|
||||
locked,
|
||||
} = item;
|
||||
|
||||
let value = fileExst ? `file_${id}` : `folder_${id}`;
|
||||
value += draggable ? "_draggable" : "";
|
||||
|
||||
const isThirdPartyFolder = providerKey && isRootFolder;
|
||||
|
||||
const onContentRowSelect = (checked, file) => {
|
||||
@ -191,14 +196,22 @@ const SimpleFilesRow = (props) => {
|
||||
}
|
||||
};
|
||||
|
||||
const finalizeVersion = () => finalizeVersionAction(id);
|
||||
const finalizeVersion = () =>
|
||||
finalizeVersionAction(id).catch((err) => toastr.error(err));
|
||||
|
||||
const onClickFavorite = (e) => {
|
||||
const { action } = e.currentTarget.dataset;
|
||||
setFavoriteAction(action, id);
|
||||
setFavoriteAction(action, id)
|
||||
.then(() =>
|
||||
action === "mark"
|
||||
? toastr.success(t("MarkedAsFavorite"))
|
||||
: toastr.success(t("RemovedFromFavorites"))
|
||||
)
|
||||
.catch((err) => toastr.error(err));
|
||||
};
|
||||
|
||||
const lockFile = () => lockFileAction(id, locked);
|
||||
const lockFile = () =>
|
||||
lockFileAction(id, locked).catch((err) => toastr.error(err));
|
||||
|
||||
const onClickLinkForPortal = () => {
|
||||
const isFile = !!fileExst;
|
||||
@ -218,7 +231,8 @@ const SimpleFilesRow = (props) => {
|
||||
|
||||
const onClickDownload = () => window.open(viewUrl, "_blank");
|
||||
|
||||
const onDuplicate = () => duplicateAction(item, t("CopyOperation"));
|
||||
const onDuplicate = () =>
|
||||
duplicateAction(item, t("CopyOperation")).catch((err) => toastr.error(err));
|
||||
|
||||
const onClickRename = () => {
|
||||
setAction({
|
||||
@ -245,204 +259,218 @@ const SimpleFilesRow = (props) => {
|
||||
|
||||
const translations = {
|
||||
deleteOperation: t("DeleteOperation"),
|
||||
folderRemoved: t("FolderRemoved"),
|
||||
fileRemoved: t("FileRemoved"),
|
||||
};
|
||||
|
||||
item.fileExst
|
||||
? deleteFileAction(item.id, item.folderId, translations)
|
||||
: deleteFolderAction(item.id, item.parentId, translations);
|
||||
.then(() => toastr.success(t("FileRemoved")))
|
||||
.catch((err) => toastr.error(err))
|
||||
: deleteFolderAction(item.id, item.parentId, translations)
|
||||
.then(() => toastr.success(t("FolderRemoved")))
|
||||
.catch((err) => toastr.error(err));
|
||||
};
|
||||
|
||||
const getFilesContextOptions = useCallback(
|
||||
(options, item) => {
|
||||
const isSharable = item.access !== 1 && item.access !== 0;
|
||||
const getFilesContextOptions = useCallback(() => {
|
||||
const isSharable = item.access !== 1 && item.access !== 0;
|
||||
|
||||
return options.map((option) => {
|
||||
switch (option) {
|
||||
case "open":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Open"),
|
||||
icon: "CatalogFolderIcon",
|
||||
onClick: onOpenLocation,
|
||||
disabled: false,
|
||||
};
|
||||
case "show-version-history":
|
||||
return {
|
||||
key: option,
|
||||
label: t("ShowVersionHistory"),
|
||||
icon: "HistoryIcon",
|
||||
onClick: showVersionHistory,
|
||||
disabled: false,
|
||||
};
|
||||
case "finalize-version":
|
||||
return {
|
||||
key: option,
|
||||
label: t("FinalizeVersion"),
|
||||
icon: "HistoryFinalizedIcon",
|
||||
onClick: finalizeVersion,
|
||||
disabled: false,
|
||||
};
|
||||
case "separator0":
|
||||
case "separator1":
|
||||
case "separator2":
|
||||
case "separator3":
|
||||
return { key: option, isSeparator: true };
|
||||
case "open-location":
|
||||
return {
|
||||
key: option,
|
||||
label: t("OpenLocation"),
|
||||
icon: "DownloadAsIcon",
|
||||
onClick: onOpenLocation,
|
||||
disabled: false,
|
||||
};
|
||||
case "mark-as-favorite":
|
||||
return {
|
||||
key: option,
|
||||
label: t("MarkAsFavorite"),
|
||||
icon: "FavoritesIcon",
|
||||
onClick: onClickFavorite,
|
||||
disabled: false,
|
||||
"data-action": "mark",
|
||||
};
|
||||
case "block-unblock-version":
|
||||
return {
|
||||
key: option,
|
||||
label: t("UnblockVersion"),
|
||||
icon: "LockIcon",
|
||||
onClick: lockFile,
|
||||
disabled: false,
|
||||
};
|
||||
case "sharing-settings":
|
||||
return {
|
||||
key: option,
|
||||
label: t("SharingSettings"),
|
||||
icon: "CatalogSharedIcon",
|
||||
onClick: onClickShare,
|
||||
disabled: isSharable,
|
||||
};
|
||||
case "send-by-email":
|
||||
return {
|
||||
key: option,
|
||||
label: t("SendByEmail"),
|
||||
icon: "MailIcon",
|
||||
disabled: true,
|
||||
};
|
||||
case "owner-change":
|
||||
return {
|
||||
key: option,
|
||||
label: t("ChangeOwner"),
|
||||
icon: "CatalogUserIcon",
|
||||
onClick: onOwnerChange,
|
||||
disabled: false,
|
||||
};
|
||||
case "link-for-portal-users":
|
||||
return {
|
||||
key: option,
|
||||
label: t("LinkForPortalUsers"),
|
||||
icon: "InvitationLinkIcon",
|
||||
onClick: onClickLinkForPortal,
|
||||
disabled: false,
|
||||
};
|
||||
case "edit":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Edit"),
|
||||
icon: "AccessEditIcon",
|
||||
onClick: onClickLinkEdit,
|
||||
disabled: false,
|
||||
};
|
||||
case "preview":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Preview"),
|
||||
icon: "EyeIcon",
|
||||
onClick: onClickLinkEdit,
|
||||
disabled: true,
|
||||
};
|
||||
case "view":
|
||||
return {
|
||||
key: option,
|
||||
label: t("View"),
|
||||
icon: "EyeIcon",
|
||||
onClick: onMediaFileClick,
|
||||
disabled: false,
|
||||
};
|
||||
case "download":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Download"),
|
||||
icon: "DownloadIcon",
|
||||
onClick: onClickDownload,
|
||||
disabled: false,
|
||||
};
|
||||
case "move":
|
||||
return {
|
||||
key: option,
|
||||
label: t("MoveTo"),
|
||||
icon: "MoveToIcon",
|
||||
onClick: onMoveAction,
|
||||
disabled: false,
|
||||
};
|
||||
case "copy":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Copy"),
|
||||
icon: "CopyIcon",
|
||||
onClick: onCopyAction,
|
||||
disabled: false,
|
||||
};
|
||||
case "duplicate":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Duplicate"),
|
||||
icon: "CopyIcon",
|
||||
onClick: onDuplicate,
|
||||
disabled: false,
|
||||
};
|
||||
case "rename":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Rename"),
|
||||
icon: "RenameIcon",
|
||||
onClick: onClickRename,
|
||||
disabled: false,
|
||||
};
|
||||
case "change-thirdparty-info":
|
||||
return {
|
||||
key: option,
|
||||
label: t("ThirdPartyInfo"),
|
||||
icon: "AccessEditIcon",
|
||||
onClick: onChangeThirdPartyInfo,
|
||||
disabled: false,
|
||||
};
|
||||
case "delete":
|
||||
return {
|
||||
key: option,
|
||||
label: isThirdPartyFolder ? t("DeleteThirdParty") : t("Delete"),
|
||||
icon: "CatalogTrashIcon",
|
||||
onClick: onClickDelete,
|
||||
disabled: false,
|
||||
};
|
||||
case "remove-from-favorites":
|
||||
return {
|
||||
key: option,
|
||||
label: t("RemoveFromFavorites"),
|
||||
icon: "FavoritesIcon",
|
||||
onClick: onClickFavorite,
|
||||
disabled: false,
|
||||
"data-action": "remove",
|
||||
};
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return contextOptions.map((option) => {
|
||||
switch (option) {
|
||||
case "open":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Open"),
|
||||
icon: "CatalogFolderIcon",
|
||||
onClick: onOpenLocation,
|
||||
disabled: false,
|
||||
};
|
||||
case "show-version-history":
|
||||
return {
|
||||
key: option,
|
||||
label: t("ShowVersionHistory"),
|
||||
icon: "HistoryIcon",
|
||||
onClick: showVersionHistory,
|
||||
disabled: false,
|
||||
};
|
||||
case "finalize-version":
|
||||
return {
|
||||
key: option,
|
||||
label: t("FinalizeVersion"),
|
||||
icon: "HistoryFinalizedIcon",
|
||||
onClick: finalizeVersion,
|
||||
disabled: false,
|
||||
};
|
||||
case "separator0":
|
||||
case "separator1":
|
||||
case "separator2":
|
||||
case "separator3":
|
||||
return { key: option, isSeparator: true };
|
||||
case "open-location":
|
||||
return {
|
||||
key: option,
|
||||
label: t("OpenLocation"),
|
||||
icon: "DownloadAsIcon",
|
||||
onClick: onOpenLocation,
|
||||
disabled: false,
|
||||
};
|
||||
case "mark-as-favorite":
|
||||
return {
|
||||
key: option,
|
||||
label: t("MarkAsFavorite"),
|
||||
icon: "FavoritesIcon",
|
||||
onClick: onClickFavorite,
|
||||
disabled: false,
|
||||
"data-action": "mark",
|
||||
};
|
||||
case "block-unblock-version":
|
||||
return {
|
||||
key: option,
|
||||
label: t("UnblockVersion"),
|
||||
icon: "LockIcon",
|
||||
onClick: lockFile,
|
||||
disabled: false,
|
||||
};
|
||||
case "sharing-settings":
|
||||
return {
|
||||
key: option,
|
||||
label: t("SharingSettings"),
|
||||
icon: "CatalogSharedIcon",
|
||||
onClick: onClickShare,
|
||||
disabled: isSharable,
|
||||
};
|
||||
case "send-by-email":
|
||||
return {
|
||||
key: option,
|
||||
label: t("SendByEmail"),
|
||||
icon: "MailIcon",
|
||||
disabled: true,
|
||||
};
|
||||
case "owner-change":
|
||||
return {
|
||||
key: option,
|
||||
label: t("ChangeOwner"),
|
||||
icon: "CatalogUserIcon",
|
||||
onClick: onOwnerChange,
|
||||
disabled: false,
|
||||
};
|
||||
case "link-for-portal-users":
|
||||
return {
|
||||
key: option,
|
||||
label: t("LinkForPortalUsers"),
|
||||
icon: "InvitationLinkIcon",
|
||||
onClick: onClickLinkForPortal,
|
||||
disabled: false,
|
||||
};
|
||||
case "edit":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Edit"),
|
||||
icon: "AccessEditIcon",
|
||||
onClick: onClickLinkEdit,
|
||||
disabled: false,
|
||||
};
|
||||
case "preview":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Preview"),
|
||||
icon: "EyeIcon",
|
||||
onClick: onClickLinkEdit,
|
||||
disabled: true,
|
||||
};
|
||||
case "view":
|
||||
return {
|
||||
key: option,
|
||||
label: t("View"),
|
||||
icon: "EyeIcon",
|
||||
onClick: onMediaFileClick,
|
||||
disabled: false,
|
||||
};
|
||||
case "download":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Download"),
|
||||
icon: "DownloadIcon",
|
||||
onClick: onClickDownload,
|
||||
disabled: false,
|
||||
};
|
||||
case "move":
|
||||
return {
|
||||
key: option,
|
||||
label: t("MoveTo"),
|
||||
icon: "MoveToIcon",
|
||||
onClick: onMoveAction,
|
||||
disabled: false,
|
||||
};
|
||||
case "copy":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Copy"),
|
||||
icon: "CopyIcon",
|
||||
onClick: onCopyAction,
|
||||
disabled: false,
|
||||
};
|
||||
case "duplicate":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Duplicate"),
|
||||
icon: "CopyIcon",
|
||||
onClick: onDuplicate,
|
||||
disabled: false,
|
||||
};
|
||||
case "rename":
|
||||
return {
|
||||
key: option,
|
||||
label: t("Rename"),
|
||||
icon: "RenameIcon",
|
||||
onClick: onClickRename,
|
||||
disabled: false,
|
||||
};
|
||||
case "change-thirdparty-info":
|
||||
return {
|
||||
key: option,
|
||||
label: t("ThirdPartyInfo"),
|
||||
icon: "AccessEditIcon",
|
||||
onClick: onChangeThirdPartyInfo,
|
||||
disabled: false,
|
||||
};
|
||||
case "delete":
|
||||
return {
|
||||
key: option,
|
||||
label: isThirdPartyFolder ? t("DeleteThirdParty") : t("Delete"),
|
||||
icon: "CatalogTrashIcon",
|
||||
onClick: onClickDelete,
|
||||
disabled: false,
|
||||
};
|
||||
case "remove-from-favorites":
|
||||
return {
|
||||
key: option,
|
||||
label: t("RemoveFromFavorites"),
|
||||
icon: "FavoritesIcon",
|
||||
onClick: onClickFavorite,
|
||||
disabled: false,
|
||||
"data-action": "remove",
|
||||
};
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
},
|
||||
[contextOptions, item]
|
||||
);
|
||||
return undefined;
|
||||
});
|
||||
}, [contextOptions, item]);
|
||||
|
||||
const onDropZoneUpload = (files, uploadToFolder) => {
|
||||
const folderId = uploadToFolder ? uploadToFolder : selectedFolderId;
|
||||
|
||||
dragging && setDragging(false);
|
||||
startUpload(files, folderId, t);
|
||||
};
|
||||
|
||||
const onDrop = (items) => {
|
||||
if (!fileExst) {
|
||||
onDropZoneUpload(items, item.id);
|
||||
} else {
|
||||
onDropZoneUpload(items, selectedFolderId);
|
||||
}
|
||||
};
|
||||
|
||||
// const onSelectItem = () => {
|
||||
// selected === "close" && setSelected("none");
|
||||
@ -457,28 +485,25 @@ const SimpleFilesRow = (props) => {
|
||||
const contextOptionsProps =
|
||||
!isEdit && contextOptions && contextOptions.length > 0
|
||||
? {
|
||||
contextOptions: getFilesContextOptions(contextOptions, item),
|
||||
contextOptions: getFilesContextOptions(),
|
||||
}
|
||||
: {};
|
||||
|
||||
const checkedProps = isEdit || id <= 0 ? {} : { checked };
|
||||
|
||||
const element = getItemIcon(isEdit || id <= 0);
|
||||
const displayShareButton = isMobile ? "26px" : !canShare ? "38px" : "96px";
|
||||
let className = isFolder && access < 2 && !isRecycleBin ? " dropable" : "";
|
||||
if (draggable) className += " draggable";
|
||||
|
||||
const sharedButton =
|
||||
!canShare || (isPrivacy && !fileExst) || isEdit || id <= 0 || isMobile
|
||||
? null
|
||||
: getSharedButton(shared);
|
||||
|
||||
const displayShareButton = isMobile ? "26px" : !canShare ? "38px" : "96px";
|
||||
|
||||
let className = isFolder && access < 2 && !isRecycleBin ? " dropable" : "";
|
||||
if (draggable) className += " draggable";
|
||||
|
||||
return (
|
||||
<DragAndDrop
|
||||
className={className}
|
||||
//onDrop={this.onDrop.bind(this, item)}
|
||||
onDrop={onDrop}
|
||||
//onMouseDown={this.onMouseDown}
|
||||
dragging={dragging && isFolder && access < 2}
|
||||
{...contextOptionsProps}
|
||||
@ -517,11 +542,12 @@ export default inject(
|
||||
versionHistoryStore,
|
||||
filesActionsStore,
|
||||
mediaViewerDataStore,
|
||||
uploadDataStore,
|
||||
},
|
||||
{ item }
|
||||
) => {
|
||||
const { homepage, isTabletView } = auth.settingsStore;
|
||||
const { dragging, setIsLoading } = initFilesStore;
|
||||
const { dragging, setDragging, setIsLoading } = initFilesStore;
|
||||
const { type, extension, id } = filesStore.fileActionStore;
|
||||
const { isRecycleBinFolder, isPrivacyFolder } = treeFoldersStore;
|
||||
|
||||
@ -544,7 +570,7 @@ export default inject(
|
||||
fileActionStore,
|
||||
} = filesStore;
|
||||
|
||||
const { isRootFolder } = selectedFolderStore;
|
||||
const { isRootFolder, id: selectedFolderId } = selectedFolderStore;
|
||||
const { setIsVerHistoryPanel, setVerHistoryFileId } = versionHistoryStore;
|
||||
const { setAction } = fileActionStore;
|
||||
|
||||
@ -554,7 +580,7 @@ export default inject(
|
||||
|
||||
const isFolder = selectedItem ? false : item.fileExst ? false : true;
|
||||
const draggable =
|
||||
selectedItem && isRecycleBinFolder && selectedItem.id !== id;
|
||||
!isRecycleBinFolder && selectedItem && selectedItem.id !== id;
|
||||
|
||||
const {
|
||||
deleteFileAction,
|
||||
@ -569,6 +595,7 @@ export default inject(
|
||||
} = filesActionsStore;
|
||||
|
||||
const { setMediaViewerData } = mediaViewerDataStore;
|
||||
const { startUpload } = uploadDataStore;
|
||||
|
||||
return {
|
||||
dragging,
|
||||
@ -584,6 +611,7 @@ export default inject(
|
||||
checked: selection.some((el) => el.id === item.id),
|
||||
isFolder,
|
||||
draggable,
|
||||
isItemsSelected: !!selection.length,
|
||||
homepage,
|
||||
isTabletView,
|
||||
actionId: fileActionStore.id,
|
||||
@ -608,16 +636,9 @@ export default inject(
|
||||
selectRowAction,
|
||||
setThirdpartyInfo,
|
||||
setMediaViewerData,
|
||||
selectedFolderId,
|
||||
setDragging,
|
||||
startUpload,
|
||||
};
|
||||
}
|
||||
)(withTranslation("Home")(observer(SimpleFilesRow)));
|
||||
|
||||
// onDrop = (item, items, e) => {
|
||||
// const { onDropZoneUpload, selectedFolderId } = this.props;
|
||||
|
||||
// if (!item.fileExst) {
|
||||
// onDropZoneUpload(items, item.id);
|
||||
// } else {
|
||||
// onDropZoneUpload(items, selectedFolderId);
|
||||
// }
|
||||
// };
|
||||
|
@ -44,13 +44,13 @@ class SectionBodyContent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isDrag: false,
|
||||
canDrag: true,
|
||||
};
|
||||
// this.state = {
|
||||
// isDrag: false,
|
||||
// canDrag: true,
|
||||
// };
|
||||
|
||||
this.tooltipRef = React.createRef();
|
||||
this.currentDroppable = null;
|
||||
// this.tooltipRef = React.createRef();
|
||||
// this.currentDroppable = null;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -58,22 +58,20 @@ class SectionBodyContent extends React.Component {
|
||||
"#customScrollBar > .scroll-body"
|
||||
);
|
||||
|
||||
window.addEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
document.addEventListener("dragstart", this.onDragStart);
|
||||
document.addEventListener("dragover", this.onDragOver);
|
||||
document.addEventListener("dragleave", this.onDragLeaveDoc);
|
||||
document.addEventListener("drop", this.onDropEvent);
|
||||
// window.addEventListener("mouseup", this.onMouseUp);
|
||||
// document.addEventListener("dragstart", this.onDragStart);
|
||||
// document.addEventListener("dragover", this.onDragOver);
|
||||
// document.addEventListener("dragleave", this.onDragLeaveDoc);
|
||||
// document.addEventListener("drop", this.onDropEvent);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
document.addEventListener("dragstart", this.onDragStart);
|
||||
document.removeEventListener("dragover", this.onDragOver);
|
||||
document.removeEventListener("dragleave", this.onDragLeaveDoc);
|
||||
document.removeEventListener("drop", this.onDropEvent);
|
||||
}
|
||||
// componentWillUnmount() {
|
||||
// window.removeEventListener("mouseup", this.onMouseUp);
|
||||
// document.addEventListener("dragstart", this.onDragStart);
|
||||
// document.removeEventListener("dragover", this.onDragOver);
|
||||
// document.removeEventListener("dragleave", this.onDragLeaveDoc);
|
||||
// document.removeEventListener("drop", this.onDropEvent);
|
||||
// }
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
Object.entries(this.props).forEach(
|
||||
@ -98,250 +96,250 @@ class SectionBodyContent extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
onDragStart = (e) => {
|
||||
if (e.dataTransfer.dropEffect === "none") {
|
||||
this.state.canDrag && this.setState({ canDrag: false });
|
||||
}
|
||||
};
|
||||
// onDragStart = (e) => {
|
||||
// if (e.dataTransfer.dropEffect === "none") {
|
||||
// this.state.canDrag && this.setState({ canDrag: false });
|
||||
// }
|
||||
// };
|
||||
|
||||
onDropEvent = () => {
|
||||
this.props.dragging && this.props.setDragging(false);
|
||||
};
|
||||
// onDropEvent = () => {
|
||||
// this.props.dragging && this.props.setDragging(false);
|
||||
// };
|
||||
|
||||
onDragOver = (e) => {
|
||||
e.preventDefault();
|
||||
const { dragging, setDragging } = this.props;
|
||||
if (e.dataTransfer.items.length > 0 && !dragging && this.state.canDrag) {
|
||||
setDragging(true);
|
||||
}
|
||||
};
|
||||
// onDragOver = (e) => {
|
||||
// e.preventDefault();
|
||||
// const { dragging, setDragging } = this.props;
|
||||
// if (e.dataTransfer.items.length > 0 && !dragging && this.state.canDrag) {
|
||||
// setDragging(true);
|
||||
// }
|
||||
// };
|
||||
|
||||
onDragLeaveDoc = (e) => {
|
||||
e.preventDefault();
|
||||
const { dragging, setDragging } = this.props;
|
||||
if (dragging && !e.relatedTarget) {
|
||||
setDragging(false);
|
||||
}
|
||||
};
|
||||
// onDragLeaveDoc = (e) => {
|
||||
// e.preventDefault();
|
||||
// const { dragging, setDragging } = this.props;
|
||||
// if (dragging && !e.relatedTarget) {
|
||||
// setDragging(false);
|
||||
// }
|
||||
// };
|
||||
|
||||
onMouseDown = (e) => {
|
||||
if (
|
||||
window.innerWidth < 1025 ||
|
||||
e.target.tagName === "rect" ||
|
||||
e.target.tagName === "path"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const mouseButton = e.which
|
||||
? e.which !== 1
|
||||
: e.button
|
||||
? e.button !== 0
|
||||
: false;
|
||||
const label = e.currentTarget.getAttribute("label");
|
||||
if (mouseButton || e.currentTarget.tagName !== "DIV" || label) {
|
||||
return;
|
||||
}
|
||||
document.addEventListener("mousemove", this.onMouseMove);
|
||||
this.setTooltipPosition(e);
|
||||
const { selection } = this.props;
|
||||
// onMouseDown = (e) => {
|
||||
// if (
|
||||
// window.innerWidth < 1025 ||
|
||||
// e.target.tagName === "rect" ||
|
||||
// e.target.tagName === "path"
|
||||
// ) {
|
||||
// return;
|
||||
// }
|
||||
// const mouseButton = e.which
|
||||
// ? e.which !== 1
|
||||
// : e.button
|
||||
// ? e.button !== 0
|
||||
// : false;
|
||||
// const label = e.currentTarget.getAttribute("label");
|
||||
// if (mouseButton || e.currentTarget.tagName !== "DIV" || label) {
|
||||
// return;
|
||||
// }
|
||||
// document.addEventListener("mousemove", this.onMouseMove);
|
||||
// this.setTooltipPosition(e);
|
||||
// const { selection } = this.props;
|
||||
|
||||
const elem = e.currentTarget.closest(".draggable");
|
||||
if (!elem) {
|
||||
return;
|
||||
}
|
||||
const value = elem.getAttribute("value");
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
let splitValue = value.split("_");
|
||||
let item = null;
|
||||
if (splitValue[0] === "folder") {
|
||||
splitValue.splice(0, 1);
|
||||
if (splitValue[splitValue.length - 1] === "draggable") {
|
||||
splitValue.splice(-1, 1);
|
||||
}
|
||||
splitValue = splitValue.join("_");
|
||||
// const elem = e.currentTarget.closest(".draggable");
|
||||
// if (!elem) {
|
||||
// return;
|
||||
// }
|
||||
// const value = elem.getAttribute("value");
|
||||
// if (!value) {
|
||||
// return;
|
||||
// }
|
||||
// let splitValue = value.split("_");
|
||||
// let item = null;
|
||||
// if (splitValue[0] === "folder") {
|
||||
// splitValue.splice(0, 1);
|
||||
// if (splitValue[splitValue.length - 1] === "draggable") {
|
||||
// splitValue.splice(-1, 1);
|
||||
// }
|
||||
// splitValue = splitValue.join("_");
|
||||
|
||||
item = selection.find((x) => x.id + "" === splitValue && !x.fileExst);
|
||||
} else {
|
||||
splitValue.splice(0, 1);
|
||||
if (splitValue[splitValue.length - 1] === "draggable") {
|
||||
splitValue.splice(-1, 1);
|
||||
}
|
||||
splitValue = splitValue.join("_");
|
||||
// item = selection.find((x) => x.id + "" === splitValue && !x.fileExst);
|
||||
// } else {
|
||||
// splitValue.splice(0, 1);
|
||||
// if (splitValue[splitValue.length - 1] === "draggable") {
|
||||
// splitValue.splice(-1, 1);
|
||||
// }
|
||||
// splitValue = splitValue.join("_");
|
||||
|
||||
item = selection.find((x) => x.id + "" === splitValue && x.fileExst);
|
||||
}
|
||||
if (item) {
|
||||
this.setState({ isDrag: true });
|
||||
}
|
||||
};
|
||||
// item = selection.find((x) => x.id + "" === splitValue && x.fileExst);
|
||||
// }
|
||||
// if (item) {
|
||||
// this.setState({ isDrag: true });
|
||||
// }
|
||||
// };
|
||||
|
||||
onMouseUp = (e) => {
|
||||
const { selection, dragging, setDragging, dragItem } = this.props;
|
||||
// onMouseUp = (e) => {
|
||||
// const { selection, dragging, setDragging, dragItem } = this.props;
|
||||
|
||||
document.body.classList.remove("drag-cursor");
|
||||
// document.body.classList.remove("drag-cursor");
|
||||
|
||||
if (this.state.isDrag || !this.state.canDrag) {
|
||||
this.setState({ isDrag: false, canDrag: true });
|
||||
}
|
||||
const mouseButton = e.which
|
||||
? e.which !== 1
|
||||
: e.button
|
||||
? e.button !== 0
|
||||
: false;
|
||||
if (mouseButton || !this.tooltipRef.current || !dragging) {
|
||||
return;
|
||||
}
|
||||
document.removeEventListener("mousemove", this.onMouseMove);
|
||||
this.tooltipRef.current.style.display = "none";
|
||||
// if (this.state.isDrag || !this.state.canDrag) {
|
||||
// this.setState({ isDrag: false, canDrag: true });
|
||||
// }
|
||||
// const mouseButton = e.which
|
||||
// ? e.which !== 1
|
||||
// : e.button
|
||||
// ? e.button !== 0
|
||||
// : false;
|
||||
// if (mouseButton || !this.tooltipRef.current || !dragging) {
|
||||
// return;
|
||||
// }
|
||||
// document.removeEventListener("mousemove", this.onMouseMove);
|
||||
// this.tooltipRef.current.style.display = "none";
|
||||
|
||||
const elem = e.target.closest(".dropable");
|
||||
if (elem && selection.length && dragging) {
|
||||
const value = elem.getAttribute("value");
|
||||
if (!value) {
|
||||
setDragging(false);
|
||||
return;
|
||||
}
|
||||
let splitValue = value.split("_");
|
||||
let item = null;
|
||||
if (splitValue[0] === "folder") {
|
||||
splitValue.splice(0, 1);
|
||||
if (splitValue[splitValue.length - 1] === "draggable") {
|
||||
splitValue.splice(-1, 1);
|
||||
}
|
||||
splitValue = splitValue.join("_");
|
||||
// const elem = e.target.closest(".dropable");
|
||||
// if (elem && selection.length && dragging) {
|
||||
// const value = elem.getAttribute("value");
|
||||
// if (!value) {
|
||||
// setDragging(false);
|
||||
// return;
|
||||
// }
|
||||
// let splitValue = value.split("_");
|
||||
// let item = null;
|
||||
// if (splitValue[0] === "folder") {
|
||||
// splitValue.splice(0, 1);
|
||||
// if (splitValue[splitValue.length - 1] === "draggable") {
|
||||
// splitValue.splice(-1, 1);
|
||||
// }
|
||||
// splitValue = splitValue.join("_");
|
||||
|
||||
item = selection.find((x) => x.id + "" === splitValue && !x.fileExst);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (item) {
|
||||
setDragging(false);
|
||||
return;
|
||||
} else {
|
||||
setDragging(false);
|
||||
this.onMoveTo(splitValue);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
setDragging(false);
|
||||
if (dragItem) {
|
||||
this.onMoveTo(dragItem);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
// item = selection.find((x) => x.id + "" === splitValue && !x.fileExst);
|
||||
// } else {
|
||||
// return;
|
||||
// }
|
||||
// if (item) {
|
||||
// setDragging(false);
|
||||
// return;
|
||||
// } else {
|
||||
// setDragging(false);
|
||||
// this.onMoveTo(splitValue);
|
||||
// return;
|
||||
// }
|
||||
// } else {
|
||||
// setDragging(false);
|
||||
// if (dragItem) {
|
||||
// this.onMoveTo(dragItem);
|
||||
// return;
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
// };
|
||||
|
||||
onMouseMove = (e) => {
|
||||
if (this.state.isDrag) {
|
||||
document.body.classList.add("drag-cursor");
|
||||
!this.props.dragging && this.props.setDragging(true);
|
||||
const tooltip = this.tooltipRef.current;
|
||||
tooltip.style.display = "block";
|
||||
this.setTooltipPosition(e);
|
||||
// onMouseMove = (e) => {
|
||||
// if (this.state.isDrag) {
|
||||
// document.body.classList.add("drag-cursor");
|
||||
// !this.props.dragging && this.props.setDragging(true);
|
||||
// const tooltip = this.tooltipRef.current;
|
||||
// tooltip.style.display = "block";
|
||||
// this.setTooltipPosition(e);
|
||||
|
||||
const wrapperElement = document.elementFromPoint(e.clientX, e.clientY);
|
||||
if (!wrapperElement) {
|
||||
return;
|
||||
}
|
||||
const droppable = wrapperElement.closest(".dropable");
|
||||
// const wrapperElement = document.elementFromPoint(e.clientX, e.clientY);
|
||||
// if (!wrapperElement) {
|
||||
// return;
|
||||
// }
|
||||
// const droppable = wrapperElement.closest(".dropable");
|
||||
|
||||
if (this.currentDroppable !== droppable) {
|
||||
if (this.currentDroppable) {
|
||||
this.currentDroppable.style.background = backgroundDragEnterColor;
|
||||
}
|
||||
this.currentDroppable = droppable;
|
||||
// if (this.currentDroppable !== droppable) {
|
||||
// if (this.currentDroppable) {
|
||||
// this.currentDroppable.style.background = backgroundDragEnterColor;
|
||||
// }
|
||||
// this.currentDroppable = droppable;
|
||||
|
||||
if (this.currentDroppable) {
|
||||
droppable.style.background = backgroundDragColor;
|
||||
this.currentDroppable = droppable;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// if (this.currentDroppable) {
|
||||
// droppable.style.background = backgroundDragColor;
|
||||
// this.currentDroppable = droppable;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
setTooltipPosition = (e) => {
|
||||
const tooltip = this.tooltipRef.current;
|
||||
if (tooltip) {
|
||||
const margin = 8;
|
||||
tooltip.style.left = e.pageX + margin + "px";
|
||||
tooltip.style.top = e.pageY + margin + "px";
|
||||
}
|
||||
};
|
||||
// setTooltipPosition = (e) => {
|
||||
// const tooltip = this.tooltipRef.current;
|
||||
// if (tooltip) {
|
||||
// const margin = 8;
|
||||
// tooltip.style.left = e.pageX + margin + "px";
|
||||
// tooltip.style.top = e.pageY + margin + "px";
|
||||
// }
|
||||
// };
|
||||
|
||||
onMoveTo = (destFolderId) => {
|
||||
const {
|
||||
selection,
|
||||
t,
|
||||
isShare,
|
||||
isCommon,
|
||||
isAdmin,
|
||||
setSecondaryProgressBarData,
|
||||
copyToAction,
|
||||
moveToAction,
|
||||
} = this.props;
|
||||
// onMoveTo = (destFolderId) => {
|
||||
// const {
|
||||
// selection,
|
||||
// t,
|
||||
// isShare,
|
||||
// isCommon,
|
||||
// isAdmin,
|
||||
// setSecondaryProgressBarData,
|
||||
// copyToAction,
|
||||
// moveToAction,
|
||||
// } = this.props;
|
||||
|
||||
const folderIds = [];
|
||||
const fileIds = [];
|
||||
const conflictResolveType = 0; //Skip = 0, Overwrite = 1, Duplicate = 2
|
||||
const deleteAfter = true;
|
||||
// const folderIds = [];
|
||||
// const fileIds = [];
|
||||
// const conflictResolveType = 0; //Skip = 0, Overwrite = 1, Duplicate = 2
|
||||
// const deleteAfter = true;
|
||||
|
||||
setSecondaryProgressBarData({
|
||||
icon: "move",
|
||||
visible: true,
|
||||
percent: 0,
|
||||
label: t("MoveToOperation"),
|
||||
alert: false,
|
||||
});
|
||||
// setSecondaryProgressBarData({
|
||||
// icon: "move",
|
||||
// visible: true,
|
||||
// percent: 0,
|
||||
// label: t("MoveToOperation"),
|
||||
// alert: false,
|
||||
// });
|
||||
|
||||
for (let item of selection) {
|
||||
if (item.fileExst) {
|
||||
fileIds.push(item.id);
|
||||
} else {
|
||||
folderIds.push(item.id);
|
||||
}
|
||||
}
|
||||
// for (let item of selection) {
|
||||
// if (item.fileExst) {
|
||||
// fileIds.push(item.id);
|
||||
// } else {
|
||||
// folderIds.push(item.id);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (isAdmin) {
|
||||
if (isShare) {
|
||||
copyToAction(
|
||||
destFolderId,
|
||||
folderIds,
|
||||
fileIds,
|
||||
conflictResolveType,
|
||||
deleteAfter
|
||||
);
|
||||
} else {
|
||||
moveToAction(
|
||||
destFolderId,
|
||||
folderIds,
|
||||
fileIds,
|
||||
conflictResolveType,
|
||||
deleteAfter
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (isShare || isCommon) {
|
||||
copyToAction(
|
||||
destFolderId,
|
||||
folderIds,
|
||||
fileIds,
|
||||
conflictResolveType,
|
||||
deleteAfter
|
||||
);
|
||||
} else {
|
||||
moveToAction(
|
||||
destFolderId,
|
||||
folderIds,
|
||||
fileIds,
|
||||
conflictResolveType,
|
||||
deleteAfter
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
// if (isAdmin) {
|
||||
// if (isShare) {
|
||||
// copyToAction(
|
||||
// destFolderId,
|
||||
// folderIds,
|
||||
// fileIds,
|
||||
// conflictResolveType,
|
||||
// deleteAfter
|
||||
// );
|
||||
// } else {
|
||||
// moveToAction(
|
||||
// destFolderId,
|
||||
// folderIds,
|
||||
// fileIds,
|
||||
// conflictResolveType,
|
||||
// deleteAfter
|
||||
// );
|
||||
// }
|
||||
// } else {
|
||||
// if (isShare || isCommon) {
|
||||
// copyToAction(
|
||||
// destFolderId,
|
||||
// folderIds,
|
||||
// fileIds,
|
||||
// conflictResolveType,
|
||||
// deleteAfter
|
||||
// );
|
||||
// } else {
|
||||
// moveToAction(
|
||||
// destFolderId,
|
||||
// folderIds,
|
||||
// fileIds,
|
||||
// conflictResolveType,
|
||||
// deleteAfter
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
renderFileMoveTooltip = () => {
|
||||
const { selection, iconOfDraggedFile } = this.props;
|
||||
@ -375,15 +373,15 @@ class SectionBodyContent extends React.Component {
|
||||
);
|
||||
};
|
||||
|
||||
startMoveOperation = () => {
|
||||
this.props.moveToAction(this.props.dragItem);
|
||||
this.onCloseThirdPartyMoveDialog();
|
||||
};
|
||||
// startMoveOperation = () => {
|
||||
// this.props.moveToAction(this.props.dragItem);
|
||||
// this.onCloseThirdPartyMoveDialog();
|
||||
// };
|
||||
|
||||
startCopyOperation = () => {
|
||||
this.props.copyToAction(this.props.dragItem);
|
||||
this.onCloseThirdPartyMoveDialog();
|
||||
};
|
||||
// startCopyOperation = () => {
|
||||
// this.props.copyToAction(this.props.dragItem);
|
||||
// this.onCloseThirdPartyMoveDialog();
|
||||
// };
|
||||
|
||||
render() {
|
||||
//console.log("Files Home SectionBodyContent render", this.props);
|
||||
|
@ -215,7 +215,11 @@ class SectionHeaderContent extends React.Component {
|
||||
|
||||
onMoveAction = () => this.props.setMoveToPanelVisible(true);
|
||||
onCopyAction = () => this.props.setCopyPanelVisible(true);
|
||||
downloadAction = () => this.props.downloadAction(t("ArchivingData"));
|
||||
downloadAction = () =>
|
||||
this.props
|
||||
.downloadAction(this.props.t("ArchivingData"))
|
||||
.catch((err) => toastr.error(err));
|
||||
|
||||
downloadAsAction = () => this.props.setDownloadDialogVisible(true);
|
||||
renameAction = () => toastr.info("renameAction click");
|
||||
onOpenSharingPanel = () => this.props.setSharingPanelVisible(true);
|
||||
@ -237,7 +241,7 @@ class SectionHeaderContent extends React.Component {
|
||||
deleteSelectedElem: t("DeleteSelectedElem"),
|
||||
};
|
||||
|
||||
deleteAction(translations);
|
||||
deleteAction(translations).catch((err) => toastr.error(err));
|
||||
}
|
||||
};
|
||||
|
||||
@ -555,7 +559,6 @@ export default inject(
|
||||
auth,
|
||||
initFilesStore,
|
||||
filesStore,
|
||||
uploadDataStore,
|
||||
dialogsStore,
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
@ -563,7 +566,6 @@ export default inject(
|
||||
settingsStore,
|
||||
}) => {
|
||||
const { setIsLoading } = initFilesStore;
|
||||
const { secondaryProgressDataStore } = uploadDataStore;
|
||||
const {
|
||||
setSelected,
|
||||
fileActionStore,
|
||||
|
@ -274,11 +274,7 @@ class PureHome extends React.Component {
|
||||
</PageLayout.SectionFilter>
|
||||
|
||||
<PageLayout.SectionBody>
|
||||
<SectionBodyContent
|
||||
isMobile={isMobile}
|
||||
onChange={this.onRowChange}
|
||||
onDropZoneUpload={this.onDrop}
|
||||
/>
|
||||
<SectionBodyContent />
|
||||
</PageLayout.SectionBody>
|
||||
|
||||
<PageLayout.SectionPaging>
|
||||
@ -319,7 +315,6 @@ export default inject(
|
||||
filter,
|
||||
fileActionStore,
|
||||
selection,
|
||||
|
||||
setSelections,
|
||||
} = filesStore;
|
||||
|
||||
|
@ -22,8 +22,6 @@ import { FileAction } from "@appserver/common/constants";
|
||||
import { TIMEOUT } from "../helpers/constants";
|
||||
import { loopTreeFolders } from "../helpers/files-helpers";
|
||||
|
||||
//import toastr from "@appserver/components/toast";
|
||||
|
||||
const {
|
||||
fetchFiles,
|
||||
markItemAsFavorite,
|
||||
@ -77,7 +75,7 @@ class FilesActionStore {
|
||||
alert: false,
|
||||
});
|
||||
|
||||
removeFiles(folderIds, fileIds, deleteAfter, immediately)
|
||||
return removeFiles(folderIds, fileIds, deleteAfter, immediately)
|
||||
.then((res) => {
|
||||
const id = res[0] && res[0].id ? res[0].id : null;
|
||||
this.loopDeleteOperation(id, translations);
|
||||
@ -87,7 +85,6 @@ class FilesActionStore {
|
||||
visible: true,
|
||||
alert: true,
|
||||
});
|
||||
//toastr.error(err);
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
});
|
||||
}
|
||||
@ -130,7 +127,6 @@ class FilesActionStore {
|
||||
loopTreeFolders(path, newTreeFolders, folders, foldersCount);
|
||||
setTreeFolders(newTreeFolders);
|
||||
}
|
||||
//toastr.success(successMessage);
|
||||
});
|
||||
}
|
||||
})
|
||||
@ -139,7 +135,6 @@ class FilesActionStore {
|
||||
visible: true,
|
||||
alert: true,
|
||||
});
|
||||
//toastr.error(err);
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
});
|
||||
};
|
||||
@ -147,7 +142,7 @@ class FilesActionStore {
|
||||
getDownloadProgress = (data, label) => {
|
||||
const url = data.url;
|
||||
|
||||
getProgress()
|
||||
return getProgress()
|
||||
.then((res) => {
|
||||
const currentItem = res.find((x) => x.id === data.id);
|
||||
if (!url) {
|
||||
@ -169,7 +164,6 @@ class FilesActionStore {
|
||||
visible: true,
|
||||
alert: true,
|
||||
});
|
||||
//toastr.error(err);
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
});
|
||||
};
|
||||
@ -180,8 +174,9 @@ class FilesActionStore {
|
||||
const folderIds = [];
|
||||
const items = [];
|
||||
|
||||
if (selection.length === 1) {
|
||||
return window.open(selection[0].viewUrl, "_blank");
|
||||
if (selection.length === 1 && selection[0].fileExst) {
|
||||
window.open(selection[0].viewUrl, "_blank");
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
for (let item of selection) {
|
||||
@ -202,7 +197,7 @@ class FilesActionStore {
|
||||
alert: false,
|
||||
});
|
||||
|
||||
downloadFiles(fileIds, folderIds)
|
||||
return downloadFiles(fileIds, folderIds)
|
||||
.then((res) => {
|
||||
this.getDownloadProgress(res[0], label);
|
||||
})
|
||||
@ -211,7 +206,6 @@ class FilesActionStore {
|
||||
visible: true,
|
||||
alert: true,
|
||||
});
|
||||
//toastr.error(err);
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
});
|
||||
};
|
||||
@ -263,7 +257,7 @@ class FilesActionStore {
|
||||
conflictResolveType,
|
||||
deleteAfter
|
||||
) => {
|
||||
copyToFolder(
|
||||
return copyToFolder(
|
||||
destFolderId,
|
||||
folderIds,
|
||||
fileIds,
|
||||
@ -320,7 +314,7 @@ class FilesActionStore {
|
||||
label: translations.deleteOperation,
|
||||
alert: false,
|
||||
});
|
||||
deleteFile(fileId)
|
||||
return deleteFile(fileId)
|
||||
.then((res) => {
|
||||
const id = res[0] && res[0].id ? res[0].id : null;
|
||||
this.loopDeleteProgress(id, currentFolderId, false, translations);
|
||||
@ -330,7 +324,6 @@ class FilesActionStore {
|
||||
visible: true,
|
||||
alert: true,
|
||||
});
|
||||
//toastr.error(err);
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
});
|
||||
};
|
||||
@ -343,7 +336,7 @@ class FilesActionStore {
|
||||
label: translations.deleteOperation,
|
||||
alert: false,
|
||||
});
|
||||
deleteFolder(folderId, currentFolderId)
|
||||
return deleteFolder(folderId, currentFolderId)
|
||||
.then((res) => {
|
||||
const id = res[0] && res[0].id ? res[0].id : null;
|
||||
this.loopDeleteProgress(id, currentFolderId, true, translations);
|
||||
@ -353,7 +346,6 @@ class FilesActionStore {
|
||||
visible: true,
|
||||
alert: true,
|
||||
});
|
||||
//toastr.error(err);
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
});
|
||||
};
|
||||
@ -394,16 +386,12 @@ class FilesActionStore {
|
||||
loopTreeFolders(path, newTreeFolders, folders, foldersCount);
|
||||
setTreeFolders(newTreeFolders);
|
||||
}
|
||||
//isFolder
|
||||
// ? toastr.success(translations.folderRemoved)
|
||||
// : toastr.success(translations.fileRemoved);
|
||||
})
|
||||
.catch((err) => {
|
||||
setSecondaryProgressBarData({
|
||||
visible: true,
|
||||
alert: true,
|
||||
});
|
||||
//toastr.error(err);
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
})
|
||||
.finally(() =>
|
||||
@ -415,22 +403,22 @@ class FilesActionStore {
|
||||
|
||||
lockFileAction = (id, locked) => {
|
||||
setIsLoading(true);
|
||||
lockFile(id, locked).then((res) => {
|
||||
return lockFile(id, locked).then((res) => {
|
||||
/*const newFiles = files;
|
||||
const indexOfFile = newFiles.findIndex(x => x.id === res.id);
|
||||
newFiles[indexOfFile] = res;*/
|
||||
fetchFiles(selectedFolderStore.id, filesStore.filter)
|
||||
//.catch((err) => toastr.error(err))
|
||||
.finally(() => setIsLoading(false));
|
||||
fetchFiles(selectedFolderStore.id, filesStore.filter).finally(() =>
|
||||
setIsLoading(false)
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
finalizeVersionAction = (id) => {
|
||||
setIsLoading(true);
|
||||
|
||||
finalizeVersion(id, 0, false)
|
||||
return finalizeVersion(id, 0, false)
|
||||
.then(() => {
|
||||
return fetchFiles(selectedFolderStore.id, filesStore.filter); //.catch((err) => toastr.error(err));
|
||||
fetchFiles(selectedFolderStore.id, filesStore.filter);
|
||||
})
|
||||
.finally(() => setIsLoading(false));
|
||||
};
|
||||
@ -450,8 +438,8 @@ class FilesActionStore {
|
||||
alert: false,
|
||||
});
|
||||
|
||||
this.copyToAction(
|
||||
selectedFolderId,
|
||||
return this.copyToAction(
|
||||
selectedFolderStore.id,
|
||||
folderIds,
|
||||
fileIds,
|
||||
conflictResolveType,
|
||||
@ -464,20 +452,15 @@ class FilesActionStore {
|
||||
switch (action) {
|
||||
case "mark":
|
||||
return markItemAsFavorite([id]).then(() => getFileInfo(id));
|
||||
//.then(() => toastr.success(t("MarkedAsFavorite")))
|
||||
//.catch((e) => toastr.error(e));
|
||||
|
||||
case "remove":
|
||||
return (
|
||||
removeItemFromFavorite([id])
|
||||
.then(() => {
|
||||
return treeFoldersStore.isFavoritesFolder
|
||||
? fetchFavoritesFolder(selectedFolderId)
|
||||
: getFileInfo(id);
|
||||
})
|
||||
//.then(() => toastr.success(t("RemovedFromFavorites")))
|
||||
.then(() => setSelected("close"))
|
||||
);
|
||||
//.catch((e) => toastr.error(e));
|
||||
return removeItemFromFavorite([id])
|
||||
.then(() => {
|
||||
return treeFoldersStore.isFavoritesFolder
|
||||
? fetchFavoritesFolder(selectedFolderStore.id)
|
||||
: getFileInfo(id);
|
||||
})
|
||||
.then(() => setSelected("close"));
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -636,9 +636,6 @@ class FilesStore {
|
||||
|
||||
const contextOptions = this.getFilesContextOptions(item, canOpenPlayer);
|
||||
|
||||
//let value = fileExst ? `file_${id}` : `folder_${id}`;
|
||||
//value += draggable ? "_draggable" : "";
|
||||
|
||||
//const isCanWebEdit = canWebEdit(item.fileExst);
|
||||
const icon = getIcon(24, fileExst, providerKey);
|
||||
|
||||
@ -669,13 +666,11 @@ class FilesStore {
|
||||
title,
|
||||
updated,
|
||||
updatedBy,
|
||||
//value,
|
||||
version,
|
||||
versionGroup,
|
||||
viewUrl,
|
||||
webUrl,
|
||||
providerKey,
|
||||
//draggable,
|
||||
canOpenPlayer,
|
||||
//canWebEdit: isCanWebEdit,
|
||||
//canShare,
|
||||
@ -836,6 +831,7 @@ class FilesStore {
|
||||
};
|
||||
|
||||
setSelections = (items) => {
|
||||
if (!items.length) return;
|
||||
if (this.selection.length > items.length) {
|
||||
//Delete selection
|
||||
const newSelection = [];
|
||||
|
@ -3,10 +3,14 @@ const CopyPlugin = require("copy-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const ModuleFederationPlugin = require("webpack").container
|
||||
.ModuleFederationPlugin;
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
//const CompressionPlugin = require("compression-webpack-plugin");
|
||||
|
||||
const path = require("path");
|
||||
const pkg = require("./package.json");
|
||||
const deps = pkg.dependencies;
|
||||
const homepage = pkg.homepage;
|
||||
const title = pkg.title;
|
||||
|
||||
var config = {
|
||||
mode: "development",
|
||||
@ -15,7 +19,7 @@ var config = {
|
||||
devServer: {
|
||||
publicPath: homepage,
|
||||
|
||||
contentBase: [path.join(__dirname, "public")],
|
||||
contentBase: [path.join(__dirname, "dist")],
|
||||
contentBasePublicPath: homepage,
|
||||
port: 5008,
|
||||
historyApiFallback: {
|
||||
@ -41,9 +45,11 @@ var config = {
|
||||
},
|
||||
|
||||
output: {
|
||||
publicPath: "auto", //homepage
|
||||
chunkFilename: "[id].[contenthash].js",
|
||||
publicPath: "auto",
|
||||
chunkFilename: "js/[id].[contenthash].js",
|
||||
assetModuleFilename: "assets/[hash][ext][query]",
|
||||
path: path.resolve(process.cwd(), "dist"),
|
||||
filename: "[name].[contenthash].bundle.js",
|
||||
},
|
||||
|
||||
resolve: {
|
||||
@ -55,6 +61,10 @@ var config = {
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|ico)$/i,
|
||||
type: "asset/resource",
|
||||
},
|
||||
{
|
||||
test: /\.m?js/,
|
||||
type: "javascript/auto",
|
||||
@ -139,6 +149,7 @@ var config = {
|
||||
new HtmlWebpackPlugin({
|
||||
template: "./public/index.html",
|
||||
publicPath: homepage,
|
||||
title: title,
|
||||
//base: `${homepage}/`,
|
||||
}),
|
||||
new CopyPlugin({
|
||||
@ -159,6 +170,21 @@ var config = {
|
||||
module.exports = (env, argv) => {
|
||||
if (argv.mode === "production") {
|
||||
config.mode = "production";
|
||||
config.optimization = {
|
||||
splitChunks: { chunks: "all" },
|
||||
minimize: true,
|
||||
minimizer: [new TerserPlugin()],
|
||||
};
|
||||
// config.plugins.push(
|
||||
// new CompressionPlugin({
|
||||
// filename: "[path][base].gz[query]",
|
||||
// algorithm: "gzip",
|
||||
// test: /\.js(\?.*)?$/i,
|
||||
// threshold: 10240,
|
||||
// minRatio: 0.8,
|
||||
// deleteOriginalAssets: true,
|
||||
// })
|
||||
// );
|
||||
} else {
|
||||
config.devtool = "cheap-module-source-map";
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"private": "true",
|
||||
"homepage": "/products/people",
|
||||
"title": "ONLYOFFICE",
|
||||
"scripts": {
|
||||
"start": "webpack-cli serve",
|
||||
"build": "webpack --mode production",
|
||||
@ -19,6 +20,7 @@
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"compression-webpack-plugin": "^7.1.2",
|
||||
"copy-webpack-plugin": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
|
@ -89,7 +89,7 @@
|
||||
height: 36px;
|
||||
}
|
||||
</style>
|
||||
<title>ONLYOFFICE</title>
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript> You need to enable JavaScript to run this app. </noscript>
|
||||
@ -109,7 +109,7 @@
|
||||
ry="3"
|
||||
width="24"
|
||||
height="24"
|
||||
style="fill: url('#fill0')"
|
||||
style="fill: url('#fill0');"
|
||||
></rect>
|
||||
<defs>
|
||||
<linearGradient id="fill0">
|
||||
@ -135,7 +135,7 @@
|
||||
ry="3"
|
||||
width="168"
|
||||
height="24"
|
||||
style="fill: url('#fill01')"
|
||||
style="fill: url('#fill01');"
|
||||
></rect>
|
||||
<defs>
|
||||
<linearGradient id="fill01">
|
||||
@ -163,7 +163,7 @@
|
||||
r="18"
|
||||
width="36"
|
||||
height="36"
|
||||
style="fill: url('#fill02')"
|
||||
style="fill: url('#fill02');"
|
||||
></circle>
|
||||
<defs>
|
||||
<linearGradient id="fill02">
|
||||
@ -193,7 +193,7 @@
|
||||
width="100%"
|
||||
height="100%"
|
||||
clip-path="url(#clip-path1)"
|
||||
style="fill: url('#fill1')"
|
||||
style="fill: url('#fill1');"
|
||||
></rect>
|
||||
<defs>
|
||||
<clipPath id="clip-path1">
|
||||
@ -223,7 +223,7 @@
|
||||
width="100%"
|
||||
height="100%"
|
||||
clip-path="url(#clip-path2)"
|
||||
style="fill: url('#fill2')"
|
||||
style="fill: url('#fill2');"
|
||||
></rect>
|
||||
<defs>
|
||||
<clipPath id="clip-path2">
|
||||
|
@ -3,10 +3,14 @@ const CopyPlugin = require("copy-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const ModuleFederationPlugin = require("webpack").container
|
||||
.ModuleFederationPlugin;
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
//const CompressionPlugin = require("compression-webpack-plugin");
|
||||
|
||||
const path = require("path");
|
||||
const pkg = require("./package.json");
|
||||
const deps = pkg.dependencies;
|
||||
const homepage = pkg.homepage;
|
||||
const title = pkg.title;
|
||||
|
||||
var config = {
|
||||
mode: "development",
|
||||
@ -15,7 +19,7 @@ var config = {
|
||||
devServer: {
|
||||
publicPath: homepage,
|
||||
|
||||
contentBase: [path.join(__dirname, "public")],
|
||||
contentBase: [path.join(__dirname, "dist")],
|
||||
contentBasePublicPath: homepage,
|
||||
port: 5002,
|
||||
historyApiFallback: {
|
||||
@ -41,9 +45,11 @@ var config = {
|
||||
},
|
||||
|
||||
output: {
|
||||
publicPath: "auto", //homepage
|
||||
chunkFilename: "[id].[contenthash].js",
|
||||
publicPath: "auto",
|
||||
chunkFilename: "js/[id].[contenthash].js",
|
||||
assetModuleFilename: "assets/[hash][ext][query]",
|
||||
path: path.resolve(process.cwd(), "dist"),
|
||||
filename: "[name].[contenthash].bundle.js",
|
||||
},
|
||||
|
||||
resolve: {
|
||||
@ -55,6 +61,10 @@ var config = {
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|ico)$/i,
|
||||
type: "asset/resource",
|
||||
},
|
||||
{
|
||||
test: /\.m?js/,
|
||||
type: "javascript/auto",
|
||||
@ -140,6 +150,7 @@ var config = {
|
||||
new HtmlWebpackPlugin({
|
||||
template: "./public/index.html",
|
||||
publicPath: homepage,
|
||||
title: title,
|
||||
//base: `${homepage}/`,
|
||||
}),
|
||||
new CopyPlugin({
|
||||
@ -160,6 +171,21 @@ var config = {
|
||||
module.exports = (env, argv) => {
|
||||
if (argv.mode === "production") {
|
||||
config.mode = "production";
|
||||
config.optimization = {
|
||||
splitChunks: { chunks: "all" },
|
||||
minimize: true,
|
||||
minimizer: [new TerserPlugin()],
|
||||
};
|
||||
// config.plugins.push(
|
||||
// new CompressionPlugin({
|
||||
// filename: "[path][base].gz[query]",
|
||||
// algorithm: "gzip",
|
||||
// test: /\.js(\?.*)?$/i,
|
||||
// threshold: 10240,
|
||||
// minRatio: 0.8,
|
||||
// deleteOriginalAssets: true,
|
||||
// })
|
||||
// );
|
||||
} else {
|
||||
config.devtool = "cheap-module-source-map";
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"private": "true",
|
||||
"homepage": "",
|
||||
"title": "ONLYOFFICE",
|
||||
"scripts": {
|
||||
"start": "webpack-cli serve",
|
||||
"build": "webpack --mode production",
|
||||
@ -18,15 +19,18 @@
|
||||
"@babel/preset-react": "^7.12.10",
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"compression-webpack-plugin": "^7.1.2",
|
||||
"copy-webpack-plugin": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
"json-loader": "^0.5.7",
|
||||
"serve": "11.3.2",
|
||||
"source-map-loader": "^1.1.2",
|
||||
"style-loader": "1.2.1",
|
||||
"webpack": "5.14.0",
|
||||
"webpack-cli": "4.5.0",
|
||||
"webpack-dev-server": "3.11.2",
|
||||
"serve": "11.3.2"
|
||||
"webpack-dev-server": "3.11.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
|
@ -91,12 +91,12 @@
|
||||
height: 36px;
|
||||
}
|
||||
</style>
|
||||
<title>ONLYOFFICE</title>
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript> You need to enable JavaScript to run this app. </noscript>
|
||||
<div class="ipl-progress-indicator" id="ipl-progress-indicator"></div>
|
||||
<div id="temp-content" style="display: none">
|
||||
<div id="temp-content" style="display: none;">
|
||||
<header class="temp-header-container">
|
||||
<div id="burger-loader-svg" class="burger-loader-svg">
|
||||
<svg
|
||||
@ -111,7 +111,7 @@
|
||||
ry="3"
|
||||
width="24"
|
||||
height="24"
|
||||
style="fill: url('#fill0')"
|
||||
style="fill: url('#fill0');"
|
||||
></rect>
|
||||
<defs>
|
||||
<linearGradient id="fill0">
|
||||
@ -137,7 +137,7 @@
|
||||
ry="3"
|
||||
width="168"
|
||||
height="24"
|
||||
style="fill: url('#fill01')"
|
||||
style="fill: url('#fill01');"
|
||||
></rect>
|
||||
<defs>
|
||||
<linearGradient id="fill01">
|
||||
@ -165,7 +165,7 @@
|
||||
r="18"
|
||||
width="36"
|
||||
height="36"
|
||||
style="fill: url('#fill02')"
|
||||
style="fill: url('#fill02');"
|
||||
></circle>
|
||||
<defs>
|
||||
<linearGradient id="fill02">
|
||||
@ -194,7 +194,7 @@
|
||||
width="100%"
|
||||
height="100%"
|
||||
clip-path="url(#clip-path1)"
|
||||
style="fill: url('#fill1')"
|
||||
style="fill: url('#fill1');"
|
||||
></rect>
|
||||
<defs>
|
||||
<clipPath id="clip-path1">
|
||||
|
@ -1,17 +1,23 @@
|
||||
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const ModuleFederationPlugin = require("webpack").container
|
||||
.ModuleFederationPlugin;
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
//const CompressionPlugin = require("compression-webpack-plugin");
|
||||
|
||||
const path = require("path");
|
||||
const pkg = require("./package.json");
|
||||
const deps = pkg.dependencies;
|
||||
const homepage = pkg.homepage;
|
||||
const title = pkg.title;
|
||||
|
||||
const config = {
|
||||
entry: "./src/index",
|
||||
mode: "development",
|
||||
|
||||
devServer: {
|
||||
contentBase: path.join(__dirname, "public"),
|
||||
contentBase: [path.join(__dirname, "dist")],
|
||||
port: 5001,
|
||||
historyApiFallback: {
|
||||
// Paths with dots should still use the history fallback.
|
||||
@ -44,12 +50,18 @@ const config = {
|
||||
|
||||
output: {
|
||||
publicPath: "auto",
|
||||
chunkFilename: "[id].[contenthash].js",
|
||||
chunkFilename: "js/[id].[contenthash].js",
|
||||
assetModuleFilename: "assets/[hash][ext][query]",
|
||||
path: path.resolve(process.cwd(), "dist"),
|
||||
filename: "[name].[contenthash].bundle.js",
|
||||
},
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|ico)$/i,
|
||||
type: "asset/resource",
|
||||
},
|
||||
{
|
||||
test: /\.m?js/,
|
||||
type: "javascript/auto",
|
||||
@ -108,12 +120,13 @@ const config = {
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new ModuleFederationPlugin({
|
||||
name: "studio",
|
||||
filename: "remoteEntry.js",
|
||||
remotes: {
|
||||
studio: `studio@${homepage}/remoteEntry.js`,
|
||||
people: `people@${homepage}/products/people//remoteEntry.js`,
|
||||
people: `people@${homepage}/products/people/remoteEntry.js`,
|
||||
files: `files@${homepage}/products/files/remoteEntry.js`,
|
||||
login: `login@${homepage}/login/remoteEntry.js`,
|
||||
},
|
||||
@ -147,6 +160,19 @@ const config = {
|
||||
new HtmlWebpackPlugin({
|
||||
template: "./public/index.html",
|
||||
publicPath: homepage,
|
||||
title: title,
|
||||
}),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: "public",
|
||||
globOptions: {
|
||||
dot: true,
|
||||
gitignore: true,
|
||||
ignore: ["**/index.html"],
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
};
|
||||
@ -154,6 +180,21 @@ const config = {
|
||||
module.exports = (env, argv) => {
|
||||
if (argv.mode === "production") {
|
||||
config.mode = "production";
|
||||
config.optimization = {
|
||||
splitChunks: { chunks: "all" },
|
||||
minimize: true,
|
||||
minimizer: [new TerserPlugin()],
|
||||
};
|
||||
// config.plugins.push(
|
||||
// new CompressionPlugin({
|
||||
// filename: "[path][base].gz[query]",
|
||||
// algorithm: "gzip",
|
||||
// test: /\.js(\?.*)?$/i,
|
||||
// threshold: 10240,
|
||||
// minRatio: 0.8,
|
||||
// deleteOriginalAssets: true,
|
||||
// })
|
||||
// );
|
||||
} else {
|
||||
config.devtool = "cheap-module-source-map";
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"private": "true",
|
||||
"homepage": "/products/files/doceditor",
|
||||
"title": "ONLYOFFICE",
|
||||
"scripts": {
|
||||
"start": "webpack-cli serve",
|
||||
"build": "webpack --mode production",
|
||||
@ -19,6 +20,7 @@
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"compression-webpack-plugin": "^7.1.2",
|
||||
"copy-webpack-plugin": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
|
@ -34,7 +34,7 @@
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
|
||||
<title>ONLYOFFICE</title>
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript> You need to enable JavaScript to run this app. </noscript>
|
||||
|
@ -3,19 +3,24 @@ const CopyPlugin = require("copy-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const ModuleFederationPlugin = require("webpack").container
|
||||
.ModuleFederationPlugin;
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const CompressionPlugin = require("compression-webpack-plugin");
|
||||
|
||||
const path = require("path");
|
||||
const pkg = require("./package.json");
|
||||
const deps = pkg.dependencies;
|
||||
const homepage = pkg.homepage;
|
||||
const title = pkg.title;
|
||||
|
||||
var config = {
|
||||
mode: "development",
|
||||
const config = {
|
||||
entry: "./src/index",
|
||||
target: "web",
|
||||
mode: "development",
|
||||
|
||||
devServer: {
|
||||
publicPath: homepage,
|
||||
|
||||
contentBase: [path.join(__dirname, "public")],
|
||||
contentBase: [path.join(__dirname, "dist")],
|
||||
contentBasePublicPath: homepage,
|
||||
port: 5013,
|
||||
historyApiFallback: {
|
||||
@ -40,12 +45,6 @@ var config = {
|
||||
},
|
||||
},
|
||||
|
||||
output: {
|
||||
publicPath: "auto", //homepage
|
||||
chunkFilename: "[id].[contenthash].js",
|
||||
path: path.resolve(process.cwd(), "dist"),
|
||||
},
|
||||
|
||||
resolve: {
|
||||
extensions: [".jsx", ".js", ".json"],
|
||||
fallback: {
|
||||
@ -53,8 +52,20 @@ var config = {
|
||||
},
|
||||
},
|
||||
|
||||
output: {
|
||||
publicPath: "auto",
|
||||
chunkFilename: "js/[id].[contenthash].js",
|
||||
assetModuleFilename: "assets/[hash][ext][query]",
|
||||
path: path.resolve(process.cwd(), "dist"),
|
||||
filename: "[name].[contenthash].bundle.js",
|
||||
},
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|ico)$/i,
|
||||
type: "asset/resource",
|
||||
},
|
||||
{
|
||||
test: /\.m?js/,
|
||||
type: "javascript/auto",
|
||||
@ -69,13 +80,17 @@ var config = {
|
||||
loader: "@svgr/webpack",
|
||||
options: {
|
||||
svgoConfig: {
|
||||
plugins: [{ removeViewbox: false }],
|
||||
plugins: [{ removeViewBox: false }],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{ test: /\.json$/, loader: "json-loader" },
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: ["style-loader", "css-loader"],
|
||||
},
|
||||
{
|
||||
test: /\.s[ac]ss$/i,
|
||||
use: [
|
||||
@ -132,26 +147,42 @@ var config = {
|
||||
new HtmlWebpackPlugin({
|
||||
template: "./public/index.html",
|
||||
publicPath: homepage,
|
||||
title: title,
|
||||
//base: `${homepage}/`,
|
||||
}),
|
||||
// new CopyPlugin({
|
||||
// patterns: [
|
||||
// {
|
||||
// from: "public",
|
||||
// globOptions: {
|
||||
// dot: true,
|
||||
// gitignore: true,
|
||||
// ignore: ["**/index.html"],
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// }),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: "public",
|
||||
globOptions: {
|
||||
dot: true,
|
||||
gitignore: true,
|
||||
ignore: ["**/index.html"],
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = (env, argv) => {
|
||||
if (argv.mode === "production") {
|
||||
config.mode = "production";
|
||||
config.optimization = {
|
||||
splitChunks: { chunks: "all" },
|
||||
minimize: true,
|
||||
minimizer: [new TerserPlugin()],
|
||||
};
|
||||
config.plugins.push(
|
||||
new CompressionPlugin({
|
||||
filename: "[path][base].gz[query]",
|
||||
algorithm: "gzip",
|
||||
test: /\.js(\?.*)?$/i,
|
||||
threshold: 10240,
|
||||
minRatio: 0.8,
|
||||
deleteOriginalAssets: true,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
config.devtool = "cheap-module-source-map";
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"private": "true",
|
||||
"homepage": "/login",
|
||||
"title": "ONLYOFFICE",
|
||||
"scripts": {
|
||||
"start": "webpack-cli serve",
|
||||
"build": "webpack --mode production",
|
||||
@ -19,6 +20,7 @@
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"compression-webpack-plugin": "^7.1.2",
|
||||
"copy-webpack-plugin": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
|
@ -1,14 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Login</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
-->
|
||||
<link id="favicon" rel="shortcut icon" href="favicon.ico" />
|
||||
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
<!-- Tell the browser it's a PWA -->
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<!-- Tell iOS it's a PWA -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<link rel="apple-touch-icon" href="appIcon.png" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i"
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
/>
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript> You need to enable JavaScript to run this app. </noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
<script>
|
||||
console.log("It's LOGIN INIT");
|
||||
console.log("It's Login INIT");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -3,10 +3,14 @@ const CopyPlugin = require("copy-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const ModuleFederationPlugin = require("webpack").container
|
||||
.ModuleFederationPlugin;
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
//const CompressionPlugin = require("compression-webpack-plugin");
|
||||
|
||||
const path = require("path");
|
||||
const pkg = require("./package.json");
|
||||
const deps = pkg.dependencies;
|
||||
const homepage = pkg.homepage;
|
||||
const title = pkg.title;
|
||||
|
||||
var config = {
|
||||
mode: "development",
|
||||
@ -15,7 +19,7 @@ var config = {
|
||||
devServer: {
|
||||
publicPath: homepage,
|
||||
|
||||
contentBase: [path.join(__dirname, "public")],
|
||||
contentBase: [path.join(__dirname, "dist")],
|
||||
contentBasePublicPath: homepage,
|
||||
port: 5011,
|
||||
historyApiFallback: {
|
||||
@ -41,9 +45,11 @@ var config = {
|
||||
},
|
||||
|
||||
output: {
|
||||
publicPath: "auto", //homepage
|
||||
chunkFilename: "[id].[contenthash].js",
|
||||
publicPath: "auto",
|
||||
chunkFilename: "js/[id].[contenthash].js",
|
||||
assetModuleFilename: "assets/[hash][ext][query]",
|
||||
path: path.resolve(process.cwd(), "dist"),
|
||||
filename: "[name].[contenthash].bundle.js",
|
||||
},
|
||||
|
||||
resolve: {
|
||||
@ -55,6 +61,10 @@ var config = {
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|ico)$/i,
|
||||
type: "asset/resource",
|
||||
},
|
||||
{
|
||||
test: /\.m?js/,
|
||||
type: "javascript/auto",
|
||||
@ -69,7 +79,7 @@ var config = {
|
||||
loader: "@svgr/webpack",
|
||||
options: {
|
||||
svgoConfig: {
|
||||
plugins: [{ removeViewbox: false }],
|
||||
plugins: [{ removeViewBox: false }],
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -134,6 +144,7 @@ var config = {
|
||||
new HtmlWebpackPlugin({
|
||||
template: "./public/index.html",
|
||||
publicPath: homepage,
|
||||
title: title,
|
||||
//base: `${homepage}/`,
|
||||
}),
|
||||
new CopyPlugin({
|
||||
@ -154,6 +165,21 @@ var config = {
|
||||
module.exports = (env, argv) => {
|
||||
if (argv.mode === "production") {
|
||||
config.mode = "production";
|
||||
config.optimization = {
|
||||
splitChunks: { chunks: "all" },
|
||||
minimize: true,
|
||||
minimizer: [new TerserPlugin()],
|
||||
};
|
||||
// config.plugins.push(
|
||||
// new CompressionPlugin({
|
||||
// filename: "[path][base].gz[query]",
|
||||
// algorithm: "gzip",
|
||||
// test: /\.js(\?.*)?$/i,
|
||||
// threshold: 10240,
|
||||
// minRatio: 0.8,
|
||||
// deleteOriginalAssets: true,
|
||||
// })
|
||||
// );
|
||||
} else {
|
||||
config.devtool = "cheap-module-source-map";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user