slate: support normal names for slates and not just slug names

This commit is contained in:
@wwwjim 2020-08-25 21:41:05 -07:00
parent 8e432232c0
commit 8de00917d0
6 changed files with 102 additions and 36 deletions

View File

@ -2,6 +2,7 @@ import * as React from "react";
import * as Actions from "~/common/actions";
import * as Constants from "~/common/constants";
import * as System from "~/components/system";
import * as Strings from "~/common/strings";
import { css } from "@emotion/react";
@ -33,6 +34,7 @@ export default class SidebarSingleSlateSettings extends React.Component {
public: this.props.data.data.public,
body: this.props.data.data.body,
layouts: this.props.data.data.layouts,
name: this.props.data.data.name,
loading: false,
};
@ -41,8 +43,8 @@ export default class SidebarSingleSlateSettings extends React.Component {
const response = await Actions.updateSlate({
id: this.props.data.slateId,
slatename: this.state.slatename,
data: {
name: this.state.name,
objects: this.props.data.data.objects,
layouts: this.props.data.data.layouts,
public: this.state.public,
@ -74,7 +76,11 @@ export default class SidebarSingleSlateSettings extends React.Component {
_handleDelete = async (e) => {
this.setState({ loading: true });
if (!window.confirm("Are you sure you want to delete this Slate? This action is irreversible.")) {
if (
!window.confirm(
"Are you sure you want to delete this Slate? This action is irreversible."
)
) {
return this.setState({ loading: false });
}
@ -102,33 +108,42 @@ export default class SidebarSingleSlateSettings extends React.Component {
render() {
const { slatename } = this.state;
const url = `/${this.props.viewer.username}/${slatename}`;
const slug = Strings.createSlug(this.state.name);
const url = `/${this.props.viewer.username}/${slug}`;
return (
<React.Fragment>
<System.P style={{ fontFamily: Constants.font.semiBold }}>Slate Settings</System.P>
<System.P style={{ marginTop: 24 }}>Update settings for {this.props.data.slatename}.</System.P>
<System.P style={{ fontFamily: Constants.font.semiBold }}>
Slate Settings
</System.P>
<System.P style={{ marginTop: 24 }}>
Update settings for {this.props.data.slatename}.
</System.P>
<System.Input
containerStyle={{ marginTop: 48 }}
style={{ marginTop: 24 }}
label="Slatename"
label="Slate name"
description={
<React.Fragment>
Changing the slatename will change your public slate URL. Your slate URL is:{" "}
Changing the slatename will change your public slate URL. Your
slate URL is:{" "}
<a href={url} target="_blank">
https://slate.host{url}
</a>
</React.Fragment>
}
name="slatename"
value={this.state.slatename}
placeholder="Slatename"
name="name"
value={this.state.name}
placeholder="Name"
onChange={this._handleChange}
onSubmit={this._handleSubmit}
/>
<System.DescriptionGroup label="Description" style={{ marginTop: 48 }} />
<System.DescriptionGroup
label="Description"
style={{ marginTop: 48 }}
/>
<System.Textarea
style={{ marginTop: 24 }}
label="Description"
@ -147,17 +162,29 @@ export default class SidebarSingleSlateSettings extends React.Component {
/>
</div>
<div css={STYLES_RIGHT}>
<System.Toggle name="public" onChange={this._handleChange} active={this.state.public} />
<System.Toggle
name="public"
onChange={this._handleChange}
active={this.state.public}
/>
</div>
</div>
<div style={{ marginTop: 32 }}>
<System.ButtonPrimary full onClick={this._handleSubmit} loading={this.state.loading}>
<System.ButtonPrimary
full
onClick={this._handleSubmit}
loading={this.state.loading}
>
Save changes
</System.ButtonPrimary>
{!this.state.loading ? (
<System.ButtonSecondary style={{ marginTop: 16 }} full onClick={this._handleCancel}>
<System.ButtonSecondary
style={{ marginTop: 16 }}
full
onClick={this._handleCancel}
>
Cancel
</System.ButtonSecondary>
) : null}
@ -173,7 +200,11 @@ export default class SidebarSingleSlateSettings extends React.Component {
{!this.state.loading ? (
<div style={{ marginTop: 32 }}>
<System.ButtonSecondary full onClick={this._handleDelete} loading={this.state.loading}>
<System.ButtonSecondary
full
onClick={this._handleDelete}
loading={this.state.loading}
>
Delete {this.props.data.slatename}
</System.ButtonSecondary>
</div>

View File

@ -46,7 +46,7 @@ export default async (req, res) => {
}
const slate = await Data.createSlate({
slatename,
slatename: Strings.createSlug(req.body.data.name),
data: {
public: true,
ownerId: id,

View File

@ -12,7 +12,9 @@ export default async (req, res) => {
const id = Utilities.getIdFromCookie(req);
if (!id) {
return res.status(500).json({ decorator: "SERVER_FIND_USER_UPDATE_SLATE", error: true });
return res
.status(500)
.json({ decorator: "SERVER_FIND_USER_UPDATE_SLATE", error: true });
}
const user = await Data.getUserById({
@ -36,32 +38,51 @@ export default async (req, res) => {
const response = await Data.getSlateById({ id: req.body.data.id });
if (!response) {
return res.status(404).json({ decorator: "SERVER_UPDATE_SLATE_NOT_FOUND", error: true });
return res
.status(404)
.json({ decorator: "SERVER_UPDATE_SLATE_NOT_FOUND", error: true });
}
if (response.error) {
return res.status(500).json({ decorator: "SERVER_UPDATE_SLATE_NOT_FOUND", error: true });
return res
.status(500)
.json({ decorator: "SERVER_UPDATE_SLATE_NOT_FOUND", error: true });
}
if (!req.body.data) {
return res.status(500).json({
decorator: "SERVER_UPDATE_SLATE_MUST_PROVIDE_DATA",
error: true,
});
}
if (!req.body.data.data.name) {
return res.status(500).json({
decorator: "SERVER_UPDATE_SLATE_MUST_PROVIDE_NAME",
error: true,
});
}
const slate = await Data.updateSlateById({
id: response.id,
slatename: Strings.createSlug(req.body.data.slatename),
slatename: Strings.createSlug(req.body.data.data.name),
updated_at: new Date(),
data: {
...response.data,
objects: req.body.data.data.objects,
layouts: req.body.data.data.layouts,
public: req.body.data.data.public,
body: req.body.data.data.body,
...req.body.data.data,
},
});
if (!slate) {
return res.status(404).json({ decorator: "SERVER_UPDATE_SLATE", error: true });
return res
.status(404)
.json({ decorator: "SERVER_UPDATE_SLATE", error: true });
}
if (slate.error) {
return res.status(500).json({ decorator: "SERVER_UPDATE_SLATE", error: true });
return res
.status(500)
.json({ decorator: "SERVER_UPDATE_SLATE", error: true });
}
return res.status(200).json({ decorator: "SERVER_UPDATE_SLATE", slate });

View File

@ -20,7 +20,7 @@ export default class SceneHome extends React.Component {
const slates = {
columns: [
{
key: "slatename",
key: "name",
name: "Slate Name",
width: "100%",
type: "SLATE_LINK",
@ -41,7 +41,10 @@ export default class SceneHome extends React.Component {
rows: this.props.viewer.slates.map((each) => {
return {
...each,
url: `https://slate.host/${this.props.viewer.username}/${each.slatename}`,
url: `https://slate.host/${this.props.viewer.username}/${
each.slatename
}`,
name: each.data.name,
public: each.data.public,
objects: <span css={STYLES_NUMBER}>{each.data.objects.length}</span>,
};
@ -49,7 +52,9 @@ export default class SceneHome extends React.Component {
};
// TODO(jim): Refactor later.
const slateButtons = [{ name: "Create slate", type: "SIDEBAR", value: "SIDEBAR_CREATE_SLATE" }];
const slateButtons = [
{ name: "Create slate", type: "SIDEBAR", value: "SIDEBAR_CREATE_SLATE" },
];
/*
// TODO(jim): Refactor later.
@ -87,9 +92,15 @@ export default class SceneHome extends React.Component {
return (
<ScenePage>
<ScenePageHeader title="Home [WIP]">This scene is currently a work in progress.</ScenePageHeader>
<ScenePageHeader title="Home [WIP]">
This scene is currently a work in progress.
</ScenePageHeader>
<Section title="Slates" buttons={slateButtons} onAction={this.props.onAction}>
<Section
title="Slates"
buttons={slateButtons}
onAction={this.props.onAction}
>
<System.Table
data={slates}
name="slate"

View File

@ -22,6 +22,7 @@ const moveIndex = (set, fromIndex, toIndex) => {
export default class SceneSlate extends React.Component {
state = {
name: this.props.current.data.name,
slatename: this.props.current.slatename,
public: this.props.current.data.public,
objects: this.props.current.data.objects,
@ -63,6 +64,7 @@ export default class SceneSlate extends React.Component {
public: this.props.current.data.public,
objects: this.props.current.data.objects,
body: this.props.current.data.body,
name: this.props.current.data.name,
layouts: layouts,
loading: false,
});
@ -92,12 +94,12 @@ export default class SceneSlate extends React.Component {
const response = await Actions.updateSlate({
id: this.props.current.slateId,
slatename: this.state.slatename,
data: {
objects: objects ? objects : this.state.objects,
layouts: layouts ? layouts : this.state.layouts,
public: this.state.public,
body: this.state.body,
name: this.state.name,
},
});
@ -198,12 +200,12 @@ export default class SceneSlate extends React.Component {
const response = await Actions.updateSlate({
id: this.props.current.slateId,
slatename: this.state.slatename,
data: {
objects,
layouts,
public: this.state.public,
body: this.state.body,
name: this.state.name,
},
});
@ -256,13 +258,13 @@ export default class SceneSlate extends React.Component {
};
render() {
const { slatename, objects, body = "A slate." } = this.state;
const { slatename, objects, body = "A slate.", name } = this.state;
return (
<ScenePage style={{ padding: `88px 24px 128px 24px` }}>
<ScenePageHeader
style={{ padding: `0 24px 0 24px` }}
title={slatename}
title={name}
actions={
<React.Fragment>
<CircleButtonLight

View File

@ -20,7 +20,7 @@ export default class SceneSlates extends React.Component {
const slates = {
columns: [
{
key: "slatename",
key: "name",
name: "Slate Name",
width: "100%",
type: "SLATE_LINK",
@ -41,6 +41,7 @@ export default class SceneSlates extends React.Component {
rows: this.props.viewer.slates.map((each) => {
return {
...each,
name: each.data.name,
url: `https://slate.host/${this.props.viewer.username}/${
each.slatename
}`,