make docs shared in ui

This commit is contained in:
2019-09-13 14:28:40 +03:00
parent 28f4b1a339
commit 1ee06d674d
7 changed files with 117 additions and 24 deletions

View File

@@ -97,8 +97,22 @@
flex-shrink: 0;
flex-grow: 0;
button {
div {
height: 100%;
width: 3rem;
>* {
width: 100%;
height: 100%;
.bp3-popover-target {
width: 100%;
height: 100%;
button {
width: 100%;
height: 100%;
}
}
}
}
}
@@ -203,6 +217,7 @@
}
.document {
textarea,
.documentContents {
transition: 0.3s;
@@ -239,4 +254,4 @@
}
}
}
}
}

View File

@@ -1,6 +1,13 @@
import "./Docs.scss";
import { Button, Classes, TextArea } from "@blueprintjs/core";
import {
Button,
Classes,
Menu,
MenuItem,
Popover,
TextArea,
} from "@blueprintjs/core";
import * as React from "react";
import { connect } from "react-redux";
import { RouteComponentProps, withRouter } from "react-router";
@@ -29,7 +36,12 @@ export interface IDocumentEditComponentProps extends RouteComponentProps {
deleteDoc: (id: number) => void;
cancelDelete: () => void;
uploadDocs: () => void;
updateDoc: (id: number, name: string, content: string) => void;
updateDoc: (
id: number,
name: string,
content: string,
shared: boolean,
) => void;
}
export interface IDocumentEditComponentState {
@@ -52,6 +64,7 @@ export class DocumentEditComponent extends React.PureComponent<
this.state = defaultDocumentEditComponentState;
this.handleInputChange = this.handleInputChange.bind(this);
this.handleNameKeyPress = this.handleNameKeyPress.bind(this);
this.share = this.share.bind(this);
this.remove = this.remove.bind(this);
this.save = this.save.bind(this);
this.onUnload = this.onUnload.bind(this);
@@ -74,18 +87,48 @@ export class DocumentEditComponent extends React.PureComponent<
onKeyPress={this.handleNameKeyPress}
/>
<div className="buttons">
<Button
icon="trash"
minimal={true}
intent="danger"
onClick={this.remove}
/>
<Button
icon="tick"
intent="success"
minimal={true}
onClick={this.save}
/>
<div>
<Popover
target={
<Button
icon="document-share"
minimal={true}
intent={
doc.shared ? "success" : "none"
}
/>
}
content={
<Menu>
<MenuItem
icon="globe"
text={
doc.shared
? "Remove access"
: "Make public"
}
onClick={this.share}
/>
</Menu>
}
/>
</div>
<div>
<Button
icon="trash"
minimal={true}
intent="danger"
onClick={this.remove}
/>
</div>
<div>
<Button
icon="tick"
intent="success"
minimal={true}
onClick={this.save}
/>
</div>
</div>
</div>
<TextArea
@@ -121,6 +164,15 @@ export class DocumentEditComponent extends React.PureComponent<
}
}
public share() {
const doc = this.props.allDocs[this.state.id];
const updShared = !doc.shared;
this.props.updateDoc(this.state.id, doc.name, doc.content, updShared);
this.upload();
}
public handleInputChange(
event:
| React.FormEvent<HTMLInputElement>
@@ -138,7 +190,12 @@ export class DocumentEditComponent extends React.PureComponent<
};
updDoc[name] = value;
this.props.updateDoc(this.state.id, updDoc.name, updDoc.content);
this.props.updateDoc(
this.state.id,
updDoc.name,
updDoc.content,
doc.shared,
);
}
public componentDidUpdate() {
@@ -193,8 +250,12 @@ function mapDispatchToProps(dispatch: Dispatch) {
cancelDelete: () => dispatch(deleteDocCancel()),
deleteDoc: (id: number) => dispatch(deleteDocStart(id)),
uploadDocs: () => dispatch(uploadDocsStart()),
updateDoc: (id: number, name: string, content: string) =>
dispatch(updateDoc(id, name, content)),
updateDoc: (
id: number,
name: string,
content: string,
shared: boolean,
) => dispatch(updateDoc(id, name, content, shared)),
};
}

View File

@@ -23,8 +23,13 @@ export async function patchDoc(
id: number,
name?: string,
content?: string,
shared?: boolean,
): Promise<IAPIResponse<IDocumentJSON>> {
return fetchJSONAuth(`/docs/byID/${id}`, "PATCH", { name, content });
return fetchJSONAuth(`/docs/byID/${id}`, "PATCH", {
name,
content,
shared,
});
}
export async function deleteDoc(id: number): Promise<IAPIResponse<boolean>> {

View File

@@ -180,6 +180,7 @@ export interface IDocUpdateAction extends Action {
id: number;
name: string;
content: string;
shared: boolean;
};
}
@@ -187,8 +188,12 @@ export function updateDoc(
id: number,
name: string,
content: string,
shared: boolean,
): IDocUpdateAction {
return { type: DocsTypes.DOC_UPDATE, payload: { id, name, content } };
return {
type: DocsTypes.DOC_UPDATE,
payload: { id, name, content, shared },
};
}
export type DocsAction =

View File

@@ -99,12 +99,14 @@ export const docsReducer: Reducer<IDocsState, DocsAction> = (
const remote = doc.remote;
if (
payload.content !== remote.content ||
payload.name !== remote.name
payload.name !== remote.name ||
payload.shared !== remote.shared
) {
all[payload.id] = {
...doc,
content: payload.content,
name: payload.name,
shared: payload.shared,
dirty: true,
};
dirty = true;
@@ -113,6 +115,7 @@ export const docsReducer: Reducer<IDocsState, DocsAction> = (
...doc,
content: payload.content,
name: payload.name,
shared: payload.shared,
dirty: false,
};
const dirtyDocs = Object.values(all).filter(e => e.dirty);

View File

@@ -146,7 +146,7 @@ function* docsUploadStart(action: IDocsUploadStartAction) {
for (const doc of changedDocs) {
const { response, timeout } = yield race({
response: call(patchDoc, doc.id, doc.name, doc.content),
response: call(patchDoc, doc.id, doc.name, doc.content, doc.shared),
timeout: delay(10000),
});