@@ -552,25 +593,8 @@ export default class DataView extends React.Component {
);
const footer = (
-
-
- {Object.keys(this.state.checked).length ? (
- {
- return !!elem;
- })
- }
- >
- Delete {Object.keys(this.state.checked).length} file
- {Object.keys(this.state.checked).length > 1 ? "s" : ""}
-
- ) : null}
-
-
+ {Object.keys(this.state.checked).length ? (
+
+
+
+ {Object.keys(this.state.checked).length} files selected
+
+
+
+
+ Add to slate
+
+ {
+ return !!elem;
+ })
+ }
+ >
+ Delete files
+
+
+
+ ) : null}
+
);
if (this.state.view === "grid") {
return (
@@ -640,7 +690,19 @@ export default class DataView extends React.Component {
const columns = [
{
key: "checkbox",
- name:
,
+ name: Object.keys(this.state.checked).length ? (
+
this.setState({ checked: {} })}
+ >
+
+
+ ) : (
+
+ ),
width: "24px",
},
{
@@ -667,7 +729,7 @@ export default class DataView extends React.Component {
return {
...each,
- checkbox: this._handleCheckBox ? (
+ checkbox: (
- ) : (
-
),
name: (
numItems
- ? props.slate.data.objects.slice(0, numItems)
- : props.slate.data.objects;
+ let objects;
+ if (props.slate.data.objects.length === 0) {
+ objects = [
+
,
+ ];
+ } else {
+ let trimmed =
+ props.slate.data.objects.length > numItems
+ ? props.slate.data.objects.slice(0, numItems)
+ : props.slate.data.objects;
+ objects = trimmed.map((each) => (
+
+
+
+ ));
+ }
+ let numExtra = props.numItems
+ ? props.numItems - objects.length
+ : 5 - objects.length;
+ let extra = [];
+ for (let i = 0; i < numExtra; i++) {
+ extra.push(
+
+ );
+ }
return (
- {objects.map((each) => (
-
-
-
- ))}
+ {objects}
+ {extra}
);
}
const STYLES_BLOCK = css`
- box-shadow: 0 0 0 1px ${Constants.system.border} inset;
+ box-shadow: 0 0 0 1px rgba(229, 229, 229, 0.75) inset,
+ 0 0 40px 0 ${Constants.system.shadow};
border-radius: 8px;
padding: 32px 40px;
font-size: 12px;
@@ -153,17 +197,6 @@ const STYLES_BODY = css`
word-wrap: break-word;
`;
-const STYLES_CREATE_NEW = css`
- color: ${Constants.system.darkGray};
- box-shadow: 0px 0px 0px 1px rgba(229, 229, 229, 0.5) inset;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- width: 160px;
- height: 160px;
-`;
-
const STYLES_ICON_BOX = css`
height: 32px;
width: 32px;
@@ -354,20 +387,10 @@ export default class SlatePreviewBlock extends React.Component {
) : (
)}
- {this.props.slate.data.objects &&
- this.props.slate.data.objects.length ? (
-
- ) : (
-
- )}
+
);
}
diff --git a/components/core/Table.js b/components/core/Table.js
index 50a77e1d..3865b97f 100644
--- a/components/core/Table.js
+++ b/components/core/Table.js
@@ -20,6 +20,7 @@ const TABLE_COLUMN_WIDTH_DEFAULTS = {
const STYLES_CONTAINER = css`
border: 1px solid rgba(229, 229, 229, 0.75);
+ box-shadow: 0 0 40px 0 ${Constants.system.shadow};
`;
const STYLES_TABLE_ROW = css`
diff --git a/components/sidebars/SidebarAddFileToSlate.js b/components/sidebars/SidebarAddFileToSlate.js
new file mode 100644
index 00000000..5881a181
--- /dev/null
+++ b/components/sidebars/SidebarAddFileToSlate.js
@@ -0,0 +1,180 @@
+import * as React from "react";
+import * as Strings from "~/common/strings";
+import * as Constants from "~/common/constants";
+import * as System from "~/components/system";
+import * as Validations from "~/common/validations";
+import * as SVG from "~/common/svg";
+import * as Actions from "~/common/actions";
+
+import { dispatchCustomEvent } from "~/common/custom-events";
+import { css } from "@emotion/react";
+import { ButtonPrimary } from "~/components/system/components/Buttons";
+
+const STYLES_SLATE_NAME = css`
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-family: ${Constants.font.medium};
+`;
+
+const STYLES_HEADER = css`
+ font-family: ${Constants.font.semiBold};
+ font-size: 18px;
+ margin-top: 32px;
+ margin-bottom: 16px;
+`;
+
+const STYLES_SLATE_LIST = css`
+ max-height: 400px;
+ overflow-y: scroll;
+`;
+
+const STYLES_SLATE_LINE = css`
+ display: flex;
+ align-items: center;
+ width: 100%;
+ padding: 12px 16px;
+ background-color: ${Constants.system.white};
+ margin-bottom: 1px;
+ cursor: pointer;
+`;
+
+const STYLES_ICON_BOX = css`
+ display: flex;
+ align-items: center;
+`;
+
+export default class SidebarAddFileToSlate extends React.Component {
+ state = {
+ selected: {},
+ };
+
+ _handleCreateSlate = async () => {
+ if (
+ Object.values(this.state.selected).some((value) => {
+ return !!value;
+ })
+ ) {
+ await this._handleSubmit();
+ }
+ await this.props.onCancel();
+ this.props.onAction({
+ type: "SIDEBAR",
+ value: "SIDEBAR_CREATE_SLATE",
+ data: this.props.sidebarData,
+ });
+ };
+
+ _handleAdd = (slate) => {
+ if (this.state.selected[slate.id]) {
+ this.setState({
+ selected: { ...this.state.selected, [slate.id]: false },
+ });
+ } else {
+ this.setState({
+ selected: { ...this.state.selected, [slate.id]: slate },
+ });
+ }
+ };
+
+ _handleSubmit = async () => {
+ let data = this.props.sidebarData.files.map((file) => {
+ return { title: file.name, ...file };
+ });
+ for (let slate of Object.values(this.state.selected)) {
+ if (!slate) continue;
+ const addResponse = await Actions.addFileToSlate({ slate, data });
+
+ if (!addResponse) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
+ return;
+ } else if (addResponse.error) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: addResponse.decorator } },
+ });
+ return;
+ }
+ }
+ await this.props.onRehydrate();
+ dispatchCustomEvent({
+ name: "remote-update-carousel",
+ detail: null,
+ });
+ this.props.onCancel();
+ };
+
+ render() {
+ return (
+
+
+ Add files to slate
+
+
+
Slates
+
+
+
+ Create new slate
+
+
+
+ {this.props.viewer.slates.map((slate) => (
+
this._handleAdd(slate)}>
+
+ {this.state.selected[slate.id] ? (
+
+ ) : (
+
+ )}
+
+
+ {slate.data.name || slate.slatename}
+
+
+ ))}
+
+
+ Add to slates
+
+
+ );
+ }
+}
diff --git a/components/sidebars/SidebarCreateSlate.js b/components/sidebars/SidebarCreateSlate.js
index 675703d1..3225b49a 100644
--- a/components/sidebars/SidebarCreateSlate.js
+++ b/components/sidebars/SidebarCreateSlate.js
@@ -3,6 +3,7 @@ import * as Strings from "~/common/strings";
import * as Constants from "~/common/constants";
import * as System from "~/components/system";
import * as Validations from "~/common/validations";
+import * as Actions from "~/common/actions";
import { dispatchCustomEvent } from "~/common/custom-events";
import { css } from "@emotion/react";
@@ -87,6 +88,48 @@ export default class SidebarCreateSlate extends React.Component {
return;
}
+ if (
+ this.props.sidebarData &&
+ this.props.sidebarData.files &&
+ this.props.sidebarData.files[0].decorator === "FILE"
+ ) {
+ let data = this.props.sidebarData.files.map((file) => {
+ return { title: file.name, ...file };
+ });
+ const addResponse = await Actions.addFileToSlate({
+ slate: response.slate,
+ data,
+ });
+
+ if (!addResponse) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: {
+ alert: {
+ message:
+ "We're having trouble connecting right now. Please try again later",
+ },
+ },
+ });
+ return;
+ }
+
+ if (addResponse.error) {
+ dispatchCustomEvent({
+ name: "create-alert",
+ detail: { alert: { decorator: response.decorator } },
+ });
+ return;
+ }
+
+ await this.props.onRehydrate();
+
+ dispatchCustomEvent({
+ name: "remote-update-carousel",
+ detail: null,
+ });
+ }
+
this.setState({ loading: false });
this.props.onAction({
type: "NAVIGATE",
diff --git a/components/sidebars/SidebarHelp.js b/components/sidebars/SidebarHelp.js
index b781abae..d5fb18e6 100644
--- a/components/sidebars/SidebarHelp.js
+++ b/components/sidebars/SidebarHelp.js
@@ -28,7 +28,7 @@ export default class SidebarCreateSlate extends React.Component {
_handleSubmit = async () => {
this.setState({ loading: true });
- if (!this.state.email || !this.state.email.length) {
+ if (Strings.isEmpty(this.state.email)) {
dispatchCustomEvent({
name: "create-alert",
detail: {
@@ -54,17 +54,6 @@ export default class SidebarCreateSlate extends React.Component {
return;
}
- if (!Validations.email(this.state.email)) {
- dispatchCustomEvent({
- name: "create-alert",
- detail: {
- alert: { message: "Please check that your email address is valid" },
- },
- });
- this.setState({ loading: false });
- return;
- }
-
const response = await Actions.createSupportMessage({
username: this.props.viewer.username,
name: this.state.name,
diff --git a/components/system/components/Buttons.js b/components/system/components/Buttons.js
index b39e60f6..a23ad5ef 100644
--- a/components/system/components/Buttons.js
+++ b/components/system/components/Buttons.js
@@ -11,32 +11,13 @@ const STYLES_BUTTON = `
outline: 0;
border: 0;
min-height: 40px;
- padding: 6px 24px 6px 24px;
+ padding: 4px 16px;
display: inline-flex;
align-items: center;
justify-content: center;
- font-size: 12px;
+ font-size: 14px;
letter-spacing: 0.2px;
- font-family: ${Constants.font.semiBold};
- transition: 200ms ease all;
- overflow-wrap: break-word;
- user-select: none;
-`;
-
-const STYLES_BUTTON_FULL = `
- box-sizing: border-box;
- border-radius: 4px;
- outline: 0;
- border: 0;
- min-height: 40px;
- padding: 6px 24px 6px 24px;
- display: flex;
- width: 100%;
- align-items: center;
- justify-content: center;
- font-size: 12px;
- letter-spacing: 0.2px;
- font-family: ${Constants.font.semiBold};
+ font-family: ${Constants.font.medium};
transition: 200ms ease all;
overflow-wrap: break-word;
user-select: none;
@@ -60,30 +41,25 @@ const STYLES_BUTTON_PRIMARY = css`
}
`;
-const STYLES_BUTTON_PRIMARY_FULL = css`
- ${STYLES_BUTTON_FULL}
+const STYLES_BUTTON_PRIMARY_TRANSPARENT = css`
+ ${STYLES_BUTTON}
+ ${"" /* font-size: 16px;
+ font-family: ${Constants.font.medium}; */}
cursor: pointer;
- background-color: ${Constants.system.brand};
- color: ${Constants.system.white};
-
- :hover {
- background-color: #065ca8;
- }
-
- :focus {
- box-shadow: inset 0 0 5px 2px rgba(0, 0, 0, 0.3);
- background-color: #065ca8;
- outline: 0;
- border: 0;
- }
+ background-color: transparent;
+ color: ${Constants.system.brand};
`;
export const ButtonPrimary = (props) => {
if (props.loading) {
return (
@@ -93,8 +69,12 @@ export const ButtonPrimary = (props) => {
if (props.type === "label") {
return (