Merge branch 'master' into share-links

This commit is contained in:
Tom Moor
2018-05-22 21:27:45 -07:00
9 changed files with 76 additions and 42 deletions

View File

@ -4,7 +4,7 @@
<p align="center">
<i>An open, extensible, wiki for your team built using React and Node.js.<br/>Try out Outline using our hosted version at <a href="https://www.getoutline.com">www.getoutline.com</a>.</i>
<br/>
<img src="https://user-images.githubusercontent.com/31465/34456332-51e41eb0-ed9c-11e7-9fa9-20e7fa946494.jpg" alt="Outline" width="800" height="500">
<img src="https://user-images.githubusercontent.com/31465/34456332-51e41eb0-ed9c-11e7-9fa9-20e7fa946494.jpg" alt="Outline" width="800" />
</p>
<p align="center">
<img src="https://circleci.com/gh/outline/outline.svg?style=shield&amp;circle-token=c0c4c2f39990e277385d5c1ae96169c409eb887a" alt="" data-canonical-src="" style="max-width:100%;">
@ -63,12 +63,13 @@ Outline is composed of separate backend and frontend application which are both
### Frontend
Outline's frontend is a React application compiled with [Webpack](https://webpack.js.org/). It uses [Mobx](https://mobx.js.org/) for state management and [Styled Components](https://www.styled-components.com/) for component styles. Unless global, state logic and styles are always co-located with React components together with their subcomponents to make the component tree easier to manage. The editor is driven by [Slate](https://github.com/ianstormtaylor/slate) with several plugins.
Outline's frontend is a React application compiled with [Webpack](https://webpack.js.org/). It uses [Mobx](https://mobx.js.org/) for state management and [Styled Components](https://www.styled-components.com/) for component styles. Unless global, state logic and styles are always co-located with React components together with their subcomponents to make the component tree easier to manage.
The editor itself is built ontop of [Slate](https://github.com/ianstormtaylor/slate) and hosted in a separate repository to encourage reuse: [rich-markdown-editor](https://github.com/outline/rich-markdown-editor)
- `app/` - Frontend React application
- `app/scenes` - Full page views
- `app/components` - Reusable React components
- `app/components/Editor` - Text editor and its plugins
- `app/stores` - Global state stores
- `app/models` - State models
- `app/types` - Flow types for non-models

View File

@ -29,7 +29,7 @@ class SettingsSidebar extends React.Component<Props> {
return (
<Sidebar>
<HeaderBlock
subheading="◄ Return to Dashboard"
subheading="◄ Return to App"
teamName={team.name}
logoUrl={team.avatarUrl}
onClick={this.returnToDashboard}

View File

@ -35,9 +35,9 @@ function HeaderBlock({
}
const StyledExpandedIcon = styled(ExpandedIcon)`
position: relative;
top: 6px;
left: -4px;
position: absolute;
right: 0;
top: 0;
`;
const Subheading = styled.div`
@ -49,8 +49,9 @@ const Subheading = styled.div`
`;
const TeamName = styled.div`
position: relative;
padding-left: 10px;
margin-top: ${props => (props.showDisclosure ? '-8px' : '0')};
padding-right: 24px;
font-weight: 600;
color: ${color.text};
text-decoration: none;

View File

@ -155,21 +155,11 @@
"react-waypoint": "^7.3.1",
"redis": "^2.6.2",
"redis-lock": "^0.1.0",
"rich-markdown-editor": "^1.0.0",
"rich-markdown-editor": "^1.1.0",
"safestart": "1.1.0",
"sequelize": "4.28.6",
"sequelize-cli": "^2.7.0",
"sequelize-encrypted": "0.1.0",
"slate": "^0.32.5",
"slate-collapse-on-escape": "^0.6.0",
"slate-edit-code": "^0.14.0",
"slate-edit-list": "^0.11.2",
"slate-md-serializer": "3.0.3",
"slate-paste-linkify": "^0.5.0",
"slate-plain-serializer": "0.5.4",
"slate-prism": "^0.5.0",
"slate-react": "^0.12.3",
"slate-trailing-block": "^0.5.0",
"slug": "0.9.1",
"string-hash": "^1.1.0",
"string-replace-to-array": "^1.0.3",

View File

@ -8,6 +8,15 @@ Object {
}
`;
exports[`#documents.delete should require authentication 1`] = `
Object {
"error": "authentication_required",
"message": "Authentication required",
"ok": false,
"status": 401,
}
`;
exports[`#documents.list should require authentication 1`] = `
Object {
"error": "authentication_required",

View File

@ -428,7 +428,7 @@ router.post('documents.delete', auth(), async ctx => {
authorize(ctx.state.user, 'delete', document);
const collection = document.collection;
if (collection.type === 'atlas') {
if (collection && collection.type === 'atlas') {
// Delete document and all of its children
await collection.removeDocument(document);
}

View File

@ -618,3 +618,41 @@ describe('#documents.update', async () => {
expect(res.status).toEqual(403);
});
});
describe('#documents.delete', async () => {
it('should allow deleting document', async () => {
const { user, document } = await seed();
const res = await server.post('/api/documents.delete', {
body: { token: user.getJwtToken(), id: document.id },
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.success).toEqual(true);
});
it('should allow deleting document without collection', async () => {
const { user, document, collection } = await seed();
// delete collection without hooks to trigger document deletion
await collection.destroy({ hooks: false });
const res = await server.post('/api/documents.delete', {
body: { token: user.getJwtToken(), id: document.id },
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.success).toEqual(true);
});
it('should require authentication', async () => {
const { document } = await seed();
const res = await server.post('/api/documents.delete', {
body: { id: document.id },
});
const body = await res.json();
expect(res.status).toEqual(401);
expect(body).toMatchSnapshot();
});
});

View File

@ -1,9 +1,8 @@
// @flow
import _ from 'lodash';
import naturalSort from 'natural-sort';
export default (sortableArray: Object[], key: string) => {
export default (sortableArray: Object[] = [], key: string) => {
let keys = sortableArray.map(object => object[key]);
keys.sort(naturalSort());
return _.sortBy(sortableArray, object => keys.indexOf(object[key]));

View File

@ -8762,9 +8762,9 @@ retry-as-promised@^2.3.1:
bluebird "^3.4.6"
debug "^2.6.9"
rich-markdown-editor@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/rich-markdown-editor/-/rich-markdown-editor-1.0.0.tgz#ae540474e8e4e86b41d339d20cee0572c9794d2b"
rich-markdown-editor@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/rich-markdown-editor/-/rich-markdown-editor-1.1.0.tgz#178307255bba4777c5b0f991202b522e5e0850a1"
dependencies:
"@tommoor/slate-drop-or-paste-images" "^0.8.1"
boundless-arrow-key-navigation "^1.1.0"
@ -8778,11 +8778,11 @@ rich-markdown-editor@^1.0.0:
react-keydown "^1.9.7"
react-medium-image-zoom "^3.0.10"
react-portal "^4.1.4"
slate "^0.32.5"
slate "^0.33.6"
slate-collapse-on-escape "^0.6.0"
slate-edit-code "^0.14.0"
slate-edit-list "^0.11.2"
slate-md-serializer "3.0.4"
slate-md-serializer "3.1.0"
slate-paste-linkify "^0.5.0"
slate-plain-serializer "0.5.4"
slate-prism "^0.5.0"
@ -9143,13 +9143,9 @@ slate-edit-list@^0.11.2:
version "0.11.2"
resolved "https://registry.yarnpkg.com/slate-edit-list/-/slate-edit-list-0.11.2.tgz#c67b961d98435f9f7747d20b870cbc51d25af7a8"
slate-md-serializer@3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/slate-md-serializer/-/slate-md-serializer-3.0.3.tgz#194aaf74b8c5158cdd45f8d2394a1a1574acaf83"
slate-md-serializer@3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/slate-md-serializer/-/slate-md-serializer-3.0.4.tgz#0ee04c0c2e44954b82f9fab1410b658bb6191aad"
slate-md-serializer@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/slate-md-serializer/-/slate-md-serializer-3.1.0.tgz#8e82899c45a607615b19e03d42cbd38cc7f64acf"
slate-paste-linkify@^0.5.0:
version "0.5.0"
@ -9202,26 +9198,26 @@ slate-react@^0.12.3:
slate-plain-serializer "^0.5.9"
slate-prop-types "^0.4.26"
slate-schema-violations@^0.1.3:
version "0.1.7"
resolved "https://registry.yarnpkg.com/slate-schema-violations/-/slate-schema-violations-0.1.7.tgz#cf2c6156eaf545f4d1985d3d1b94c50d6d273a08"
slate-schema-violations@^0.1.10:
version "0.1.10"
resolved "https://registry.yarnpkg.com/slate-schema-violations/-/slate-schema-violations-0.1.10.tgz#165227c230ea6c1027e523b7171a73e860e73646"
slate-trailing-block@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/slate-trailing-block/-/slate-trailing-block-0.5.0.tgz#cedb4f2975f1167e0fb9d259ce1252b82f4d74ff"
slate@^0.32.5:
version "0.32.5"
resolved "https://registry.yarnpkg.com/slate/-/slate-0.32.5.tgz#5386c75dec1e5b87648189c9fbb4294cec623ff0"
slate@^0.33.6:
version "0.33.6"
resolved "https://registry.yarnpkg.com/slate/-/slate-0.33.6.tgz#0c7cb193cc5adeecec5c81e2ec0c86ab23dd6755"
dependencies:
debug "^2.3.2"
debug "^3.1.0"
direction "^0.1.5"
esrever "^0.2.0"
is-empty "^1.0.0"
is-plain-object "^2.0.4"
lodash "^4.17.4"
slate-dev-logger "^0.1.39"
slate-schema-violations "^0.1.3"
slate-schema-violations "^0.1.10"
type-of "^2.0.1"
slice-ansi@0.0.4: