publish: choose group for groupify

This commit is contained in:
Liam Fitzgerald 2020-09-08 15:04:45 +10:00
parent 73881aa25f
commit f320631230
8 changed files with 110 additions and 32 deletions

View File

@ -82,11 +82,11 @@ export default class PublishApi extends BaseApi {
return this.action('publish', 'publish-action', act);
}
groupify(bookId: string) {
groupify(bookId: string, group: Path | null) {
return this.publishAction({
groupify: {
book: bookId,
target: null,
target: group,
inclusive: false
}
});

View File

@ -163,6 +163,7 @@ export default function PublishApp(props: PublishAppProps) {
hideNicknames={hideNicknames}
hideAvatars={hideAvatars}
remoteContentPolicy={remoteContentPolicy}
associations={associations}
{...props}
/>
);

View File

@ -0,0 +1,77 @@
import React, { useEffect } from "react";
import { Box, Col, Button, InputLabel, InputCaption } from "@tlon/indigo-react";
import * as Yup from "yup";
import GlobalApi from "~/logic/api/global";
import { Notebook } from "~/types/publish-update";
import { Contacts } from "~/types/contact-update";
import { MetadataForm } from "./MetadataForm";
import { Groups, Associations } from "~/types";
import { Formik, FormikHelpers, Form } from "formik";
import GroupSearch from "~/views/components/GroupSearch";
import { AsyncButton } from "~/views/components/AsyncButton";
const formSchema = Yup.object({
group: Yup.string().nullable(),
});
interface FormSchema {
group: string | null;
}
interface GroupifyFormProps {
host: string;
book: string;
notebook: Notebook;
groups: Groups;
api: GlobalApi;
associations: Associations;
}
export function GroupifyForm(props: GroupifyFormProps) {
const onGroupify = async (
values: FormSchema,
actions: FormikHelpers<FormSchema>
) => {
try {
await props.api.publish.groupify(props.book, values.group);
actions.setStatus({ success: null });
} catch (e) {
actions.setStatus({ error: e.message });
}
};
const groupPath = props.notebook?.["writers-group-path"];
const isUnmanaged = props.groups?.[groupPath]?.hidden || false;
if (!isUnmanaged) {
return null;
}
const initialValues: FormSchema = {
group: null
};
return (
<Formik
validationSchema={formSchema}
initialValues={initialValues}
onSubmit={onGroupify}
>
<Form style={{ display: "contents" }}>
<GroupSearch
id="group"
label="Group"
caption="What group should this notebook be added to? If blank, a new group will be made for the notebook"
associations={props.associations}
/>
<AsyncButton loadingText="Groupifying..." border>
Groupify
</AsyncButton>
</Form>
</Formik>
);
}
export default GroupifyForm;

View File

@ -50,7 +50,6 @@ const ResetOnPropsChange = (props: { init: FormSchema; book: string }) => {
export function MetadataForm(props: MetadataFormProps) {
const { host, notebook, api, book } = props;
const history = useHistory();
const initialValues: FormSchema = {
name: notebook?.title,
description: notebook?.about,
@ -72,11 +71,6 @@ export function MetadataForm(props: MetadataFormProps) {
}
};
const onDelete = async () => {
await api.publish.delBook(book);
history.push("/~publish");
};
return (
<Formik
validationSchema={formSchema}
@ -84,16 +78,6 @@ export function MetadataForm(props: MetadataFormProps) {
onSubmit={onSubmit}
>
<Form style={{ display: "contents" }}>
<Col mb={4}>
<InputLabel>Delete Notebook</InputLabel>
<InputCaption>
Permanently delete this notebook. (All current members will no
longer see this notebook.)
</InputCaption>
<Button onClick={onDelete} mt={1} border error>
Delete this notebook
</Button>
</Col>
<Input
id="name"
label="Rename"

View File

@ -20,6 +20,7 @@ import { Groups } from "~/types/group-update";
import { Contacts, Rolodex } from "~/types/contact-update";
import GlobalApi from "~/logic/api/global";
import styled from "styled-components";
import {Associations} from "~/types";
const TabList = styled(_TabList)`
margin-bottom: ${(p) => p.theme.space[4]}px;
@ -38,6 +39,7 @@ interface NotebookProps {
contacts: Rolodex;
groups: Groups;
hideNicknames: boolean;
associations: Associations;
}
export function Notebook(props: NotebookProps & RouteComponentProps) {
@ -130,6 +132,7 @@ export function Notebook(props: NotebookProps & RouteComponentProps) {
api={api}
notebook={notebook}
contacts={notebookContacts}
associations={props.associations}
groups={groups}
/>
</TabPanel>

View File

@ -9,7 +9,7 @@ import { Contacts, Rolodex } from "../../../../types/contact-update";
import Notebook from "./Notebook";
import NewPost from "./new-post";
import { NoteRoutes } from './NoteRoutes';
import { LocalUpdateRemoteContentPolicy } from "~/types";
import { LocalUpdateRemoteContentPolicy, Associations } from "~/types";
interface NotebookRoutesProps {
api: GlobalApi;
@ -23,6 +23,7 @@ interface NotebookRoutesProps {
hideAvatars: boolean;
hideNicknames: boolean;
remoteContentPolicy: LocalUpdateRemoteContentPolicy;
associations: Associations;
}
export function NotebookRoutes(

View File

@ -5,7 +5,9 @@ import { Notebook } from "~/types/publish-update";
import { Contacts } from "~/types/contact-update";
import { MetadataForm } from "./MetadataForm";
import { Groups } from "~/types";
import { Groups, Associations } from "~/types";
import GroupifyForm from "./GroupifyForm";
import { useHistory } from "react-router-dom";
interface SettingsProps {
host: string;
@ -14,13 +16,18 @@ interface SettingsProps {
contacts: Contacts;
groups: Groups;
api: GlobalApi;
associations: Associations;
}
const Divider = (props) => (
<Box {...props} mb={4} borderBottom={1} borderBottomColor="lightGray" />
);
export function Settings(props: SettingsProps) {
const onGroupify = () => {
return props.api.publish.groupify(props.book);
const history = useHistory();
const onDelete = async () => {
await props.api.publish.delBook(props.book);
history.push("/~publish");
};
const groupPath = props.notebook?.["writers-group-path"];
const isUnmanaged = props.groups?.[groupPath]?.hidden || false;
@ -36,17 +43,22 @@ export function Settings(props: SettingsProps) {
>
{isUnmanaged && (
<>
<Col mb={4}>
<InputLabel>Groupify</InputLabel>
<InputCaption>Turn this notebook into a group</InputCaption>
<Button onClick={onGroupify} border>
Groupify
</Button>
</Col>
<Box mb={4} borderBottom={1} borderBottomColor="washedGray" />
<GroupifyForm {...props} />
<Divider mt={4} />
</>
)}
<MetadataForm {...props} />
<Divider />
<Col mb={4}>
<InputLabel>Delete Notebook</InputLabel>
<InputCaption>
Permanently delete this notebook. (All current members will no longer
see this notebook.)
</InputCaption>
<Button onClick={onDelete} mt={1} border error>
Delete this notebook
</Button>
</Col>
</Box>
);
}

View File

@ -88,7 +88,7 @@ export function GroupSearch(props: InviteSearchProps) {
caption={props.caption}
candidates={groups}
renderCandidate={renderCandidate}
disabled={value.length !== 0}
disabled={value && value.length !== 0}
search={(s: string, a: Association) =>
a.metadata.title.toLowerCase().startsWith(s.toLowerCase())
}