1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-08-09 15:35:27 +02:00

Compare commits

..

No commits in common. "master" and "v1.48.0" have entirely different histories.

3972 changed files with 811941 additions and 578744 deletions

View file

@ -1,6 +1,3 @@
.DS_Store
.git
bin
.idea
selfcert
gui/dist-prod

38
.gitignore vendored
View file

@ -18,9 +18,8 @@ _convert
bin/*
dist/*
embed/bindata/*
edition/static/*
gui/dist/*
gui/dist-prod/*
app/dist/*
app/dist-prod/*
# Architecture specific extensions/prefixes
*.[568vq]
@ -39,35 +38,28 @@ _testmain.go
/plugin-libreoffice/plugin-libreoffice-osx
# Ember specific
/gui/dist
/gui/dist-prod
/gui/tmp
/gui/bower_components
/gui/node_modules
/gui/.sass-cache
/gui/connect.lock
/gui/coverage/*
/gui/libpeerconnection.log
/gui/npm-debug.log
/gui/testem.log
/app/dist
/app/dist-prod
/app/tmp
/app/bower_components
/app/node_modules
/app/.sass-cache
/app/connect.lock
/app/coverage/*
/app/libpeerconnection.log
/app/npm-debug.log
/app/testem.log
node_modules
# Misc.
build
plugin-msword/plugin-msword
plugin-msword/plugin-msword-osx
npm-debug.log
debug
*.pem
*.crt
Dockerfile
container.sh
make.sh
jsconfig.json
yarn-error.log
testem.log
# ember-try
.node_modules.ember-try/
bower.json.ember-try
package.json.ember-try
embed/bindata_assetfs.go
dmz-backup*.zip
*.conf

62
.jsbeautifyrc Normal file
View file

@ -0,0 +1,62 @@
{
"css": {
"indent_size": 4,
"indent_level": 0,
"indent_with_tabs": true,
"preserve_newlines": true,
"max_preserve_newlines": 2,
"newline_between_rules": true,
"selector_separator_newlines": true
},
"scss": {
"indent_size": 4,
"indent_level": 0,
"indent_with_tabs": true,
"preserve_newlines": true,
"max_preserve_newlines": 2,
"newline_between_rules": true,
"selector_separator_newlines": true
},
"html": {
"indent_size": 4,
"indent_level": 0,
"indent_with_tabs": true,
"preserve_newlines": true,
"max_preserve_newlines": 2,
"wrap_line_length": 0,
"indent_handlebars": true,
"indent_inner_html": false,
"indent_scripts": "keep"
},
"hbs": {
"indent_size": 4,
"indent_level": 0,
"indent_with_tabs": true,
"max_preserve_newlines": 2,
"preserve_newlines": true,
"wrap_line_length": 0
},
"js": {
"indent_size": 4,
"indent_level": 0,
"indent_with_tabs": true,
"preserve_newlines": true,
"wrap_line_length": 0,
"break_chained_methods": false,
"max_preserve_newlines": 2,
"jslint_happy": true,
"brace_style": "collapse-preserve-inline",
"keep_function_indentation": false,
"space_after_anon_function": false,
"space_before_anon_function": false,
"space_before_conditional": true,
"space_in_empty_paren": false,
"space_before_func_paren": false,
"space_in_paren": false
},
"sql": {
"indent_size": 4,
"indent_level": 0,
"indent_with_tabs": true
}
}

4
.jshintignore Normal file
View file

@ -0,0 +1,4 @@
app/public/tinymce/**
app/public/tinymce/
app/public/tinymce

View file

@ -1,3 +1,3 @@
Please see this document for contribution guidelines and process:
https://docs.documize.com/s/leFaXwlU/open-source/d/VzO94aMOCgABGyfe/contributing
https://developers.documize.com/s/leFaXwlU/open-source/d/VzO94aMOCgABGyfe/contributing

View file

@ -1,32 +0,0 @@
FROM node:16-alpine as frontbuilder
WORKDIR /go/src/github.com/documize/community/gui
COPY ./gui /go/src/github.com/documize/community/gui
RUN npm --network-timeout=100000 install
RUN npm run build -- --environment=production --output-path dist-prod --suppress-sizes true
FROM golang:1.21-alpine as builder
WORKDIR /go/src/github.com/documize/community
COPY . /go/src/github.com/documize/community
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/assets /go/src/github.com/documize/community/edition/static/public/assets
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/codemirror /go/src/github.com/documize/community/edition/static/public/codemirror
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/prism /go/src/github.com/documize/community/edition/static/public/prism
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/sections /go/src/github.com/documize/community/edition/static/public/sections
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/tinymce /go/src/github.com/documize/community/edition/static/public/tinymce
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/pdfjs /go/src/github.com/documize/community/edition/static/public/pdfjs
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/i18n /go/src/github.com/documize/community/edition/static/public/i18n
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/*.* /go/src/github.com/documize/community/edition/static/
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/i18n/*.json /go/src/github.com/documize/community/edition/static/i18n/
COPY domain/mail/*.html /go/src/github.com/documize/community/edition/static/mail/
COPY core/database/templates/*.html /go/src/github.com/documize/community/edition/static/
COPY core/database/scripts/mysql/*.sql /go/src/github.com/documize/community/edition/static/scripts/mysql/
COPY core/database/scripts/postgresql/*.sql /go/src/github.com/documize/community/edition/static/scripts/postgresql/
COPY core/database/scripts/sqlserver/*.sql /go/src/github.com/documize/community/edition/static/scripts/sqlserver/
COPY domain/onboard/*.json /go/src/github.com/documize/community/edition/static/onboard/
RUN env GODEBUG=tls13=1 go build -mod=vendor -o bin/documize-community ./edition/community.go
# build release image
FROM alpine:3.16
RUN apk add --no-cache ca-certificates
COPY --from=builder /go/src/github.com/documize/community/bin/documize-community /documize
EXPOSE 5001
ENTRYPOINT [ "/documize" ]

2572
NOTICES.md

File diff suppressed because it is too large Load diff

109
README.md
View file

@ -1,110 +1,53 @@
Documize Community is an open source, modern, self-hosted, enterprise-grade knowledge management solution.
# Documize Community Edition
- Built for technical and non-technical users
- Designed to unify both customer-facing and internal documentation
- Organization through labels, spaces and categories
Documize is an Integrated Document Environment (IDE) unifying documents, wiki, reporting and dashboards -- one tool to power the enterprise-wide knowledge backbone.
It's built with Golang + EmberJS and compiled down to a single executable binary that is available for Linux, Windows and Mac.
![Alt text](screenshot.png "Documize")
All you need to provide is your database -- PostgreSQL, Microsoft SQL Server or any MySQL variant.
The mission is to bring software dev inspired features (refactoring, testing, linting, metrics, PRs) to those poor souls stuck writing docs in the dark ages.
![Documize Community](https://github.com/documize/community/blob/master/screenshot.png?raw=true)
## Latest version
## Latest Release
[Community edition: v5.13.0](https://github.com/documize/community/releases)
[Community+ edition: v5.13.0](https://www.documize.com/community/get-started)
The Community+ edition is the "enterprise" offering with advanced capabilities and customer support:
- content approval workflows
- content organization by label, space and category
- content version management
- content lifecycle management
- content feedback capture
- content PDF export
- analytics and reporting
- activity streams
- audit logs
- actions assignments
- product support
The Community+ edition is [free](https://www.documize.com/community/get-started) for the first five users -- thereafter pricing starts at just $900 annually for 100 users.
v1.47.2
## OS Support
- Linux
- Windows
- Linux
- macOS
- Raspberry Pi (ARM build)
Support for AMD and ARM 64 bit architectures.
## Tech stack
## Database Support
- EmberJS (v2.12.0)
- Go (v1.8)
- MySQL (v5.7.10+) or Percona (v5.7.16-10+)
For all database types, Full-Text Search (FTS) support is mandatory.
## Documentation
- PostgreSQL (v9.6+)
- Microsoft SQL Server (2016+ with FTS)
- Microsoft SQL Azure (v12+)
- MySQL (v5.7.10+ and v8.0.12+)
- Percona (v5.7.16-10+)
- MariaDB (10.3.0+)
<https://docs.documize.com>
## Browser Support
## Keycloak Integration
- Firefox
- Chrome
- Safari
- Microsoft Edge
- Brave
- Vivaldi
- Opera
Documize provides out-of-the-box integration with [Redhat Keycloak](http://www.keycloak.org) for open source identity and access management.
## Technology Stack
Connect and authenticate with LDAP, Active Directory and more.
- Go (v1.23.4)
- Ember JS (v3.12.0)
<https://docs.documize.com>
## Authentication Options
## Auth0 Compatible
Besides email/password login, you can also authenticate via:
Documize is compatible with Auth0 identity as a service.
* LDAP
* Active Directory
* Red Hat Keycloak
* Central Authentication Service (CAS)
[![JWT Auth for open source projects](https://cdn.auth0.com/oss/badges/a0-badge-dark.png)](https://auth0.com/?utm_source=oss&utm_medium=gp&utm_campaign=oss)
When using LDAP/Active Directory, you can enable dual-authentication with email/password.
Open Source Identity and Access Management
## Localization
## Word Conversion to HTML
Languages supported out-of-the-box:
- [Code for `wordconvert` utility](https://github.com/documize/community/tree/master/cmd/wordconvert)
- English
- German
- French
- Chinese (中文)
- Portuguese (Brazil) (Português - Brasil)
- Japanese (日本語)
- Italian
- Spanish Argentinian
## Legal
PR's welcome for additional languages.
<https://documize.com>
## Product/Technical Support
For both Community and Community+ editions, please contact our help desk for product help, suggestions and other enquiries.
<support@documize.com>
We aim to respond within two working days.
## The Legal Bit
<https://www.documize.com>
This software (Documize Community edition) is licensed under GNU AGPL v3 <http://www.gnu.org/licenses/agpl-3.0.en.html>.
Documize Community uses other open source components and we acknowledge them in [NOTICES](NOTICES.md)
This software (Documize Community Edition) is licensed under GNU AGPL v3 <http://www.gnu.org/licenses/agpl-3.0.en.html>. You can operate outside the AGPL restrictions by purchasing Documize Enterprise Edition and obtaining a commercial license by contacting <sales@documize.com>. Documize® is a registered trade mark of Documize Inc.

4
app/.bowerrc Normal file
View file

@ -0,0 +1,4 @@
{
"directory": "bower_components",
"analytics": false
}

20
app/.editorconfig Normal file
View file

@ -0,0 +1,20 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = tab
indent_size = 4
[*.hbs]
insert_final_newline = false
[*.{diff,md}]
trim_trailing_whitespace = false

6
app/.eslintignore Normal file
View file

@ -0,0 +1,6 @@
public/tinymce/**
public/tinymce/
public/tinymce
public/codemirror/**
public/codemirror/
public/codemirror

36
app/.eslintrc.js Normal file
View file

@ -0,0 +1,36 @@
module.exports = {
root: true,
parserOptions: {
ecmaVersion: 6,
sourceType: 'module'
},
extends: 'eslint:recommended',
env: {
browser: true,
jquery: true,
qunit: true,
embertest: true
},
rules: {
},
globals: {
"$": true,
"is": true,
"_": true,
"tinymce": true,
"CodeMirror": true,
"Drop": true,
"Mousetrap": true,
"Sortable": true,
"moment": true,
"Dropzone": true,
"Tooltip": true,
"server": true,
"authenticateUser": true,
"stubAudit": true,
"stubUserNotification": true,
"userLogin": true,
"Keycloak": true,
"slug": true
}
};

18
app/.gitignore vendored Normal file
View file

@ -0,0 +1,18 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/dist-prod
/tmp
# dependencies
/node_modules
/bower_components
# misc
/.sass-cache
/connect.lock
/coverage/*
/libpeerconnection.log
npm-debug.log*
testem.log

24
app/.travis.yml Normal file
View file

@ -0,0 +1,24 @@
---
language: node_js
node_js:
- "6"
sudo: false
cache:
directories:
- $HOME/.npm
- $HOME/.cache # includes bowers cache
before_install:
- npm config set spin false
- npm install -g bower phantomjs-prebuilt
- bower --version
- phantomjs --version
install:
- npm install
- bower install
script:
- npm test

3
app/.watchmanconfig Normal file
View file

@ -0,0 +1,3 @@
{
"ignore_dirs": ["tmp", "dist", "dist-prod"]
}

53
app/README.md Normal file
View file

@ -0,0 +1,53 @@
# Documize
This README outlines the details of collaborating on this Ember application.
A short introduction of this app could easily go here.
## Prerequisites
You will need the following things properly installed on your computer.
* [Git](http://git-scm.com/)
* [Node.js](http://nodejs.org/) (with NPM)
* [Bower](http://bower.io/)
* [Ember CLI](http://ember-cli.com/)
* [PhantomJS](http://phantomjs.org/)
## Installation
* `git clone <repository-url>` this repository
* `cd documize`
* `npm install`
* `bower install`
## Running / Development
* `ember serve`
* Visit your app at [http://localhost:4200](http://localhost:4200).
### Code Generators
Make use of the many generators for code, try `ember help generate` for more details
### Running Tests
* `ember test`
* `ember test --server`
### Building
* `ember build` (development)
* `ember build --environment production` (production)
### Deploying
Specify what it takes to deploy your app.
## Further Reading / Useful Links
* [ember.js](http://emberjs.com/)
* [ember-cli](http://ember-cli.com/)
* Development Browser Extensions
* [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
* [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)

View file

@ -9,21 +9,21 @@
//
// https://documize.com
import Application from '@ember/application';
import Ember from 'ember';
import Resolver from './resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
let App;
// Ember.MODEL_FACTORY_INJECTIONS = true;
Ember.MODEL_FACTORY_INJECTIONS = true;
// Ember.RSVP.on('error', function(error) {
// console.log("App:");
// console.log(error);
// });
App = Application.extend({
App = Ember.Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver

View file

@ -0,0 +1,26 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import Base from 'ember-simple-auth/authenticators/base';
const {
RSVP: { resolve }
} = Ember;
export default Base.extend({
restore(data) {
return resolve(data);
},
authenticate(data) {
return resolve(data);
}
});

View file

@ -9,12 +9,16 @@
//
// https://documize.com
import { isPresent } from '@ember/utils';
import { reject, resolve } from 'rsvp';
import { inject as service } from '@ember/service';
import Ember from 'ember';
import Base from 'ember-simple-auth/authenticators/base';
import encodingUtil from '../utils/encoding';
import netUtil from '../utils/net';
import Base from 'ember-simple-auth/authenticators/base';
const {
isPresent,
RSVP: { resolve, reject },
inject: { service }
} = Ember;
export default Base.extend({
ajax: service(),
@ -38,14 +42,14 @@ export default Base.extend({
let { password, email } = credentials;
if (!isPresent(password) || !isPresent(email)) {
return reject("invalid");
return Ember.RSVP.reject("invalid");
}
encoded = encodingUtil.Base64.encode(`${domain}:${email}:${password}`);
} else if (typeof credentials === 'string') {
encoded = credentials;
} else {
return reject("invalid");
return Ember.RSVP.reject("invalid");
}
let headers = { 'Authorization': 'Basic ' + encoded };

View file

@ -0,0 +1,54 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import Base from 'ember-simple-auth/authenticators/base';
import netUtil from '../utils/net';
const {
isPresent,
RSVP: { resolve, reject },
inject: { service }
} = Ember;
export default Base.extend({
ajax: service(),
appMeta: service(),
kcAuth: service(),
localStorage: service(),
restore(data) {
// TODO: verify authentication data
if (data) {
return resolve(data);
}
return reject();
},
authenticate(data) {
data.domain = netUtil.getSubdomain();
if (!isPresent(data.token) || !isPresent(data.email)) {
return Ember.RSVP.reject("invalid");
}
return this.get('ajax').post('public/authenticate/keycloak', {
data: JSON.stringify(data),
contentType: 'json'
});
},
invalidate() {
this.get('localStorage').clearAll();
return this.get('kcAuth').logout();
}
});

View file

@ -0,0 +1,15 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
});

View file

@ -0,0 +1,156 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import constants from '../../utils/constants';
import encoding from '../../utils/encoding';
import NotifierMixin from "../../mixins/notifier";
const {
computed
} = Ember;
export default Ember.Component.extend(NotifierMixin, {
appMeta: Ember.inject.service(),
isDocumizeProvider: computed.equal('authProvider', constants.AuthProvider.Documize),
isKeycloakProvider: computed.equal('authProvider', constants.AuthProvider.Keycloak),
KeycloakUrlError: computed.empty('keycloakConfig.url'),
KeycloakRealmError: computed.empty('keycloakConfig.realm'),
KeycloakClientIdError: computed.empty('keycloakConfig.clientId'),
KeycloakPublicKeyError: computed.empty('keycloakConfig.publicKey'),
KeycloakAdminUserError: computed.empty('keycloakConfig.adminUser'),
KeycloakAdminPasswordError: computed.empty('keycloakConfig.adminPassword'),
keycloakConfig: {
url: '',
realm: '',
clientId: '',
publicKey: '',
adminUser: '',
adminPassword: '',
group: '',
disableLogout: false,
defaultPermissionAddSpace: false
},
didReceiveAttrs() {
this._super(...arguments);
let provider = this.get('authProvider');
switch (provider) {
case constants.AuthProvider.Documize:
// nothing to do
break;
case constants.AuthProvider.Keycloak: // eslint-disable-line no-case-declarations
let config = this.get('authConfig');
if (is.undefined(config) || is.null(config) || is.empty(config) ) {
config = {};
} else {
config = JSON.parse(config);
config.publicKey = encoding.Base64.decode(config.publicKey);
config.defaultPermissionAddSpace = config.hasOwnProperty('defaultPermissionAddSpace') ? config.defaultPermissionAddSpace : false;
config.disableLogout = config.hasOwnProperty('disableLogout') ? config.disableLogout : true;
}
this.set('keycloakConfig', config);
break;
}
},
actions: {
onDocumize() {
this.set('authProvider', constants.AuthProvider.Documize);
},
onKeycloak() {
this.set('authProvider', constants.AuthProvider.Keycloak);
},
onSave() {
let provider = this.get('authProvider');
let config = this.get('authConfig');
switch (provider) {
case constants.AuthProvider.Documize:
config = {};
break;
case constants.AuthProvider.Keycloak:
if (this.get('KeycloakUrlError')) {
this.$("#keycloak-url").focus();
return;
}
if (this.get('KeycloakRealmError')) {
this.$("#keycloak-realm").focus();
return;
}
if (this.get('KeycloakClientIdError')) {
this.$("#keycloak-clientId").focus();
return;
}
if (this.get('KeycloakPublicKeyError')) {
this.$("#keycloak-publicKey").focus();
return;
}
if (this.get('KeycloakAdminUserError')) {
this.$("#keycloak-admin-user").focus();
return;
}
if (this.get('KeycloakAdminPasswordError')) {
this.$("#keycloak-admin-password").focus();
return;
}
config = Ember.copy(this.get('keycloakConfig'));
config.url = config.url.trim();
config.realm = config.realm.trim();
config.clientId = config.clientId.trim();
config.publicKey = config.publicKey.trim();
config.group = is.undefined(config.group) ? '' : config.group.trim();
config.adminUser = config.adminUser.trim();
config.adminPassword = config.adminPassword.trim();
config.defaultPermissionAddSpace = config.hasOwnProperty('defaultPermissionAddSpace') ? config.defaultPermissionAddSpace : true;
config.disableLogout = config.hasOwnProperty('disableLogout') ? config.disableLogout : true;
if (is.endWith(config.url, '/')) {
config.url = config.url.substring(0, config.url.length-1);
}
Ember.set(config, 'publicKey', encoding.Base64.encode(this.get('keycloakConfig.publicKey')));
break;
}
let data = { authProvider: provider, authConfig: JSON.stringify(config) };
this.get('onSave')(data).then(() => {
if (data.authProvider === constants.AuthProvider.Keycloak) {
this.get('onSync')().then((response) => {
if (response.isError) {
this.showNotification(response.message);
data.authProvider = constants.AuthProvider.Documize;
this.get('onSave')(data).then(() => {
this.showNotification('Reverted back to Documize');
});
} else {
if (data.authProvider === this.get('appMeta.authProvider')) {
this.showNotification(response.message);
} else {
this.get('onChange')(data);
}
}
});
} else {
this.showNotification('Saved');
}
});
}
}
});

View file

@ -0,0 +1,45 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
const {
isEmpty,
computed,
set
} = Ember;
export default Ember.Component.extend({
titleEmpty: computed.empty('model.general.title'),
messageEmpty: computed.empty('model.general.message'),
hasTitleInputError: computed.and('titleEmpty', 'titleError'),
hasMessageInputError: computed.and('messageEmpty', 'messageError'),
actions: {
save() {
if (isEmpty(this.get('model.general.title'))) {
set(this, 'titleError', true);
return $("#siteTitle").focus();
}
if (isEmpty(this.get('model.general.message'))) {
set(this, 'messageError', true);
return $("#siteMessage").focus();
}
this.model.general.set('allowAnonymousAccess', Ember.$("#allowAnonymousAccess").prop('checked'));
this.get('save')().then(() => {
set(this, 'titleError', false);
set(this, 'messageError', false);
});
}
}
});

View file

@ -0,0 +1,58 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
const {
computed
} = Ember;
export default Ember.Component.extend({
SMTPHostEmptyError: computed.empty('model.smtp.host'),
SMTPPortEmptyError: computed.empty('model.smtp.port'),
SMTPSenderEmptyError: computed.empty('model.smtp.sender'),
SMTPUserIdEmptyError: computed.empty('model.smtp.userid'),
SMTPPasswordEmptyError: computed.empty('model.smtp.password'),
actions: {
saveSMTP() {
if (this.get('SMTPHostEmptyError')) {
$("#smtp-host").focus();
return;
}
if (this.get('SMTPPortEmptyError')) {
$("#smtp-port").focus();
return;
}
if (this.get('SMTPSenderEmptyError')) {
$("#smtp-sender").focus();
return;
}
if (this.get('SMTPUserIdEmptyError')) {
$("#smtp-userid").focus();
return;
}
if (this.get('SMTPPasswordEmptyError')) {
$("#smtp-password").focus();
return;
}
this.get('saveSMTP')().then(() => {
});
},
saveLicense() {
this.get('saveLicense')().then(() => {
window.location.reload();
});
}
}
});

View file

@ -0,0 +1,202 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import AuthProvider from '../../mixins/auth';
export default Ember.Component.extend(AuthProvider, {
editUser: null,
deleteUser: null,
drop: null,
password: {},
filter: '',
filteredUsers: [],
selectedUsers: [],
hasSelectedUsers: false,
didReceiveAttrs() {
this.users.forEach(user => {
user.set('me', user.get('id') === this.get('session.session.authenticated.user.id'));
user.set('selected', false);
});
this.set('filteredUsers', this.users);
},
willDestroyElement() {
let drop = this.get('drop');
if (is.not.null(drop)) {
drop.destroy();
}
},
onKeywordChange: function () {
Ember.run.debounce(this, this.filterUsers, 350);
}.observes('filter'),
filterUsers() {
let users = this.get('users');
let filteredUsers = [];
let filter = this.get('filter').toLowerCase();
users.forEach(user => {
if (user.get('fullname').toLowerCase().includes(filter) || user.get('email').toLowerCase().includes(filter)) {
filteredUsers.pushObject(user);
}
});
this.set('filteredUsers', filteredUsers);
},
actions: {
toggleSelect(user) {
user.set('selected', !user.get('selected'));
let su = this.get('selectedUsers');
if (user.get('selected')) {
su.push(user.get('id'));
} else {
su = _.reject(su, function(id){ return id === user.get('id') });
}
this.set('selectedUsers', su);
this.set('hasSelectedUsers', su.length > 0);
},
toggleActive(id) {
let user = this.users.findBy("id", id);
user.set('active', !user.get('active'));
this.attrs.onSave(user);
},
toggleEditor(id) {
let user = this.users.findBy("id", id);
user.set('editor', !user.get('editor'));
this.attrs.onSave(user);
},
toggleAdmin(id) {
let user = this.users.findBy("id", id);
user.set('admin', !user.get('admin'));
this.attrs.onSave(user);
},
edit(id) {
let self = this;
let user = this.users.findBy("id", id);
let userCopy = user.getProperties('id', 'created', 'revised', 'firstname', 'lastname', 'email', 'initials', 'active', 'editor', 'admin', 'accounts');
this.set('editUser', userCopy);
this.set('password', {
password: "",
confirmation: ""
});
$(".edit-user-dialog").css("display", "block");
$("input").removeClass("error");
let drop = new Drop({
target: $(".edit-button-" + id)[0],
content: $(".edit-user-dialog")[0],
classes: 'drop-theme-basic',
position: "bottom right",
openOn: "always",
tetherOptions: {
offset: "5px 0",
targetOffset: "10px 0"
},
remove: false
});
self.set('drop', drop);
drop.on('open', function () {
self.$("#edit-firstname").focus();
});
},
confirmDelete(id) {
let user = this.users.findBy("id", id);
this.set('deleteUser', user);
$(".delete-user-dialog").css("display", "block");
let drop = new Drop({
target: $(".delete-button-" + id)[0],
content: $(".delete-user-dialog")[0],
classes: 'drop-theme-basic',
position: "bottom right",
openOn: "always",
tetherOptions: {
offset: "5px 0",
targetOffset: "10px 0"
},
remove: false
});
this.set('drop', drop);
},
cancel() {
let drop = this.get('drop');
drop.close();
},
save() {
let user = this.get('editUser');
let password = this.get('password');
if (is.empty(user.firstname)) {
$("#edit-firstname").addClass("error").focus();
return;
}
if (is.empty(user.lastname)) {
$("#edit-lastname").addClass("error").focus();
return;
}
if (is.empty(user.email)) {
$("#edit-email").addClass("error").focus();
return;
}
let drop = this.get('drop');
drop.close();
this.attrs.onSave(user);
if (is.not.empty(password.password) && is.not.empty(password.confirmation) &&
password.password === password.confirmation) {
this.attrs.onPassword(user, password.password);
}
},
delete() {
let drop = this.get('drop');
drop.close();
this.set('selectedUsers', []);
this.set('hasSelectedUsers', false);
this.attrs.onDelete(this.get('deleteUser.id'));
},
onBulkDelete() {
let su = this.get('selectedUsers');
su.forEach(userId => {
this.attrs.onDelete(userId);
});
this.set('selectedUsers', []);
this.set('hasSelectedUsers', false);
return true;
}
}
});

View file

@ -0,0 +1,57 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import AuthProvider from '../../mixins/auth';
const {
isEmpty,
computed,
set,
get
} = Ember;
export default Ember.Component.extend(AuthProvider, {
newUser: { firstname: "", lastname: "", email: "", active: true },
firstnameEmpty: computed.empty('newUser.firstname'),
lastnameEmpty: computed.empty('newUser.lastname'),
emailEmpty: computed.empty('newUser.email'),
hasFirstnameEmptyError: computed.and('firstnameEmpty', 'firstnameError'),
hasLastnameEmptyError: computed.and('lastnameEmpty', 'lastnameError'),
hasEmailEmptyError: computed.and('emailEmpty', 'emailError'),
actions: {
add() {
if (isEmpty(this.get('newUser.firstname'))) {
set(this, 'firstnameError', true);
return $("#newUserFirstname").focus();
}
if (isEmpty(this.get('newUser.lastname'))) {
set(this, 'lastnameError', true);
return $("#newUserLastname").focus();
}
if (isEmpty(this.get('newUser.email')) || is.not.email(this.get('newUser.email'))) {
set(this, 'emailError', true);
return $("#newUserEmail").focus();
}
let user = get(this, 'newUser');
get(this, 'add')(user).then(() => {
this.set('newUser', { firstname: "", lastname: "", email: "", active: true });
set(this, 'firstnameError', false);
set(this, 'lastnameError', false);
set(this, 'emailError', false);
$("#newUserFirstname").focus();
});
}
}
});

View file

@ -9,11 +9,10 @@
//
// https://documize.com
import { inject as service } from '@ember/service';
import Component from '@ember/component';
import Ember from 'ember';
export default Component.extend({
store: service(),
export default Ember.Component.extend({
store: Ember.inject.service(),
didReceiveAttrs() {
let p = this.get('store').createRecord('page');
@ -21,7 +20,7 @@ export default Component.extend({
p.set('id', this.get('block.id'));
p.set('orgId', this.get('block.orgId'));
p.set('documentId', 'dummy');
p.set('documentId', this.get('document.id'));
p.set('contentType', this.get('block.contentType'));
p.set('pageType', this.get('block.pageType'));
p.set('title', this.get('block.title'));
@ -31,7 +30,7 @@ export default Component.extend({
m.set('pageId', this.get('block.id'));
m.set('orgId', this.get('block.orgId'));
m.set('documentId', 'dummy');
m.set('documentId', this.get('document.id'));
m.set('rawBody', this.get('block.rawBody'));
m.set('config', this.get('block.config'));
m.set('externalSource', this.get('block.externalSource'));
@ -44,13 +43,11 @@ export default Component.extend({
actions: {
onCancel() {
let cb = this.get('onCancel');
cb();
this.attrs.onCancel();
},
onAction(page, meta) {
let cb = this.get('onAction');
cb(page, meta);
this.attrs.onAction(page, meta);
}
}
});

View file

@ -0,0 +1,137 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import TooltipMixin from '../../mixins/tooltip';
const {
inject: { service }
} = Ember;
export default Ember.Component.extend(TooltipMixin, {
link: service(),
linkName: '',
keywords: '',
selection: null,
matches: {
documents: [],
pages: [],
attachments: []
},
tabs: [
{ label: 'Section', selected: true },
{ label: 'Attachment', selected: false },
{ label: 'Search', selected: false }
],
contentLinkerButtonId: Ember.computed('page', function () {
let page = this.get('page');
return `content-linker-button-${page.id}`;
}),
showSections: Ember.computed('tabs.@each.selected', function () {
return this.get('tabs').findBy('label', 'Section').selected;
}),
showAttachments: Ember.computed('tabs.@each.selected', function () {
return this.get('tabs').findBy('label', 'Attachment').selected;
}),
showSearch: Ember.computed('tabs.@each.selected', function () {
return this.get('tabs').findBy('label', 'Search').selected;
}),
hasMatches: Ember.computed('matches', function () {
let m = this.get('matches');
return m.documents.length || m.pages.length || m.attachments.length;
}),
init() {
this._super(...arguments);
let self = this;
let folderId = this.get('folder.id');
let documentId = this.get('document.id');
let pageId = this.get('page.id');
this.get('link').getCandidates(folderId, documentId, pageId).then(function (candidates) {
self.set('candidates', candidates);
self.set('hasSections', is.not.null(candidates.pages) && candidates.pages.length);
self.set('hasAttachments', is.not.null(candidates.attachments) && candidates.attachments.length);
});
},
didRender() {
this.addTooltip(document.getElementById("content-linker-button"));
this.addTooltip(document.getElementById("content-counter-button"));
},
willDestroyElement() {
this.destroyTooltips();
},
onKeywordChange: function () {
Ember.run.debounce(this, this.fetch, 750);
}.observes('keywords'),
fetch() {
let keywords = this.get('keywords');
let self = this;
if (_.isEmpty(keywords)) {
this.set('matches', { documents: [], pages: [], attachments: [] });
return;
}
this.get('link').searchCandidates(keywords).then(function (matches) {
self.set('matches', matches);
});
},
actions: {
setSelection(i) {
let candidates = this.get('candidates');
let matches = this.get('matches');
this.set('selection', i);
candidates.pages.forEach(c => {
Ember.set(c, 'selected', c.id === i.id);
});
candidates.attachments.forEach(c => {
Ember.set(c, 'selected', c.id === i.id);
});
matches.documents.forEach(c => {
Ember.set(c, 'selected', c.id === i.id);
});
matches.pages.forEach(c => {
Ember.set(c, 'selected', c.id === i.id);
});
matches.attachments.forEach(c => {
Ember.set(c, 'selected', c.id === i.id);
});
},
onInsertLink() {
let selection = this.get('selection');
if (is.null(selection)) {
return;
}
return this.get('onInsertLink')(selection);
},
onTabSelect(tabs) {
this.set('tabs', tabs);
}
}
});

View file

@ -9,22 +9,20 @@
//
// https://documize.com
import Component from '@ember/component';
import Ember from 'ember';
export default Component.extend({
export default Ember.Component.extend({
didReceiveAttrs() {
this.set('editorType', 'section/' + this.get('page.contentType') + '/type-editor');
},
actions: {
onCancel() {
let cb = this.get('onCancel');
cb();
this.attrs.onCancel();
},
onAction(page, meta) {
let cb = this.get('onAction');
cb(page, meta);
this.attrs.onAction(page, meta);
}
}
});

View file

@ -0,0 +1,66 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
import TooltipMixin from '../../mixins/tooltip';
const {
computed,
} = Ember;
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
documentService: Ember.inject.service('document'),
editMode: false,
docName: '',
docExcerpt: '',
hasNameError: computed.empty('docName'),
hasExcerptError: computed.empty('docExcerpt'),
keyUp(e) {
if (e.keyCode === 27) { // escape key
this.send('onCancel');
}
},
actions: {
toggleEdit() {
this.set('docName', this.get('document.name'));
this.set('docExcerpt', this.get('document.excerpt'));
this.set('editMode', true);
Ember.run.schedule('afterRender', () => {
$('#document-name').select();
});
},
onSave() {
if (this.get('hasNameError') || this.get('hasExcerptError')) {
return;
}
this.set('document.name', this.get('docName'));
this.set('document.excerpt', this.get('docExcerpt'));
this.showNotification('Saved');
this.get('browser').setTitle(this.get('document.name'));
this.get('browser').setMetaDescription(this.get('document.excerpt'));
this.get('documentService').save(this.get('document'));
this.set('editMode', false);
},
onCancel() {
this.set('editMode', false);
}
}
});

View file

@ -0,0 +1,49 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
revision: null,
hasDiff: Ember.computed('diff', function () {
return this.get('diff').length > 0;
}),
didReceiveAttrs() {
let revisions = this.get('revisions');
revisions.forEach((r) => {
Ember.set(r, 'deleted', r.revisions === 0);
Ember.set(r, 'label', `${r.created} - ${r.firstname} ${r.lastname} - ${r.title}`);
});
if (revisions.length > 0 && is.null(this.get('revision'))) {
this.send('onSelectRevision', revisions[0]);
}
this.set('revisions', revisions);
},
actions: {
onSelectRevision(revision) {
this.set('revision', revision);
if (!revision.deleted) {
this.attrs.onFetchDiff(revision.pageId, revision.id);
}
},
onRollback() {
let revision = this.get('revision');
this.attrs.onRollback(revision.pageId, revision.id);
}
}
});

View file

@ -0,0 +1,92 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
import TooltipMixin from '../../mixins/tooltip';
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
documentService: Ember.inject.service('document'),
sectionService: Ember.inject.service('section'),
editMode: false,
didReceiveAttrs() {
this._super(...arguments);
if (this.get('isDestroyed') || this.get('isDestroying')) {
return;
}
let page = this.get('page');
this.get('documentService').getPageMeta(page.get('documentId'), page.get('id')).then((meta) => {
if (this.get('isDestroyed') || this.get('isDestroying')) {
return;
}
this.set('meta', meta);
if (this.get('toEdit') === this.get('page.id') && this.get('isEditor')) {
this.send('onEdit');
}
});
},
actions: {
onSavePage(page, meta) {
this.set('page', page);
this.set('meta', meta);
this.set('editMode', false);
this.get('onSavePage')(page, meta);
},
onSavePageAsBlock(block) {
this.attrs.onSavePageAsBlock(block);
},
onCopyPage(documentId) {
this.attrs.onCopyPage(this.get('page.id'), documentId);
},
onMovePage(documentId) {
this.attrs.onMovePage(this.get('page.id'), documentId);
},
onDeletePage(deleteChildren) {
let page = this.get('page');
if (is.undefined(page)) {
return;
}
let params = {
id: page.get('id'),
title: page.get('title'),
children: deleteChildren
};
this.attrs.onDeletePage(params);
},
onEdit() {
if (this.get('editMode')) {
return;
}
this.get('toEdit', '');
// this.set('pageId', this.get('page.id'));
this.set('editMode', true);
},
onCancelEdit() {
this.set('editMode', false);
}
}
});

View file

@ -0,0 +1,77 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
import TooltipMixin from '../../mixins/tooltip';
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
sectionService: Ember.inject.service('section'),
viewMode: true,
editMode: false,
didInsertElement() {
this.get('sectionService').refresh(this.get('document.id')).then((changes) => {
if (this.get('isDestroyed') || this.get('isDestroying')) {
return;
}
let oldPage = this.get('page');
if (is.undefined(changes) || is.undefined(oldPage)) {
return;
}
changes.forEach((newPage) => {
if (oldPage.get('id') === newPage.get('id')) {
oldPage.set('body', newPage.get('body'));
oldPage.set('revised', newPage.get('revised'));
this.showNotification(`Refreshed ${oldPage.get('title')}`);
}
});
});
},
actions: {
onExpand() {
this.set('pageId', this.get('page.id'));
this.set('expanded', !this.get('expanded'));
},
onSavePageAsBlock(block) {
this.attrs.onSavePageAsBlock(block);
},
onCopyPage(documentId) {
this.attrs.onCopyPage(this.get('page.id'), documentId);
},
onMovePage(documentId) {
this.attrs.onMovePage(this.get('page.id'), documentId);
},
onDeletePage(deleteChildren) {
let page = this.get('page');
if (is.undefined(page)) {
return;
}
let params = {
id: page.get('id'),
title: page.get('title'),
children: deleteChildren
};
this.attrs.onDeletePage(params);
}
}
});

View file

@ -0,0 +1,316 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
import TooltipMixin from '../../mixins/tooltip';
const {
computed,
} = Ember;
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
documentService: Ember.inject.service('document'),
sectionService: Ember.inject.service('section'),
appMeta: Ember.inject.service(),
link: Ember.inject.service(),
hasPages: computed.notEmpty('pages'),
newSectionName: 'Section',
newSectionNameMissing: computed.empty('newSectionName'),
newSectionLocation: '',
beforePage: '',
toEdit: '',
didReceiveAttrs() {
this._super(...arguments);
this.loadBlocks();
Ember.run.schedule('afterRender', () => {
let jumpTo = "#page-" + this.get('pageId');
if (!$(jumpTo).inView()) {
$(jumpTo).velocity("scroll", { duration: 250, offset: -100 });
}
});
},
didRender() {
this._super(...arguments);
this.contentLinkHandler();
},
didInsertElement() {
this._super(...arguments);
this.setupAddWizard();
let self = this;
$(".tooltipped").each(function(i, el) {
self.addTooltip(el);
});
},
willDestroyElement() {
this._super(...arguments);
$('.start-section:not(.start-section-empty-state)').off('.hoverIntent');
this.destroyTooltips();
},
contentLinkHandler() {
let links = this.get('link');
let doc = this.get('document');
let self = this;
$("a[data-documize='true']").off('click').on('click', function (e) {
let link = links.getLinkObject(self.get('links'), this);
// local link? exists?
if ((link.linkType === "section" || link.linkType === "tab") && link.documentId === doc.get('id')) {
let exists = self.get('pages').findBy('id', link.targetId);
if (_.isUndefined(exists)) {
link.orphan = true;
} else {
if (link.linkType === "section") {
self.attrs.onGotoPage(link.targetId);
}
}
}
if (link.orphan) {
$(this).addClass('broken-link');
self.showNotification('Broken link!');
e.preventDefault();
e.stopPropagation();
return false;
}
links.linkClick(doc, link);
return false;
});
},
setupAddWizard() {
Ember.run.schedule('afterRender', () => {
$('.start-section:not(.start-section-empty-state)').off('.hoverIntent');
$('.start-section:not(.start-section-empty-state)').hoverIntent({interval: 100, over: function() {
// in
$(this).find('.start-button').velocity("transition.slideDownIn", {duration: 300});
}, out: function() {
// out
$(this).find('.start-button').velocity("transition.slideUpOut", {duration: 300});
} });
});
},
addSection(model) {
// calculate sequence of page (position in document)
let sequence = 0;
let level = 1;
let beforePage = this.get('beforePage');
if (is.not.null(beforePage)) {
level = beforePage.get('level');
// get any page before the beforePage so we can insert this new section between them
let index = _.findIndex(this.get('pages'), function(p) { return p.get('id') === beforePage.get('id'); });
if (index !== -1) {
let beforeBeforePage = this.get('pages')[index-1];
if (is.not.undefined(beforeBeforePage)) {
sequence = (beforePage.get('sequence') + beforeBeforePage.get('sequence')) / 2;
} else {
sequence = beforePage.get('sequence') / 2;
}
}
}
model.page.sequence = sequence;
model.page.level = level;
this.send('onHideSectionWizard');
return this.get('onInsertSection')(model);
},
loadBlocks() {
this.get('sectionService').getSpaceBlocks(this.get('folder.id')).then((blocks) => {
if (this.get('isDestroyed') || this.get('isDestroying')) {
return;
}
this.set('blocks', blocks);
this.set('hasBlocks', blocks.get('length') > 0);
blocks.forEach((b) => {
b.set('deleteId', `delete-block-button-${b.id}`);
});
});
},
actions: {
onSavePageAsBlock(block) {
const promise = this.attrs.onSavePageAsBlock(block);
promise.then(() => {
this.loadBlocks();
});
},
onCopyPage(pageId, documentId) {
this.attrs.onCopyPage(pageId, documentId);
},
onMovePage(pageId, documentId) {
this.attrs.onMovePage(pageId, documentId);
},
onDeletePage(params) {
this.attrs.onDeletePage(params);
},
onSavePage(page, meta) {
this.set('toEdit', '');
this.attrs.onSavePage(page, meta);
},
onShowSectionWizard(page) {
if (is.undefined(page)) {
page = { id: '0' };
}
this.set('pageId', '');
let beforePage = this.get('beforePage');
if (is.not.null(beforePage) && $("#new-section-wizard").is(':visible') && beforePage.get('id') === page.id) {
this.send('onHideSectionWizard');
return;
}
this.set('newSectionLocation', page.id);
if (page.id === '0') {
// this handles add section at the end of the document
// because we are not before another page
this.set('beforePage', null);
} else {
this.set('beforePage', page);
}
$("#new-section-wizard").insertAfter(`#add-section-button-${page.id}`);
$("#new-section-wizard").velocity("transition.slideDownIn", { duration: 300, complete:
function() {
$("#new-section-name").focus();
}});
},
onHideSectionWizard() {
this.set('newSectionLocation', '');
this.set('beforePage', null);
$("#new-section-wizard").insertAfter('#wizard-placeholder');
$("#new-section-wizard").velocity("transition.slideUpOut", { duration: 300 });
},
onInsertSection(section) {
let sectionName = this.get('newSectionName');
if (is.empty(sectionName)) {
$("#new-section-name").focus();
return;
}
let page = {
documentId: this.get('document.id'),
title: sectionName,
level: 1,
sequence: 0, // calculated elsewhere
body: "",
contentType: section.get('contentType'),
pageType: section.get('pageType')
};
let meta = {
documentId: this.get('document.id'),
rawBody: "",
config: ""
};
let model = {
page: page,
meta: meta
};
const promise = this.addSection(model);
promise.then((id) => {
this.set('pageId', id);
if (model.page.pageType === 'section') {
this.set('toEdit', id);
} else {
this.set('toEdit', '');
}
this.setupAddWizard();
});
},
onInsertBlock(block) {
let sectionName = this.get('newSectionName');
if (is.empty(sectionName)) {
$("#new-section-name").focus();
return;
}
let page = {
documentId: this.get('document.id'),
title: `${block.get('title')}`,
level: 1,
sequence: 0, // calculated elsewhere
body: block.get('body'),
contentType: block.get('contentType'),
pageType: block.get('pageType'),
blockId: block.get('id')
};
let meta = {
documentId: this.get('document.id'),
rawBody: block.get('rawBody'),
config: block.get('config'),
externalSource: block.get('externalSource')
};
let model = {
page: page,
meta: meta
};
const promise = this.addSection(model);
promise.then((id) => {
this.set('pageId', id);
this.setupAddWizard();
});
},
onDeleteBlock(id) {
const promise = this.attrs.onDeleteBlock(id);
promise.then(() => {
this.loadBlocks();
});
return true;
}
}
});

View file

@ -0,0 +1,194 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import TooltipMixin from '../../mixins/tooltip';
const {
computed,
inject: { service }
} = Ember;
export default Ember.Component.extend(TooltipMixin, {
documentService: service('document'),
deleteChildren: false,
menuOpen: false,
blockTitle: "",
blockExcerpt: "",
documentList: [], //includes the current document
documentListOthers: [], //excludes the current document
selectedDocument: null,
checkId: computed('page', function () {
let id = this.get('page.id');
return `delete-check-button-${id}`;
}),
menuTarget: computed('page', function () {
let id = this.get('page.id');
return `page-menu-${id}`;
}),
deleteButtonId: computed('page', function () {
let id = this.get('page.id');
return `delete-page-button-${id}`;
}),
publishButtonId: computed('page', function () {
let id = this.get('page.id');
return `publish-button-${id}`;
}),
publishDialogId: computed('page', function () {
let id = this.get('page.id');
return `publish-dialog-${id}`;
}),
blockTitleId: computed('page', function () {
let id = this.get('page.id');
return `block-title-${id}`;
}),
blockExcerptId: computed('page', function () {
let id = this.get('page.id');
return `block-excerpt-${id}`;
}),
copyButtonId: computed('page', function () {
let id = this.get('page.id');
return `copy-page-button-${id}`;
}),
copyDialogId: computed('page', function () {
let id = this.get('page.id');
return `copy-dialog-${id}`;
}),
moveButtonId: computed('page', function () {
let id = this.get('page.id');
return `move-page-button-${id}`;
}),
moveDialogId: computed('page', function () {
let id = this.get('page.id');
return `move-dialog-${id}`;
}),
didRender() {
$("#" + this.get('blockTitleId')).removeClass('error');
$("#" + this.get('blockExcerptId')).removeClass('error');
},
actions: {
onMenuOpen() {
if ($('#' + this.get('publishDialogId')).is( ":visible" )) {
return;
}
if ($('#' + this.get('copyDialogId')).is( ":visible" )) {
return;
}
if ($('#' + this.get('moveDialogId')).is( ":visible" )) {
return;
}
this.set('menuOpen', !this.get('menuOpen'));
},
onEdit() {
this.attrs.onEdit();
},
deletePage() {
this.attrs.onDeletePage(this.get('deleteChildren'));
},
onSavePageAsBlock() {
let page = this.get('page');
let titleElem = '#' + this.get('blockTitleId');
let blockTitle = this.get('blockTitle');
if (is.empty(blockTitle)) {
$(titleElem).addClass('error');
return;
}
let excerptElem = '#' + this.get('blockExcerptId');
let blockExcerpt = this.get('blockExcerpt');
blockExcerpt = blockExcerpt.replace(/\n/g, "");
if (is.empty(blockExcerpt)) {
$(excerptElem).addClass('error');
return;
}
this.get('documentService').getPageMeta(this.get('document.id'), page.get('id')).then((pm) => {
let block = {
folderId: this.get('folder.id'),
contentType: page.get('contentType'),
pageType: page.get('pageType'),
title: blockTitle,
body: page.get('body'),
excerpt: blockExcerpt,
rawBody: pm.get('rawBody'),
config: pm.get('config'),
externalSource: pm.get('externalSource')
};
this.attrs.onSavePageAsBlock(block);
this.set('menuOpen', false);
this.set('blockTitle', '');
this.set('blockExcerpt', '');
$(titleElem).removeClass('error');
$(excerptElem).removeClass('error');
return true;
});
},
// Copy/move actions
onCopyDialogOpen() {
// Fetch document targets once.
if (this.get('documentList').length > 0) {
return;
}
this.get('documentService').getPageMoveCopyTargets().then((d) => {
let me = this.get('document');
this.set('documentList', d);
this.set('documentListOthers', d.filter((item) => item.get('id') !== me.get('id')));
});
},
onTargetChange(d) {
this.set('selectedDocument', d);
},
onCopyPage() {
// can't proceed if no data
if (this.get('documentList.length') === 0) {
return;
}
let targetDocumentId = this.get('document.id');
if (is.not.null(this.get('selectedDocument'))) {
targetDocumentId = this.get('selectedDocument.id');
}
this.attrs.onCopyPage(targetDocumentId);
return true;
},
onMovePage() {
// can't proceed if no data
if (this.get('documentListOthers.length') === 0) {
return;
}
if (is.null(this.get('selectedDocument'))) {
this.set('selectedDocument', this.get('documentListOthers')[0]);
}
let targetDocumentId = this.get('selectedDocument.id');
this.attrs.onMovePage(targetDocumentId);
return true;
}
}
});

View file

@ -0,0 +1,24 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
documentService: Ember.inject.service('document'),
didReceiveAttrs() {
this._super(...arguments);
this.get('documentService').getActivity(this.get('document.id')).then((activity) => {
this.set('activity', activity);
});
}
});

View file

@ -0,0 +1,147 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
import TooltipMixin from '../../mixins/tooltip';
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
documentService: Ember.inject.service('document'),
appMeta: Ember.inject.service(),
drop: null,
emptyState: Ember.computed.empty('files'),
deleteAttachment: {
id: "",
name: "",
},
init() {
this._super(...arguments);
this.getAttachments();
},
didInsertElement() {
this._super(...arguments);
if (!this.get('isEditor')) {
return;
}
let self = this;
let documentId = this.get('document.id');
let url = this.get('appMeta.endpoint');
let uploadUrl = `${url}/documents/${documentId}/attachments`;
let dzone = new Dropzone("#upload-document-files", {
headers: {
'Authorization': 'Bearer ' + self.get('session.session.content.authenticated.token')
},
url: uploadUrl,
method: "post",
paramName: 'attachment',
clickable: true,
maxFilesize: 10,
parallelUploads: 3,
uploadMultiple: false,
addRemoveLinks: false,
autoProcessQueue: true,
init: function () {
this.on("success", function (file /*, response*/ ) {
self.showNotification(`Attached ${file.name}`);
});
this.on("queuecomplete", function () {
self.getAttachments();
});
this.on("addedfile", function ( /*file*/ ) {
});
}
});
dzone.on("complete", function (file) {
dzone.removeFile(file);
});
this.set('drop', dzone);
},
willDestroyElement() {
this._super(...arguments);
let drop = this.get('drop');
if (is.not.null(drop)) {
drop.destroy();
}
},
getAttachments() {
this.get('documentService').getAttachments(this.get('document.id')).then((files) => {
this.set('files', files);
});
},
actions: {
onConfirmDelete(id, name) {
this.set('deleteAttachment', {
id: id,
name: name
});
$(".delete-attachment-dialog").css("display", "block");
let drop = new Drop({
target: $(".delete-attachment-" + id)[0],
content: $(".delete-attachment-dialog")[0],
classes: 'drop-theme-basic',
position: "bottom right",
openOn: "always",
tetherOptions: {
offset: "5px 0",
targetOffset: "10px 0"
},
remove: false
});
this.set('drop', drop);
},
onCancel() {
let drop = this.get('drop');
drop.close();
this.set('deleteAttachment', {
id: "",
name: ""
});
},
onDelete() {
let attachment = this.get('deleteAttachment');
let drop = this.get('drop');
drop.close();
this.showNotification(`Deleted ${name}`);
this.get('documentService').deleteAttachment(this.get('document.id'), attachment.id).then(() => {
this.getAttachments();
this.set('deleteAttachment', {
id: "",
name: ""
});
});
return true;
}
}
});

View file

@ -0,0 +1,24 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
page: {},
tagName: "li",
classNames: ["item"],
actions: {
onClick(id) {
this.get('onClick')(id);
}
}
});

View file

@ -0,0 +1,170 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
import TooltipMixin from '../../mixins/tooltip';
import tocUtil from '../../utils/toc';
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
document: {},
folder: {},
pages: [],
currentPageId: "",
state: {
actionablePage: false,
upDisabled: true,
downDisabled: true,
indentDisabled: true,
outdentDisabled: true
},
emptyState: Ember.computed('pages', function () {
return this.get('pages.length') === 0;
}),
didReceiveAttrs: function () {
this._super(...arguments);
this.set('showToc', is.not.undefined(this.get('pages')) && this.get('pages').get('length') > 0);
if (is.not.null(this.get('currentPageId'))) {
this.send('onEntryClick', this.get('currentPageId'));
}
},
didRender: function () {
this._super(...arguments);
if (this.session.authenticated) {
this.addTooltip(document.getElementById("toc-up-button"));
this.addTooltip(document.getElementById("toc-down-button"));
this.addTooltip(document.getElementById("toc-outdent-button"));
this.addTooltip(document.getElementById("toc-indent-button"));
}
},
didInsertElement() {
this._super(...arguments);
this.eventBus.subscribe('documentPageAdded', this, 'onDocumentPageAdded');
},
willDestroyElement() {
this._super(...arguments);
this.eventBus.unsubscribe('documentPageAdded');
this.destroyTooltips();
},
onDocumentPageAdded(pageId) {
this.send('onEntryClick', pageId);
},
// Controls what user can do with the toc (left sidebar).
// Identifies the target pages.
setState(pageId) {
this.set('currentPageId', pageId);
let toc = this.get('pages');
let page = _.findWhere(toc, { id: pageId });
let state = tocUtil.getState(toc, page);
if (!this.get('isEditor') || is.empty(pageId)) {
state.actionablePage = false;
state.upDisabled = state.downDisabled = state.indentDisabled = state.outdentDisabled = true;
}
this.set('state', state);
},
actions: {
// Page up - above pages shunt down.
pageUp() {
if (this.get('state.upDisabled')) {
return;
}
let state = this.get('state');
let pages = this.get('pages');
let page = _.findWhere(pages, { id: this.get('currentPageId') });
let pendingChanges = tocUtil.moveUp(state, pages, page);
if (pendingChanges.length > 0) {
this.attrs.onPageSequenceChange(pendingChanges);
this.send('onEntryClick', this.get('currentPageId'));
this.showNotification("Moved up");
}
},
// Move down -- pages below shift up.
pageDown() {
if (this.get('state.downDisabled')) {
return;
}
let state = this.get('state');
var pages = this.get('pages');
var page = _.findWhere(pages, { id: this.get('currentPageId') });
let pendingChanges = tocUtil.moveDown(state, pages, page);
if (pendingChanges.length > 0) {
this.attrs.onPageSequenceChange(pendingChanges);
this.send('onEntryClick', this.get('currentPageId'));
this.showNotification("Moved down");
}
},
// Indent - changes a page from H2 to H3, etc.
pageIndent() {
if (this.get('state.indentDisabled')) {
return;
}
let state = this.get('state');
var pages = this.get('pages');
var page = _.findWhere(pages, { id: this.get('currentPageId') });
let pendingChanges = tocUtil.indent(state, pages, page);
if (pendingChanges.length > 0) {
this.attrs.onPageLevelChange(pendingChanges);
this.showNotification("Indent");
this.send('onEntryClick', this.get('currentPageId'));
}
},
// Outdent - changes a page from H3 to H2, etc.
pageOutdent() {
if (this.get('state.outdentDisabled')) {
return;
}
let state = this.get('state');
var pages = this.get('pages');
var page = _.findWhere(pages, { id: this.get('currentPageId') });
let pendingChanges = tocUtil.outdent(state, pages, page);
if (pendingChanges.length > 0) {
this.attrs.onPageLevelChange(pendingChanges);
this.showNotification("Outdent");
this.send('onEntryClick', this.get('currentPageId'));
}
},
onEntryClick(id) {
this.setState(id);
this.attrs.onGotoPage(id);
}
}
});

View file

@ -0,0 +1,148 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import TooltipMixin from '../../mixins/tooltip';
import NotifierMixin from '../../mixins/notifier';
export default Ember.Component.extend(TooltipMixin, NotifierMixin, {
documentService: Ember.inject.service('document'),
sectionService: Ember.inject.service('section'),
sessionService: Ember.inject.service('session'),
appMeta: Ember.inject.service(),
userService: Ember.inject.service('user'),
localStorage: Ember.inject.service(),
pinned: Ember.inject.service(),
menuOpen: false,
pinState : {
isPinned: false,
pinId: '',
newName: '',
},
saveTemplate: {
name: "",
description: ""
},
tab: '',
init() {
this._super(...arguments);
if (is.empty(this.get('tab')) || is.undefined(this.get('tab'))) {
this.set('tab', 'index');
}
},
didReceiveAttrs() {
this._super(...arguments);
this.set('saveTemplate.name', this.get('document.name'));
this.set('saveTemplate.description', this.get('document.excerpt'));
this.set('pinState.pinId', this.get('pinned').isDocumentPinned(this.get('document.id')));
this.set('pinState.isPinned', this.get('pinState.pinId') !== '');
this.set('pinState.newName', this.get('document.name').substring(0,3).toUpperCase());
},
actions: {
onChangeTab(tab) {
this.set('tab', tab);
},
onTagChange(tags) {
let doc = this.get('document');
doc.set('tags', tags);
this.get('documentService').save(doc);
},
onMenuOpen() {
this.set('menuOpen', !this.get('menuOpen'));
},
onDeleteDocument() {
this.attrs.onDocumentDelete();
},
onPrintDocument() {
$("#sidebar-zone-more-button").click();
window.print();
},
onPageSequenceChange(changes) {
this.get('onPageSequenceChange')(changes);
},
onPageLevelChange(changes) {
this.get('onPageLevelChange')(changes);
},
onGotoPage(id) {
this.get('onGotoPage')(id);
},
onUnpin() {
this.get('pinned').unpinItem(this.get('pinState.pinId')).then(() => {
this.set('pinState.isPinned', false);
this.set('pinState.pinId', '');
this.eventBus.publish('pinChange');
});
},
onPin() {
let pin = {
pin: this.get('pinState.newName'),
documentId: this.get('document.id'),
folderId: this.get('folder.id')
};
if (is.empty(pin.pin)) {
$("#pin-document-name").addClass("error").focus();
return false;
}
this.get('pinned').pinItem(pin).then((pin) => {
this.set('pinState.isPinned', true);
this.set('pinState.pinId', pin.get('id'));
this.eventBus.publish('pinChange');
});
return true;
},
onSaveTemplate() {
var name = this.get('saveTemplate.name');
var excerpt = this.get('saveTemplate.description');
if (is.empty(name)) {
$("#new-template-name").addClass("error").focus();
return false;
}
if (is.empty(excerpt)) {
$("#new-template-desc").addClass("error").focus();
return false;
}
this.showNotification('Template saved');
this.attrs.onSaveTemplate(name, excerpt);
return true;
},
onLayoutChange(layout) {
let doc = this.get('document');
doc.set('layout', layout);
this.get('documentService').save(doc);
return true;
}
}
});

View file

@ -0,0 +1,200 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import TooltipMixin from '../../mixins/tooltip';
const {
computed,
inject: { service }
} = Ember;
export default Ember.Component.extend(TooltipMixin, {
documentService: service('document'),
expanded: false,
deleteChildren: false,
menuOpen: false,
blockTitle: "",
blockExcerpt: "",
documentList: [], //includes the current document
documentListOthers: [], //excludes the current document
selectedDocument: null,
checkId: computed('page', function () {
let id = this.get('page.id');
return `delete-check-button-${id}`;
}),
menuTarget: computed('page', function () {
let id = this.get('page.id');
return `page-menu-${id}`;
}),
deleteButtonId: computed('page', function () {
let id = this.get('page.id');
return `delete-page-button-${id}`;
}),
publishButtonId: computed('page', function () {
let id = this.get('page.id');
return `publish-button-${id}`;
}),
publishDialogId: computed('page', function () {
let id = this.get('page.id');
return `publish-dialog-${id}`;
}),
blockTitleId: computed('page', function () {
let id = this.get('page.id');
return `block-title-${id}`;
}),
blockExcerptId: computed('page', function () {
let id = this.get('page.id');
return `block-excerpt-${id}`;
}),
copyButtonId: computed('page', function () {
let id = this.get('page.id');
return `copy-page-button-${id}`;
}),
copyDialogId: computed('page', function () {
let id = this.get('page.id');
return `copy-dialog-${id}`;
}),
moveButtonId: computed('page', function () {
let id = this.get('page.id');
return `move-page-button-${id}`;
}),
moveDialogId: computed('page', function () {
let id = this.get('page.id');
return `move-dialog-${id}`;
}),
didRender() {
$("#" + this.get('blockTitleId')).removeClass('error');
$("#" + this.get('blockExcerptId')).removeClass('error');
},
actions: {
toggleExpand() {
this.set('expanded', !this.get('expanded'));
this.get('onExpand')();
},
onMenuOpen() {
if ($('#' + this.get('publishDialogId')).is( ":visible" )) {
return;
}
if ($('#' + this.get('copyDialogId')).is( ":visible" )) {
return;
}
if ($('#' + this.get('moveDialogId')).is( ":visible" )) {
return;
}
this.set('menuOpen', !this.get('menuOpen'));
},
onEdit() {
this.attrs.onEdit();
},
deletePage() {
this.attrs.onDeletePage(this.get('deleteChildren'));
},
onSavePageAsBlock() {
let page = this.get('page');
let titleElem = '#' + this.get('blockTitleId');
let blockTitle = this.get('blockTitle');
if (is.empty(blockTitle)) {
$(titleElem).addClass('error');
return;
}
let excerptElem = '#' + this.get('blockExcerptId');
let blockExcerpt = this.get('blockExcerpt');
blockExcerpt = blockExcerpt.replace(/\n/g, "");
if (is.empty(blockExcerpt)) {
$(excerptElem).addClass('error');
return;
}
this.get('documentService').getPageMeta(this.get('document.id'), page.get('id')).then((pm) => {
let block = {
folderId: this.get('folder.id'),
contentType: page.get('contentType'),
pageType: page.get('pageType'),
title: blockTitle,
body: page.get('body'),
excerpt: blockExcerpt,
rawBody: pm.get('rawBody'),
config: pm.get('config'),
externalSource: pm.get('externalSource')
};
this.attrs.onSavePageAsBlock(block);
this.set('menuOpen', false);
this.set('blockTitle', '');
this.set('blockExcerpt', '');
$(titleElem).removeClass('error');
$(excerptElem).removeClass('error');
return true;
});
},
// Copy/move actions
onCopyDialogOpen() {
// Fetch document targets once.
if (this.get('documentList').length > 0) {
return;
}
this.get('documentService').getPageMoveCopyTargets().then((d) => {
let me = this.get('document');
this.set('documentList', d);
this.set('documentListOthers', d.filter((item) => item.get('id') !== me.get('id')));
});
},
onTargetChange(d) {
this.set('selectedDocument', d);
},
onCopyPage() {
// can't proceed if no data
if (this.get('documentList.length') === 0) {
return;
}
let targetDocumentId = this.get('document.id');
if (is.not.null(this.get('selectedDocument'))) {
targetDocumentId = this.get('selectedDocument.id');
}
this.attrs.onCopyPage(targetDocumentId);
return true;
},
onMovePage() {
// can't proceed if no data
if (this.get('documentListOthers.length') === 0) {
return;
}
if (is.null(this.get('selectedDocument'))) {
this.set('selectedDocument', this.get('documentListOthers')[0]);
}
let targetDocumentId = this.get('selectedDocument.id');
this.attrs.onMovePage(targetDocumentId);
return true;
}
}
});

View file

@ -0,0 +1,109 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
documentTags: [],
tagz: [],
isEditor: false,
newTag: "",
maxTags: 3,
canAdd: false,
init() {
this._super(...arguments);
let tagz = [];
if (!_.isUndefined(this.get('documentTags')) && this.get('documentTags').length > 1) {
let tags = this.get('documentTags').split('#');
_.each(tags, function(tag) {
if (tag.length > 0) {
tagz.pushObject(tag);
}
});
}
this.set('tagz', tagz);
this.set('canAdd', this.get('isEditor') && this.get('tagz').get('length') < 3);
},
didUpdateAttrs() {
this.set('canAdd', this.get('isEditor') && this.get('tagz').get('length') < 3);
},
didInsertElement() {
},
willDestroyElement() {
$("#add-tag-field").off("keydown");
},
actions: {
onTagEditor() {
$("#add-tag-field").off("keydown").on("keydown", function(e) {
if (e.shiftKey) {
return false;
}
if (e.which === 13 || e.which === 45 || e.which === 189 || e.which === 8 || e.which === 127 || (e.which >= 65 && e.which <= 90) || (e.which >= 97 && e.which <= 122) || (e.which >= 48 && e.which <= 57)) {
return true;
}
return false;
});
},
addTag() {
let tags = this.get("tagz");
let tag = this.get('newTag');
tag = tag.toLowerCase().trim();
// empty or dupe?
if (tag.length === 0 || _.contains(tags, tag) || tags.length >= this.get('maxTags') || tag.startsWith('-')) {
return false;
}
tags.pushObject(tag);
this.set('tagz', tags);
this.set('newTag', '');
let save = "#";
_.each(tags, function(tag) {
save = save + tag + "#";
});
this.get('onChange')(save);
return true;
},
// removeTag removes specified tag from the list of tags associated with this document.
removeTag(tagToRemove) {
let tags = this.get("tagz");
let save = "";
tags = _.without(tags, tagToRemove);
_.each(tags, function(tag) {
save = save + tag + "#";
});
if (save.length) {
save = "#" + save;
}
this.set('tagz', tags);
this.get('onChange')(save);
},
}
});

View file

@ -0,0 +1,71 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
const {
isEmpty,
computed,
set
} = Ember;
export default Ember.Component.extend({
titleEmpty: computed.empty('model.title'),
firstnameEmpty: computed.empty('model.firstname'),
lastnameEmpty: computed.empty('model.lastname'),
emailEmpty: computed.empty('model.email'),
passwordEmpty: computed.empty('model.password'),
hasEmptyTitleError: computed.and('titleEmpty', 'titleError'),
hasEmptyFirstnameError: computed.and('firstnameEmpty', 'adminFirstnameError'),
hasEmptyLastnameError: computed.and('lastnameEmpty', 'adminLastnameError'),
hasEmptyEmailError: computed.and('emailEmpty', 'adminEmailError'),
hasEmptyPasswordError: computed.and('passwordEmpty', 'adminPasswordError'),
actions: {
save() {
if (isEmpty(this.get('model.title'))) {
set(this, 'titleError', true);
return $("#siteTitle").focus();
}
if (isEmpty(this.get('model.firstname'))) {
set(this, 'adminFirstnameError', true);
return $("#adminFirstname").focus();
}
if (isEmpty(this.get('model.lastname'))) {
set(this, 'adminLastnameError', true);
return $("#adminLastname").focus();
}
if (isEmpty(this.get('model.email')) || !is.email(this.get('model.email'))) {
set(this, 'adminEmailError', true);
return $("#adminEmail").focus();
}
if (isEmpty(this.get('model.password'))) {
set(this, 'adminPasswordError', true);
return $("#adminPassword").focus();
}
this.model.allowAnonymousAccess = Ember.$("#allowAnonymousAccess").prop('checked');
this.get('save')().then(() => {
set(this, 'titleError', false);
set(this, 'adminFirstnameError', false);
set(this, 'adminLastnameError', false);
set(this, 'adminEmailError', false);
set(this, 'adminPasswordError', false);
});
}
}
});

View file

@ -0,0 +1,130 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import stringUtil from '../utils/string';
export default Ember.Component.extend({
drop: null,
target: null,
button: "Delete",
color: "flat-red",
button2: "",
color2: "2",
open: "click",
position: 'bottom right',
showCancel: true,
contentId: "",
focusOn: null, // is there an input field we need to focus?
selectOn: null, // is there an input field we need to select?
onOpenCallback: null, // callback when opened
onAction: null,
onAction2: null,
offset: "5px 0",
targetOffset: "10px 0",
constrainToWindow: true,
constrainToScrollParent: true,
tether: Ember.inject.service(),
hasSecondButton: Ember.computed('button2', 'color2', function () {
return is.not.empty(this.get('button2')) && is.not.empty(this.get('color2'));
}),
didReceiveAttrs() {
this.set("contentId", 'dropdown-dialog-' + stringUtil.makeId(10));
},
didInsertElement() {
this._super(...arguments);
// TODO: refactor to eliminate self
let self = this;
if (is.null(self.get('target'))) {
return;
}
let drop = this.get('tether').createDrop({
target: document.getElementById(self.get('target')),
content: self.$(".dropdown-dialog")[0],
classes: 'drop-theme-basic',
position: self.get('position'),
openOn: self.get('open'),
constrainToWindow: true,
constrainToScrollParent: false,
tetherOptions: {
offset: self.offset,
targetOffset: self.targetOffset,
targetModifier: 'scroll-handle'
},
remove: true
});
if (drop) {
drop.on('open', function () {
if (is.not.null(self.get("focusOn"))) {
document.getElementById(self.get("focusOn")).focus();
}
if (is.not.null(self.get("selectOn"))) {
document.getElementById(self.get("selectOn")).select();
}
if (is.not.null(self.get("onOpenCallback"))) {
self.attrs.onOpenCallback(drop);
}
});
self.set('drop', drop);
}
},
willDestroyElement() {
let drop = this.get('drop');
if (drop) {
drop.destroy();
}
},
actions: {
onCancel() {
let drop = this.get('drop');
if (drop) {
drop.close();
}
},
onAction() {
if (this.get('onAction') === null) {
return;
}
let close = this.attrs.onAction();
let drop = this.get('drop');
if (close && drop) {
drop.close();
}
},
onAction2() {
if (this.get('onAction2') === null) {
return;
}
let close = this.attrs.onAction2();
let drop = this.get('drop');
if (close && drop) {
drop.close();
}
}
}
});

View file

@ -0,0 +1,71 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import stringUtil from '../utils/string';
export default Ember.Component.extend({
target: null,
open: "click",
position: 'bottom right',
contentId: "",
drop: null,
onOpenCallback: null, // callback when opened
onCloseCallback: null, // callback when closed
tether: Ember.inject.service(),
didReceiveAttrs() {
this.set("contentId", 'dropdown-menu-' + stringUtil.makeId(10));
},
didInsertElement() {
this._super(...arguments);
let self = this;
let drop = this.get('tether').createDrop({
target: document.getElementById(self.get('target')),
content: self.$(".dropdown-menu")[0],
classes: 'drop-theme-menu',
position: self.get('position'),
openOn: self.get('open'),
constrainToWindow: false,
constrainToScrollParent: false,
tetherOptions: {
offset: "5px 0",
targetOffset: "10px 0",
targetModifier: 'scroll-handle',
},
remove: true
});
if (drop) {
drop.on('open', function () {
if (is.not.null(self.get("onOpenCallback"))) {
self.attrs.onOpenCallback(drop);
}
});
drop.on('close', function () {
if (is.not.null(self.get("onCloseCallback"))) {
self.attrs.onCloseCallback();
}
});
self.set('drop', drop);
}
},
willDestroyElement() {
let drop = this.get('drop');
if (drop) {
drop.destroy();
}
}
});

View file

@ -0,0 +1,18 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.TextField.extend({
becomeFocused: function() {
this.$().focus();
}.on('didInsertElement')
});

View file

@ -0,0 +1,18 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.TextArea.extend({
becomeFocused: function() {
this.$().focus();
}.on('didInsertElement')
});

View file

@ -9,10 +9,11 @@
//
// https://documize.com
import Component from '@ember/component';
import Ember from 'ember';
export default Component.extend({
classNames: ['hashtags'],
export default Ember.Component.extend({
documentTags: [],
tagz: [],
init() {
this._super(...arguments);
@ -22,7 +23,7 @@ export default Component.extend({
let tags = this.get('documentTags').split('#');
_.each(tags, function(tag) {
if (tag.length > 0) {
tagz.pushObject(tag);
tagz.pushObject("#" + tag);
}
});
}

View file

@ -0,0 +1,109 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
folderService: Ember.inject.service('folder'),
selectedDocuments: [],
moveTarget: null,
emptyState: Ember.computed('documents', function() {
return this.get('documents.length') === 0;
}),
didReceiveAttrs() {
this._super(...arguments);
this.set('selectedDocuments', []);
this.set('canCreate', this.get('folderService').get('canEditCurrentFolder'));
this.set('deleteTargets', this.get('folders').rejectBy('id', this.get('folder.id')));
},
didUpdateAttrs() {
this._super(...arguments);
this.setupAddWizard();
},
didInsertElement() {
this._super(...arguments);
this.setupAddWizard();
},
setupAddWizard() {
Ember.run.schedule('afterRender', () => {
$('.start-document:not(.start-document-empty-state)').off('.hoverIntent');
$('.start-document:not(.start-document-empty-state)').hoverIntent({interval: 100, over: function() {
// in
$(this).find('.start-button').velocity("transition.slideDownIn", {duration: 300});
}, out: function() {
// out
$(this).find('.start-button').velocity("transition.slideUpOut", {duration: 300});
} });
});
},
actions: {
selectDocument(documentId) {
let doc = this.get('documents').findBy('id', documentId);
let list = this.get('selectedDocuments');
doc.set('selected', !doc.get('selected'));
if (doc.get('selected')) {
list.push(documentId);
} else {
var index = list.indexOf(documentId);
if (index > -1) {
list.splice(index, 1);
}
}
this.set('selectedDocuments', list);
this.get('onDocumentsChecked')(list);
},
onDelete() {
this.get("onDeleteSpace")();
},
onImport() {
this.get('onImport')();
},
onShowDocumentWizard(docId) {
if ($("#new-document-wizard").is(':visible') && this.get('docId') === docId) {
this.send('onHideDocumentWizard');
return;
}
this.set('docId', docId);
if (docId === '') {
$("#new-document-wizard").insertAfter('#wizard-placeholder');
} else {
$("#new-document-wizard").insertAfter(`#document-${docId}`);
}
$("#new-document-wizard").velocity("transition.slideDownIn", { duration: 300, complete:
function() {
$("#new-document-name").focus();
}});
},
onHideDocumentWizard() {
$("#new-document-wizard").insertAfter('#wizard-placeholder');
$("#new-document-wizard").velocity("transition.slideUpOut", { duration: 300 });
}
}
});

View file

@ -0,0 +1,60 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
import TooltipMixin from '../../mixins/tooltip';
const {
computed,
} = Ember;
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
folderService: Ember.inject.service('folder'),
folderName: '',
hasNameError: computed.empty('folderName'),
editMode: false,
isEditor: false,
keyUp(e) {
if (e.keyCode === 27) { // escape key
this.send('onCancel');
}
},
actions: {
toggleEdit() {
this.set('folderName', this.get('folder.name'));
this.set('editMode', true);
Ember.run.schedule('afterRender', () => {
$('#folder-name').select();
});
},
onSave() {
if (this.get('hasNameError')) {
return;
}
this.set('folder.name', this.get('folderName'));
this.get('folderService').save(this.get('folder'));
this.showNotification('Saved');
this.set('editMode', false);
},
onCancel() {
this.set('editMode', false);
}
}
});

View file

@ -0,0 +1,91 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
import TooltipMixin from '../../mixins/tooltip';
import AuthMixin from '../../mixins/auth';
const {
computed
} = Ember;
export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
folderService: Ember.inject.service('folder'),
session: Ember.inject.service(),
appMeta: Ember.inject.service(),
showToolbar: false,
folder: {},
busy: false,
isFolderOwner: computed.equal('folder.userId', 'session.user.id'),
moveFolderId: "",
drop: null,
didReceiveAttrs() {
this.set('isFolderOwner', this.get('folder.userId') === this.get("session.user.id"));
let show = this.get('session.authenticated') || this.get('isFolderOwner') || this.get('hasSelectedDocuments') || this.get('folderService').get('canEditCurrentFolder');
this.set('showToolbar', show);
let targets = _.reject(this.get('folders'), {
id: this.get('folder').get('id')
});
this.set('movedFolderOptions', targets);
},
didRender() {
if (this.get('hasSelectedDocuments')) {
this.addTooltip(document.getElementById("move-documents-button"));
this.addTooltip(document.getElementById("delete-documents-button"));
} else {
if (this.get('isFolderOwner')) {
this.addTooltip(document.getElementById("folder-share-button"));
this.addTooltip(document.getElementById("folder-settings-button"));
}
}
},
willDestroyElement() {
if (is.not.null(this.get('drop'))) {
this.get('drop').destroy();
this.set('drop', null);
}
this.destroyTooltips();
},
actions: {
deleteDocuments() {
this.attrs.onDeleteDocument();
},
setMoveFolder(folderId) {
this.set('moveFolderId', folderId);
let folders = this.get('folders');
folders.forEach(folder => {
folder.set('selected', folder.id === folderId);
});
},
moveDocuments() {
if (this.get("moveFolderId") === "") {
return false;
}
this.attrs.onMoveDocument(this.get('moveFolderId'));
return true;
}
}
});

View file

@ -0,0 +1,73 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import constants from '../../utils/constants';
import TooltipMixin from '../../mixins/tooltip';
import NotifierMixin from '../../mixins/notifier';
import AuthMixin from '../../mixins/auth';
export default Ember.Component.extend(TooltipMixin, NotifierMixin, AuthMixin, {
publicFolders: [],
protectedFolders: [],
privateFolders: [],
hasPublicFolders: false,
hasProtectedFolders: false,
hasPrivateFolders: false,
newFolder: '',
didReceiveAttrs() {
let folders = this.get('folders');
// clear out state
this.set('publicFolders', []);
this.set('protectedFolders', []);
this.set('privateFolders', []);
_.each(folders, folder => {
if (folder.get('folderType') === constants.FolderType.Public) {
let folders = this.get('publicFolders');
folders.pushObject(folder);
this.set('publicFolders', folders);
}
if (folder.get('folderType') === constants.FolderType.Private) {
let folders = this.get('privateFolders');
folders.pushObject(folder);
this.set('privateFolders', folders);
}
if (folder.get('folderType') === constants.FolderType.Protected) {
let folders = this.get('protectedFolders');
folders.pushObject(folder);
this.set('protectedFolders', folders);
}
});
this.set('hasPublicFolders', this.get('publicFolders.length') > 0);
this.set('hasPrivateFolders', this.get('privateFolders.length') > 0);
this.set('hasProtectedFolders', this.get('protectedFolders.length') > 0);
},
actions: {
addFolder() {
var folderName = this.get('newFolder');
if (is.empty(folderName)) {
$("#new-folder-name").addClass("error").focus();
return false;
}
this.attrs.onFolderAdd(folderName);
this.set('newFolder', '');
return true;
}
}
});

View file

@ -0,0 +1,135 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
const {
inject: { service }
} = Ember;
export default Ember.Component.extend(NotifierMixin, {
folderService: service('folder'),
userService: service('user'),
appMeta: service(),
store: service(),
didReceiveAttrs() {
this.get('userService').getAll().then((users) => {
this.set('users', users);
var folderPermissions = [];
users.forEach((user) => {
let isActive = user.get('active');
let u = {
userId: user.get('id'),
fullname: user.get('fullname'),
orgId: this.get('folder.orgId'),
folderId: this.get('folder.id'),
canEdit: false,
canView: false,
canViewPrevious: false
};
if (isActive) {
folderPermissions.pushObject(u);
}
});
var u = {
userId: "",
fullname: " Everyone",
orgId: this.get('folder.orgId'),
folderId: this.get('folder.id'),
canEdit: false,
canView: false
};
folderPermissions.pushObject(u);
this.get('folderService').getPermissions(this.get('folder.id')).then((permissions) => {
permissions.forEach((permission, index) => { // eslint-disable-line no-unused-vars
var folderPermission = folderPermissions.findBy('userId', permission.get('userId'));
if (is.not.undefined(folderPermission)) {
Ember.setProperties(folderPermission, {
orgId: permission.get('orgId'),
folderId: permission.get('folderId'),
canEdit: permission.get('canEdit'),
canView: permission.get('canView'),
canViewPrevious: permission.get('canView')
});
}
});
folderPermissions.map((permission) => {
let data = this.get('store').normalize('folder-permission', permission);
return this.get('store').push(data);
});
this.set('permissions', folderPermissions.sortBy('fullname'));
});
});
},
getDefaultInvitationMessage() {
return "Hey there, I am sharing the " + this.get('folder.name') + " (in " + this.get("appMeta.title") + ") with you so we can both access the same documents.";
},
actions: {
setPermissions() {
let message = this.getDefaultInvitationMessage();
let folder = this.get('folder');
let permissions = this.get('permissions');
this.get('permissions').forEach((permission, index) => { // eslint-disable-line no-unused-vars
Ember.set(permission, 'canView', $("#canView-" + permission.userId).prop('checked'));
Ember.set(permission, 'canEdit', $("#canEdit-" + permission.userId).prop('checked'));
});
var data = permissions.map((obj) => {
let permission = {
'orgId': obj.orgId,
'folderId': obj.folderId,
'userId': obj.userId,
'canEdit': obj.canEdit,
'canView': obj.canView
};
return permission;
});
var payload = { Message: message, Roles: data };
this.get('folderService').savePermissions(folder.get('id'), payload).then(() => {
});
var hasEveryone = _.find(data, function (permission) {
return permission.userId === "" && (permission.canView || permission.canEdit);
});
if (is.not.undefined(hasEveryone)) {
folder.markAsPublic();
} else {
if (data.length > 1) {
folder.markAsRestricted();
} else {
folder.markAsPrivate();
}
}
this.get('folderService').save(folder).then(function () {
// window.location.href = "/folder/" + folder.get('id') + "/" + folder.get('slug');
});
}
}
});

View file

@ -0,0 +1,74 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
const {
inject: { service }
} = Ember;
export default Ember.Component.extend(NotifierMixin, {
folderService: service('folder'),
appMeta: service(),
inviteEmail: '',
inviteMessage: '',
getDefaultInvitationMessage() {
return "Hey there, I am sharing the " + this.folder.get('name') + " (in " + this.get("appMeta.title") + ") with you so we can both access the same documents.";
},
willRender() {
if (this.get('inviteMessage').length === 0) {
this.set('inviteMessage', this.getDefaultInvitationMessage());
}
},
actions: {
onShare() {
var email = this.get('inviteEmail').trim().replace(/ /g, '');
var message = this.get('inviteMessage').trim();
if (message.length === 0) {
message = this.getDefaultInvitationMessage();
}
if (email.length === 0) {
$('#inviteEmail').addClass('error').focus();
return;
}
var result = {
Message: message,
Recipients: []
};
// Check for multiple email addresses
if (email.indexOf(",") > -1) {
result.Recipients = email.split(',');
}
if (email.indexOf(";") > -1 && result.Recipients.length === 0) {
result.Recipients = email.split(';');
}
// Handle just one email address
if (result.Recipients.length === 0 && email.length > 0) {
result.Recipients.push(email);
}
this.set('inviteEmail', '');
this.get('folderService').share(this.folder.get('id'), result).then(() => {
this.showNotification('Shared');
});
}
}
});

View file

@ -0,0 +1,101 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import TooltipMixin from '../../mixins/tooltip';
import NotifierMixin from '../../mixins/notifier';
import AuthMixin from '../../mixins/auth';
const {
inject: { service }
} = Ember;
export default Ember.Component.extend(TooltipMixin, NotifierMixin, AuthMixin, {
folderService: service('folder'),
templateService: service('template'),
appMeta: service(),
pinned: service(),
publicFolders: [],
protectedFolders: [],
privateFolders: [],
hasPublicFolders: false,
hasProtectedFolders: false,
hasPrivateFolders: false,
newFolder: "",
menuOpen: false,
pinState : {
isPinned: false,
pinId: '',
newName: '',
},
tab: '',
init() {
this._super(...arguments);
if (is.empty(this.get('tab')) || is.undefined(this.get('tab'))) {
this.set('tab', 'index');
}
},
didReceiveAttrs() {
if (!this.get('noFolder')) {
let folder = this.get('folder');
this.set('pinState.pinId', this.get('pinned').isSpacePinned(folder.get('id')));
this.set('pinState.isPinned', this.get('pinState.pinId') !== '');
this.set('pinState.newName', folder.get('name').substring(0,3).toUpperCase());
}
},
actions: {
onFolderAdd(folderName) {
this.attrs.onFolderAdd(folderName);
return true;
},
onChangeTab(tab) {
this.set('tab', tab);
},
onMenuOpen() {
this.set('menuOpen', !this.get('menuOpen'));
},
onUnpin() {
this.get('pinned').unpinItem(this.get('pinState.pinId')).then(() => {
this.set('pinState.isPinned', false);
this.set('pinState.pinId', '');
this.eventBus.publish('pinChange');
});
},
onPin() {
let pin = {
pin: this.get('pinState.newName'),
documentId: '',
folderId: this.get('folder.id')
};
if (is.empty(pin.pin)) {
$('#pin-space-name').addClass('error').focus();
return false;
}
this.get('pinned').pinItem(pin).then((pin) => {
this.set('pinState.isPinned', true);
this.set('pinState.pinId', pin.get('id'));
this.eventBus.publish('pinChange');
});
return true;
},
}
});

View file

@ -0,0 +1,154 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
const {
computed,
} = Ember;
export default Ember.Component.extend(NotifierMixin, {
localStorage: Ember.inject.service(),
appMeta: Ember.inject.service(),
templateService: Ember.inject.service('template'),
canEditTemplate: "",
importedDocuments: [],
savedTemplates: [],
drop: null,
newDocumentName: 'New Document',
newDocumentNameMissing: computed.empty('newDocumentName'),
init() {
this._super(...arguments);
this.get('templateService').getSavedTemplates().then((saved) => {
let emptyTemplate = {
id: "0",
title: "Empty",
description: "An empty canvas for your words",
layout: "doc",
locked: true
};
saved.unshiftObject(emptyTemplate);
this.set('savedTemplates', saved);
});
},
didInsertElement() {
this.setupImport();
},
willDestroyElement() {
if (is.not.null(this.get('drop'))) {
this.get('drop').destroy();
this.set('drop', null);
}
},
setupImport() {
// already done init?
if (is.not.null(this.get('drop'))) {
this.get('drop').destroy();
this.set('drop', null);
}
let self = this;
let folderId = this.get('folder.id');
let url = this.get('appMeta.endpoint');
let importUrl = `${url}/import/folder/${folderId}`;
let dzone = new Dropzone("#import-document-button", {
headers: {
'Authorization': 'Bearer ' + self.get('session.session.content.authenticated.token')
},
url: importUrl,
method: "post",
paramName: 'attachment',
acceptedFiles: ".doc,.docx,.txt,.md,.markdown",
clickable: true,
maxFilesize: 10,
parallelUploads: 3,
uploadMultiple: false,
addRemoveLinks: false,
autoProcessQueue: true,
init: function () {
this.on("success", function (document) {
self.send('onDocumentImported', document.name, document);
});
this.on("error", function (x) {
console.log("Conversion failed for ", x.name, " obj ", x); // eslint-disable-line no-console
});
this.on("queuecomplete", function () {});
this.on("addedfile", function (file) {
self.send('onDocumentImporting', file.name);
});
}
});
dzone.on("complete", function (file) {
dzone.removeFile(file);
});
this.set('drop', dzone);
},
actions: {
onHideDocumentWizard() {
this.get('onHideDocumentWizard')();
},
editTemplate(template) {
this.get('router').transitionTo('document', this.get('folder.id'), this.get('folder.slug'), template.get('id'), template.get('slug'));
return true;
},
startDocument(template) {
this.send("showNotification", "Creating");
this.get('templateService').importSavedTemplate(this.folder.get('id'), template.id, this.get('newDocumentName')).then((document) => {
this.get('router').transitionTo('document', this.get('folder.id'), this.get('folder.slug'), document.get('id'), document.get('slug'));
});
return true;
},
onDocumentImporting(filename) {
this.send("showNotification", `Importing ${filename}`);
this.get('onHideDocumentWizard')();
let documents = this.get('importedDocuments');
documents.push(filename);
this.set('importedDocuments', documents);
},
onDocumentImported(filename /*, document*/ ) {
this.send("showNotification", `${filename} ready`);
let documents = this.get('importedDocuments');
documents.pop(filename);
this.set('importedDocuments', documents);
this.get('onImport')();
if (documents.length === 0) {
// this.get('showDocument')(this.get('folder'), document);
}
},
}
});

View file

@ -0,0 +1,41 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
const {
computed,
isEmpty
} = Ember;
export default Ember.Component.extend({
email: "",
sayThanks: false,
emailEmpty: computed.empty('email'),
hasEmptyEmailError: computed.and('emailEmpty', 'emailIsEmpty'),
actions: {
forgot() {
let email = this.get('email');
if (isEmpty(email)) {
Ember.set(this, 'emailIsEmpty', true);
return $("#email").focus();
}
this.get('forgot')(email).then(() => {
Ember.set(this, 'sayThanks', true);
Ember.set(this, 'email', '');
Ember.set(this, 'emailIsEmpty', false);
});
}
}
});

View file

@ -0,0 +1,15 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
});

View file

@ -0,0 +1,27 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
const {
inject: { service }
} = Ember;
export default Ember.Component.extend(NotifierMixin, {
appMeta :service(),
didRender() {
if (this.get('appMeta').invalidLicense()) {
this.showNotification(`!! Expired or invalid license !!`);
}
}
});

View file

@ -0,0 +1,27 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
const {
inject: { service }
} = Ember;
export default Ember.Component.extend(NotifierMixin, {
appMeta :service(),
didRender() {
if (this.get('appMeta').invalidLicense()) {
this.showNotification(`!! Expired or invalid license !!`);
}
}
});

View file

@ -0,0 +1,163 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import netUtil from '../../utils/net';
import constants from '../../utils/constants';
import TooltipMixin from '../../mixins/tooltip';
const {
inject: { service }
} = Ember;
export default Ember.Component.extend(TooltipMixin, {
folderService: service('folder'),
appMeta: service(),
session: service(),
store: service(),
folder: null,
view: {
folder: false,
search: false,
settings: false,
profile: false
},
pinned: service(),
pins: [],
enableLogout: true,
init() {
this._super(...arguments);
if (this.get("session.authenticated") && this.get("session.user.id") !== '0') {
this.get("session.accounts").forEach((account) => {
// TODO: do not mutate account.active here
account.active = account.orgId === this.get("appMeta.orgId");
});
}
this.set('pins', this.get('pinned').get('pins'));
if (this.get('appMeta.authProvider') === constants.AuthProvider.Keycloak) {
let config = this.get('appMeta.authConfig');
config = JSON.parse(config);
this.set('enableLogout', !config.disableLogout);
}
},
didReceiveAttrs() {
if (this.get('folder') === null) {
this.set("folder", this.get('folderService.currentFolder'));
}
let route = this.get('router.currentRouteName');
this.set('view.folder', (is.startWith(route, 'folder')) ? true : false);
this.set('view.settings', (is.startWith(route, 'customize')) ? true : false);
this.set('view.profile', (route === 'profile') ? true : false);
this.set('view.search', (route === 'search') ? true : false);
},
didInsertElement() {
this._super(...arguments);
// Size the pinned items zone
if (this.get("session.authenticated")) {
this.eventBus.subscribe('resized', this, 'sizePinnedZone');
this.eventBus.subscribe('pinChange', this, 'setupPins');
this.sizePinnedZone();
this.setupPins();
let self = this;
var sortable = Sortable.create(document.getElementById('pinned-zone'), {
animation: 150,
onEnd: function () {
self.get('pinned').updateSequence(this.toArray()).then((pins) => {
self.set('pins', pins);
});
}
});
this.set('sortable', sortable);
}
},
didRender() {
if (this.get('session.isAdmin')) {
this.addTooltip(document.getElementById("workspace-settings"));
}
if (this.get("session.authenticated") && this.get('enableLogout')) {
this.addTooltip(document.getElementById("workspace-logout"));
} else {
this.addTooltip(document.getElementById("workspace-login"));
}
},
setupPins() {
if (this.get('isDestroyed') || this.get('isDestroying')) {
return;
}
this.get('pinned').getUserPins().then((pins) => {
if (this.get('isDestroyed') || this.get('isDestroying')) {
return;
}
this.set('pins', pins);
pins.forEach((pin) => {
this.addTooltip(document.getElementById(`pin-${pin.id}`));
});
});
},
// set height for pinned zone so ti scrolls on spill
sizePinnedZone() {
let topofBottomZone = parseInt($('#bottom-zone').css("top").replace("px", ""));
let heightOfTopZone = parseInt($('#top-zone').css("height").replace("px", ""));
let size = topofBottomZone - heightOfTopZone - 40;
$('#pinned-zone').css('height', size + "px");
},
willDestroyElement() {
let sortable = this.get('sortable');
if (!_.isUndefined(sortable)) {
sortable.destroy();
}
this.eventBus.unsubscribe('resized');
this.eventBus.unsubscribe('pinChange');
this.destroyTooltips();
},
actions: {
switchAccount(domain) {
window.location.href = netUtil.getAppUrl(domain);
},
jumpToPin(pin) {
let folderId = pin.get('folderId');
let documentId = pin.get('documentId');
if (_.isEmpty(documentId)) {
// jump to space
let folder = this.get('store').peekRecord('folder', folderId);
this.get('router').transitionTo('folder', folderId, folder.get('slug'));
} else {
// jump to doc
let folder = this.get('store').peekRecord('folder', folderId);
this.get('router').transitionTo('document', folderId, folder.get('slug'), documentId, 'document');
}
}
}
});

View file

@ -0,0 +1,15 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
});

View file

@ -0,0 +1,127 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
folderService: Ember.inject.service('folder'),
serial: "",
folderId: "",
slug: "",
processing: false,
didRender() {
let self = this;
$("#stage-1-firstname").focus();
// Stage 1 - person name keypress handler
$("#stage-1-firstname, #stage-1-lastname").keyup(function() {
if (!$("#stage-1-firstname").val() || !$("#stage-1-lastname").val()) {
$(".name-status").attr("src", "/assets/img/onboard/person-red.png");
} else {
$(".name-status").attr("src", "/assets/img/onboard/person-green.png");
}
});
// Stage 1 - finish
$("#stage-1-next").off('click').on('click', function() {
if (!$("#stage-1-firstname").val()) {
$("#stage-1-firstname").focus();
$("#stage-1-firstname").addClass("error");
$(".name-status").attr("src", "/assets/img/onboard/person-red.png");
return;
}
if (!$("#stage-1-lastname").val()) {
$("#stage-1-lastname").focus();
$("#stage-1-lastname").addClass("error");
$(".name-status").attr("src", "/assets/img/onboard/person-red.png");
return;
}
self.set('processing', false);
$(".stage-1").fadeOut("slow", function() {
if (self.get('processing')) {
return;
}
self.set('processing', true);
$(".stage-2").fadeIn();
$("#stage-2-password").focus();
// Stage 2 - password keypress handler
$("#stage-2-password-confirm").keyup(function() {
if ($("#stage-2-password").val().length < 6 || $("#stage-2-password").val().length > 50 ||
($("#stage-2-password").val() !== $("#stage-2-password-confirm").val())) {
$(".password-status").attr("src", "/assets/img/onboard/lock-red.png");
} else {
$(".password-status").attr("src", "/assets/img/onboard/lock-green.png");
}
});
});
});
// Stage 2 - finish
$("#stage-2-next").off('click').on('click', function() {
if (!$("#stage-2-password").val() || $("#stage-2-password").val().length < 6 || $("#stage-2-password").val().length > 50) {
$("#stage-2-password").focus();
$("#stage-2-password").addClass("error");
return;
}
if (!$("#stage-2-password-confirm").val()) {
$("#stage-2-password-confirm").focus();
$("#stage-2-password-confirm").addClass("error");
return;
}
if ($("#stage-2-password-confirm").val() !== $("#stage-2-password").val()) {
$(".mismatch").show();
$(".password-status").attr("src", "/assets/img/onboard/lock-red.png");
return;
}
self.set('processing', false);
$(".stage-2").fadeOut("slow", function() {
if (self.get('processing')) {
return;
}
self.set('processing', true);
$(".stage-3").fadeIn();
$("#spinner-1").show();
var payload = '{ "Password": "' + $("#stage-2-password").val() + '", "Serial": "' + self.serial + '", "Firstname": "' + $("#stage-1-firstname").val() + '", "Lastname": "' + $("#stage-1-lastname").val() + '" }';
var password = $("#stage-2-password").val();
self.get('folderService').onboard(self.folderId, payload).then(function(user) {
let creds = { password: password, email: user.email };
self.get('session').authenticate('authenticator:documize', creds).then(() => {
window.location.href = 's/' + self.folderId + "/" + self.slug;
});
// var credentials = encodingUtil.Base64.encode(netUtil.getSubdomain() + ":" + user.email + ":" + password);
// self.session.sso(credentials).then(function() {
// window.location.href = 's/' + self.folderId + "/" + self.slug;
// });
}, function() {
window.location.href = "/";
});
});
});
},
});

View file

@ -0,0 +1,59 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
const {
isEmpty,
isEqual,
computed,
set
} = Ember;
export default Ember.Component.extend({
password: "",
passwordConfirm: "",
mustMatch: false,
passwordEmpty: computed.empty('password'),
confirmEmpty: computed.empty('passwordConfirm'),
hasPasswordError: computed.and('passwordEmpty', 'passwordIsEmpty'),
hasConfirmError: computed.and('confirmEmpty', 'passwordConfirmIsEmpty'),
actions: {
reset() {
let password = this.get('password');
let passwordConfirm = this.get('passwordConfirm');
if (isEmpty(password)) {
set(this, 'passwordIsEmpty', true);
return $("#newPassword").focus();
}
if (isEmpty(passwordConfirm)) {
set(this, 'passwordConfirmIsEmpty', true);
return $("#passwordConfirm").focus();
}
if (!isEqual(password, passwordConfirm)) {
set(this, 'hasPasswordError', true);
set(this, 'hasConfirmError', true);
set(this, 'mustMatch', true);
return;
}
this.get('reset')(password).then(() => {
set(this, 'passwordIsEmpty', false);
set(this, 'passwordConfirmIsEmpty', false);
});
}
}
});

View file

@ -0,0 +1,54 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
results: [],
resultPhrase: "",
didReceiveAttrs() {
let results = this.get('results');
let temp = _.groupBy(results, 'documentId');
let documents = [];
_.each(temp, function (document) {
let refs = [];
if (document.length > 1) {
refs = document.slice(1);
}
_.each(refs, function (ref, index) {
ref.comma = index === refs.length - 1 ? "" : ", ";
});
let hasRefs = refs.length > 0;
documents.pushObject({
doc: document[0],
ref: refs,
hasReferences: hasRefs
});
});
let phrase = 'Nothing found';
if (results.length > 0) {
let references = results.length === 1 ? "reference" : "references";
let i = results.length;
phrase = `${i} ${references}`;
}
this.set('resultPhrase', phrase);
this.set('documents', documents);
}
});

View file

@ -0,0 +1,34 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
documentTags: [],
tagz: [],
init() {
this._super(...arguments);
let tagz = [];
if (this.get('documentTags').length > 1) {
let tags = this.get('documentTags').split('#');
_.each(tags, function(tag) {
if (tag.length > 0) {
tagz.pushObject(tag);
}
});
}
this.set('tagz', tagz);
}
});

View file

@ -0,0 +1,39 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
data: "",
didReceiveAttrs() {
this.set("data", this.get("meta.rawBody"));
},
actions: {
isDirty() {
return this.get('meta.rawBody') !== this.get('data');
},
onCancel() {
this.attrs.onCancel();
},
onAction(title) {
let page = this.get('page');
let meta = this.get('meta');
page.set('title', title);
meta.set('rawBody', this.get("data"));
this.attrs.onAction(page, meta);
}
}
});

View file

@ -0,0 +1,14 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({});

View file

@ -0,0 +1,143 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
const {
computed,
} = Ember;
export default Ember.Component.extend({
drop: null,
busy: false,
mousetrap: null,
hasNameError: computed.empty('page.title'),
containerId: Ember.computed('page', function () {
let page = this.get('page');
return `base-editor-inline-container-${page.id}`;
}),
pageId: Ember.computed('page', function () {
let page = this.get('page');
return `page-editor-${page.id}`;
}),
cancelId: Ember.computed('page', function () {
let page = this.get('page');
return `cancel-edits-button-${page.id}`;
}),
dialogId: Ember.computed('page', function () {
let page = this.get('page');
return `discard-edits-dialog-${page.id}`;
}),
contentLinkerButtonId: Ember.computed('page', function () {
let page = this.get('page');
return `content-linker-button-${page.id}`;
}),
previewButtonId: Ember.computed('page', function () {
let page = this.get('page');
return `content-preview-button-${page.id}`;
}),
didRender() {
let msContainer = document.getElementById(this.get('containerId'));
let mousetrap = this.get('mousetrap');
if (is.null(mousetrap)) {
mousetrap = new Mousetrap(msContainer);
}
mousetrap.bind('esc', () => {
this.send('onCancel');
return false;
});
mousetrap.bind(['ctrl+s', 'command+s'], () => {
this.send('onAction');
return false;
});
this.set('mousetrap', mousetrap);
$('#' + this.get('pageId')).focus(function() {
$(this).select();
});
},
willDestroyElement() {
let drop = this.get('drop');
if (is.not.null(drop)) {
drop.destroy();
}
let mousetrap = this.get('mousetrap');
if (is.not.null(mousetrap)) {
mousetrap.unbind('esc');
mousetrap.unbind(['ctrl+s', 'command+s']);
}
},
actions: {
onCancel() {
if (this.attrs.isDirty() !== null && this.attrs.isDirty()) {
$('#' + this.get('dialogId')).css("display", "block");
let drop = new Drop({
target: $('#' + this.get('cancelId'))[0],
content: $('#' + this.get('dialogId'))[0],
classes: 'drop-theme-basic',
position: "bottom right",
openOn: "always",
constrainToWindow: true,
constrainToScrollParent: false,
tetherOptions: {
offset: "5px 0",
targetOffset: "10px 0"
},
remove: false
});
this.set('drop', drop);
return;
}
this.attrs.onCancel();
},
onAction() {
if (this.get('busy') || is.empty(this.get('page.title'))) {
return;
}
if (this.get('isDestroyed') || this.get('isDestroying')) {
return;
}
this.attrs.onAction(this.get('page.title'));
},
keepEditing() {
let drop = this.get('drop');
drop.close();
},
discardEdits() {
this.attrs.onCancel();
},
onInsertLink(selection) {
return this.get('onInsertLink')(selection);
},
onPreview() {
return this.get('onPreview')();
},
}
});

View file

@ -0,0 +1,107 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
drop: null,
cancelLabel: "Close",
actionLabel: "Save",
tip: "Short and concise title",
busy: false,
hasExcerpt: Ember.computed('page', function () {
return is.not.undefined(this.get('page.excerpt'));
}),
didRender() {
let self = this;
Mousetrap.bind('esc', function () {
self.send('onCancel');
return false;
});
Mousetrap.bind(['ctrl+s', 'command+s'], function () {
self.send('onAction');
return false;
});
$("#page-title").removeClass("error");
$("#page-excerpt").removeClass("error");
$("#page-title").focus(function() {
$(this).select();
});
$("#page-excerpt").focus(function() {
$(this).select();
});
},
willDestroyElement() {
let drop = this.get('drop');
if (is.not.null(drop)) {
drop.destroy();
}
},
actions: {
onCancel() {
if (this.attrs.isDirty() !== null && this.attrs.isDirty()) {
$(".discard-edits-dialog").css("display", "block");
let drop = new Drop({
target: $("#editor-cancel")[0],
content: $(".cancel-edits-dialog")[0],
classes: 'drop-theme-basic',
position: "bottom right",
openOn: "always",
tetherOptions: {
offset: "5px 0",
targetOffset: "10px 0"
},
remove: false
});
this.set('drop', drop);
return;
}
this.attrs.onCancel();
},
onAction() {
if (this.get('busy')) {
return;
}
if (is.empty(this.get('page.title'))) {
$("#page-title").addClass("error").focus();
return;
}
if (this.get('hasExcerpt') && is.empty(this.get('page.excerpt'))) {
$("#page-excerpt").addClass("error").focus();
return;
}
this.attrs.onAction(this.get('page.title'));
},
keepEditing() {
let drop = this.get('drop');
drop.close();
},
discardEdits() {
this.attrs.onCancel();
}
}
});

View file

@ -9,7 +9,7 @@
//
// https://documize.com
import Component from '@ember/component';
import Ember from 'ember';
export default Component.extend({
export default Ember.Component.extend({
});

View file

@ -0,0 +1,143 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import TooltipMixin from '../../../mixins/tooltip';
export default Ember.Component.extend(TooltipMixin, {
isDirty: false,
pageBody: "",
syntaxOptions: [],
codeSyntax: null,
codeEditor: null,
editorId: Ember.computed('page', function () {
let page = this.get('page');
return `code-editor-${page.id}`;
}),
syntaxId: Ember.computed('page', function () {
let page = this.get('page');
return `code-editor-syntax-${page.id}`;
}),
init() {
this._super(...arguments);
let self = this;
let rawBody = this.get('meta.rawBody');
let cleanBody = rawBody.replace("</pre>", "");
cleanBody = cleanBody.replace('<pre class="code-mirror cm-s-solarized cm-s-dark" data-lang="', "");
let startPos = cleanBody.indexOf('">');
let syntax = {
mode: "htmlmixed",
name: "HTML"
};
if (startPos !== -1) {
syntax = cleanBody.substring(0, startPos);
cleanBody = cleanBody.substring(startPos + 2);
}
this.set('pageBody', cleanBody);
let opts = [];
_.each(_.sortBy(CodeMirror.modeInfo, 'name'), function(item) {
let i = { mode: item.mode, name: item.name };
opts.pushObject(i);
if (item.mode === syntax) {
self.set('codeSyntax', i);
}
});
this.set('syntaxOptions', opts);
// default check
if (is.null(this.get("codeSyntax"))) {
this.set("codeSyntax", opts.findBy("mode", "htmlmixed"));
}
},
didInsertElement() {
var editor = CodeMirror.fromTextArea(document.getElementById(this.get('editorId')), {
theme: "material",
lineNumbers: true,
lineWrapping: true,
indentUnit: 4,
tabSize: 4,
value: "",
dragDrop: false
});
CodeMirror.commands.save = function(/*instance*/){
Mousetrap.trigger('ctrl+s');
};
this.set('codeEditor', editor);
let syntax = this.get("codeSyntax");
if (is.not.undefined(syntax)) {
CodeMirror.autoLoadMode(editor, syntax.mode);
editor.setOption("mode", syntax.mode);
}
},
willDestroyElement() {
let editor = this.get('codeEditor');
if (is.not.null(editor)) {
editor.toTextArea();
editor = null;
this.set('codeEditor', null);
}
this.destroyTooltips();
},
// Wrap code in PRE tag with language identifier for subsequent rendering.
getPRE() {
let codeSyntax = this.get("codeSyntax.mode");
let body = this.get('codeEditor').getDoc().getValue();
return `<pre class="code-mirror cm-s-solarized cm-s-dark" data-lang="${codeSyntax}">${body}</pre>`;
},
actions: {
onSyntaxChange(syntax) {
let editor = this.get('codeEditor');
CodeMirror.autoLoadMode(editor, syntax.mode);
editor.setOption("mode", syntax.mode);
this.set('isDirty', true);
this.set('codeSyntax', syntax);
},
isDirty() {
return this.get('isDirty') || (this.get('codeEditor').getDoc().isClean() === false);
},
onCancel() {
this.attrs.onCancel();
},
onAction(title) {
let page = this.get('page');
let meta = this.get('meta');
meta.set('rawBody', this.getPRE());
page.set('title', title);
page.set('body', meta.get('rawBody'));
this.attrs.onAction(page, meta);
}
}
});

View file

@ -0,0 +1,85 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
codeBody: "",
codeSyntax: "htmlmixed",
didReceiveAttrs() {
this._super(...arguments);
if (this.get('isDestroyed') || this.get('isDestroying')) {
return;
}
let page = this.get('page');
let rawBody = page.get('body');
let cleanBody = rawBody.replace("</pre>", "").replace('<pre class="code-mirror cm-s-solarized cm-s-dark" data-lang="', "");
let startPos = cleanBody.indexOf('">');
if (startPos !== -1) {
this.set('codeSyntax', cleanBody.substring(0, startPos));
this.set('codeBody', cleanBody.substring(startPos + 2));
}
_.each(_.sortBy(CodeMirror.modeInfo, 'name'), (item) => {
let i = { mode: item.mode, name: item.name };
if (item.mode === this.get('codeSyntax')) {
this.set('codeSyntax', i);
}
});
},
didInsertElement() {
this._super(...arguments);
if (this.get('isDestroyed') || this.get('isDestroying')) {
return;
}
let page = this.get('page');
let elem = `page-${page.id}-code`;
var editor = CodeMirror.fromTextArea(document.getElementById(elem), {
theme: "material",
lineNumbers: true,
lineWrapping: true,
indentUnit: 4,
tabSize: 4,
value: "",
dragDrop: false,
readOnly: true
});
this.set('codeEditor', editor);
let syntax = this.get("codeSyntax");
if (is.not.undefined(syntax)) {
CodeMirror.autoLoadMode(editor, syntax.mode);
editor.setOption("mode", syntax.mode);
}
},
willDestroyElement() {
this._super(...arguments);
let editor = this.get('codeEditor');
if (is.not.null(editor)) {
editor.toTextArea();
editor = null;
}
this.set('codeEditor', null);
}
});

View file

@ -0,0 +1,228 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../../mixins/notifier';
import TooltipMixin from '../../../mixins/tooltip';
import SectionMixin from '../../../mixins/section';
export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, {
sectionService: Ember.inject.service('section'),
isDirty: false,
waiting: false,
authenticated: false,
user: {},
workspaces: [],
config: {},
didReceiveAttrs() {
let config = {};
try {
config = JSON.parse(this.get('meta.config'));
} catch (e) {} // eslint-disable-line no-empty
if (is.empty(config)) {
config = {
APIKey: "",
filter: {},
itemCount: 0,
url: "",
userId: 0,
username: "",
workspaceId: 0,
workspaceName: "",
};
}
this.set('config', config);
let self = this;
self.set('waiting', true);
this.get('sectionService').fetch(this.get('page'), "secrets", this.get('config'))
.then(function (response) {
self.set('waiting', false);
self.set('config.APIKey', response.apikey);
self.set('config.url', response.url);
self.set('config.username', response.username);
if (response.apikey.length > 0 && response.url.length > 0 && response.username.length > 0) {
self.send('auth');
}
}, function (reason) { // eslint-disable-line no-unused-vars
self.set('waiting', false);
if (self.get('config.userId') > 0) {
self.send('auth');
}
});
},
willDestroyElement() {
this.destroyTooltips();
},
getWorkspaces() {
let page = this.get('page');
let self = this;
this.set('waiting', true);
this.get('sectionService').fetch(page, "workspace", this.get('config'))
.then(function (response) {
// console.log(response);
let workspaceId = self.get('config.workspaceId');
if (response.length > 0 && workspaceId === 0) {
workspaceId = response[0].Id;
}
self.set("config.workspaceId", workspaceId);
self.set('workspaces', response);
self.selectWorkspace(workspaceId);
Ember.run.schedule('afterRender', function () {
window.scrollTo(0, document.body.scrollHeight);
response.forEach(function (workspace) {
self.addTooltip(document.getElementById("gemini-workspace-" + workspace.Id));
});
});
self.set('waiting', false);
}, function (reason) { // eslint-disable-line no-unused-vars
self.set('workspaces', []);
self.set('waiting', false);
});
},
getItems() {
let page = this.get('page');
let self = this;
this.set('waiting', true);
this.get('sectionService').fetch(page, "items", this.get('config'))
.then(function (response) {
if (self.get('isDestroyed') || self.get('isDestroying')) {
return;
}
self.set('items', response);
self.set('config.itemCount', response.length);
self.set('waiting', false);
}, function (reason) { // eslint-disable-line no-unused-vars
if (self.get('isDestroyed') || self.get('isDestroying')) {
return;
}
self.set('items', []);
self.set('waiting', false);
});
},
selectWorkspace(id) {
let self = this;
let w = this.get('workspaces');
w.forEach(function (w) {
Ember.set(w, 'selected', w.Id === id);
if (w.Id === id) {
self.set("config.filter", w.Filter);
self.set("config.workspaceId", id);
self.set("config.workspaceName", w.Title);
// console.log(self.get('config'));
}
});
this.set('workspaces', w);
this.getItems();
},
actions: {
isDirty() {
return this.get('isDirty');
},
auth() {
// missing data?
if (is.empty(this.get('config.url'))) {
$("#gemini-url").addClass("error").focus();
return;
}
if (is.empty(this.get('config.username'))) {
$("#gemini-username").addClass("error").focus();
return;
}
if (is.empty(this.get('config.APIKey'))) {
$("#gemini-apikey").addClass("error").focus();
return;
}
// knock out spaces
this.set('config.url', this.get('config.url').trim());
this.set('config.username', this.get('config.username').trim());
this.set('config.APIKey', this.get('config.APIKey').trim());
// remove trailing slash in URL
let url = this.get('config.url');
if (url.indexOf("/", url.length - 1) !== -1) {
this.set('config.url', url.substring(0, url.length - 1));
}
let page = this.get('page');
let self = this;
this.set('waiting', true);
this.get('sectionService').fetch(page, "auth", this.get('config'))
.then(function (response) {
self.set('authenticated', true);
self.set('user', response);
self.set('config.userId', response.BaseEntity.id);
self.set('waiting', false);
self.getWorkspaces();
}, function (reason) { // eslint-disable-line no-unused-vars
self.set('authenticated', false);
self.set('user', null);
self.set('config.userId', 0);
self.set('waiting', false);
switch (reason.status) {
case 400:
self.showNotification(`Unable to connect to Gemini URL`);
break;
case 403:
self.showNotification(`Unable to authenticate`);
break;
default:
self.showNotification(`Something went wrong, try again!`);
}
});
},
onWorkspaceChange(id) {
this.set('isDirty', true);
this.selectWorkspace(id);
},
onCancel() {
this.attrs.onCancel();
},
onAction(title) {
let page = this.get('page');
let meta = this.get('meta');
page.set('title', title);
meta.set('rawBody', JSON.stringify(this.get("items")));
meta.set('config', JSON.stringify(this.get('config')));
meta.set('externalSource', true);
this.attrs.onAction(page, meta);
}
}
});

View file

@ -0,0 +1,14 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({});

View file

@ -0,0 +1,263 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../../mixins/notifier';
import TooltipMixin from '../../../mixins/tooltip';
import SectionMixin from '../../../mixins/section';
export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, {
sectionService: Ember.inject.service('section'),
isDirty: false,
busy: false,
authenticated: false,
config: {},
owners: null,
didReceiveAttrs() {
let self = this;
let page = this.get('page');
if (is.undefined(this.get('config.clientId')) || is.undefined(this.get('config.callbackUrl'))) {
self.get('sectionService').fetch(page, "config", {})
.then(function (cfg) {
let config = {};
config = {
clientId: cfg.clientID,
callbackUrl: cfg.authorizationCallbackURL,
owner: null,
owner_name: "",
lists: [],
branchSince: "",
branchLines: "100",
userId: "",
pageId: page.get('id'),
showMilestones: false,
showIssues: false,
showCommits: true,
};
try {
let metaConfig = JSON.parse(self.get('meta.config'));
config.owner = metaConfig.owner;
config.lists = metaConfig.lists;
config.branchSince = metaConfig.branchSince;
config.userId = metaConfig.userId;
config.pageId = metaConfig.pageId;
config.showMilestones = metaConfig.showMilestones;
config.showIssues = metaConfig.showIssues;
config.showCommits = metaConfig.showCommits;
} catch (e) { // eslint-disable-line no-empty
}
if (_.isUndefined(config.showCommits)) {
config.showCommits = true;
}
self.set('config', config);
self.set('config.pageId', page.get('id'));
// On auth callback capture code
let code = window.location.search;
code = code.replace("?mode=edit", "");
if (is.not.undefined(code) && is.not.null(code) && is.not.empty(code) && code !== "") {
let tok = code.replace("&code=", "");
self.get('sectionService').fetch(page, "saveSecret", { "token": tok })
.then(function () {
self.send('authStage2');
}, function (error) { //jshint ignore: line
console.log(error); // eslint-disable-line no-console
self.send('auth');
});
} else {
if (config.userId !== self.get("session.session.authenticated.user.id")) {
console.log("github auth wrong user ID, switching"); // eslint-disable-line no-console
self.set('config.userId', self.get("session.session.authenticated.user.id"));
}
self.get('sectionService').fetch(page, "checkAuth", self.get('config'))
.then(function () {
self.send('authStage2');
}, function (error) {
console.log(error); // eslint-disable-line no-console
self.send('auth'); // require auth if the db token is invalid
});
}
}, function (error) {
console.log(error); // eslint-disable-line no-console
});
}
},
willDestroyElement() {
this.destroyTooltips();
},
getOwnerLists() {
this.set('busy', true);
let owners = this.get('owners');
let thisOwner = this.get('config.owner');
if (is.null(thisOwner) || is.undefined(thisOwner)) {
if (owners.length) {
thisOwner = owners[0];
this.set('config.owner', thisOwner);
}
} else {
this.set('config.owner', owners.findBy('id', thisOwner.id));
}
this.set('owner', thisOwner);
this.getOrgReposLists();
if (is.undefined(this.get('initDateTimePicker'))) {
$.datetimepicker.setLocale('en');
$('#branch-since').datetimepicker();
this.set('initDateTimePicker', "Done");
}
},
getOrgReposLists() {
this.set('busy', true);
let self = this;
let page = this.get('page');
this.get('sectionService').fetch(page, "orgrepos", self.get('config'))
.then(function (lists) {
let savedLists = self.get('config.lists');
if (savedLists === null) {
savedLists = [];
}
if (lists.length > 0) {
let noIncluded = true;
lists.forEach(function (list) {
let included = false;
var saved;
if (is.not.undefined(savedLists)) {
saved = savedLists.findBy("id", list.id);
}
if (is.not.undefined(saved)) {
included = saved.included;
noIncluded = false;
}
list.included = included;
});
if (noIncluded) {
lists[0].included = true; // make the first entry the default
}
}
self.set('config.lists', lists);
self.set('busy', false);
}, function (error) {
self.set('busy', false);
self.set('authenticated', false);
self.showNotification("Unable to fetch repositories");
console.log(error); // eslint-disable-line no-console
});
},
actions: {
isDirty() {
return this.get('isDirty');
},
onListCheckbox(id) { // select one repository only
let lists = this.get('config.lists');
let list = lists.findBy('id', id);
lists.forEach(function (entry) {
Ember.set(entry, 'included', false);
});
if (list !== null) {
Ember.set(list, 'included', true);
}
},
authStage2() {
let self = this;
self.set('config.userId', self.get("session.session.authenticated.user.id"));
self.set('authenticated', true);
self.set('busy', true);
let page = this.get('page');
self.get('sectionService').fetch(page, "owners", self.get('config'))
.then(function (owners) {
self.set('busy', false);
self.set('owners', owners);
self.getOwnerLists();
}, function (error) {
self.set('busy', false);
self.set('authenticated', false);
self.showNotification("Unable to fetch owners");
console.log(error); // eslint-disable-line no-console
});
},
auth() {
let self = this;
self.set('busy', true);
self.set('authenticated', false);
let target = "https://github.com/login/oauth/authorize?client_id=" + self.get('config.clientId') +
"&scope=repo&redirect_uri=" + encodeURIComponent(self.get('config.callbackUrl')) +
"&state=" + encodeURIComponent(window.location.href);
window.location.href = target;
},
onOwnerChange(thisOwner) {
this.set('isDirty', true);
this.set('config.owner', thisOwner);
this.set('config.lists', []);
this.getOwnerLists();
},
onStateChange(thisState) {
this.set('config.state', thisState);
},
onCancel() {
this.attrs.onCancel();
},
onAction(title) {
this.set('busy', true);
let self = this;
let page = this.get('page');
let meta = this.get('meta');
page.set('title', title);
meta.set('rawBody', '');
meta.set('config', JSON.stringify(this.get('config')));
meta.set('externalSource', true);
this.get('sectionService').fetch(page, 'content', this.get('config'))
.then(function (response) {
meta.set('rawBody', JSON.stringify(response));
self.set('busy', false);
self.attrs.onAction(page, meta);
}, function (reason) { // eslint-disable-line no-unused-vars
self.set('busy', false);
self.attrs.onAction(page, meta);
});
}
}
});

View file

@ -0,0 +1,14 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({});

View file

@ -0,0 +1,129 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import TooltipMixin from '../../../mixins/tooltip';
const {
inject: { service }
} = Ember;
export default Ember.Component.extend(TooltipMixin, {
link: service(),
pageBody: "",
pagePreview: "",
editMode: true,
codeSyntax: null,
codeEditor: null,
editorId: Ember.computed('page', function () {
let page = this.get('page');
return `markdown-editor-${page.id}`;
}),
previewId: Ember.computed('page', function () {
let page = this.get('page');
return `markdown-preview-${page.id}`;
}),
init() {
this._super(...arguments);
this.set('pageBody', this.get('meta.rawBody').trim());
},
didInsertElement() {
this.attachEditor();
this.addTooltip(document.getElementById(this.get('tooltipId')));
},
willDestroyElement() {
let editor = this.get('codeEditor');
if (this.get('editMode')) {
editor.toTextArea();
editor = null;
}
this.set('codeEditor', null);
this.destroyTooltips();
},
getBody() {
return this.get('codeEditor').getDoc().getValue().trim();
},
attachEditor() {
var editor = CodeMirror.fromTextArea(document.getElementById(this.get('editorId')), {
theme: "default",
mode: "markdown",
lineNumbers: false,
lineWrapping: true,
indentUnit: 4,
tabSize: 4,
value: "",
dragDrop: false,
extraKeys: {"Enter": "newlineAndIndentContinueMarkdownList"}
});
CodeMirror.commands.save = function(/*instance*/){
Mousetrap.trigger('ctrl+s');
};
this.set('codeEditor', editor);
let syntax = this.get("codeSyntax");
if (is.not.undefined(syntax)) {
CodeMirror.autoLoadMode(editor, "markdown");
editor.setOption("mode", "markdown");
}
},
actions: {
onPreview() {
this.set('editMode', !this.get('editMode'));
Ember.run.schedule('afterRender', () => {
if (this.get('editMode')) {
this.attachEditor();
} else {
this.set('pageBody',this.getBody());
let md = window.markdownit({ linkify: true });
let result = md.render(this.getBody());
this.set('pagePreview', result);
}
});
},
onInsertLink(link) {
let linkMarkdown = this.get('link').buildLink(link);
this.get('codeEditor').getDoc().replaceSelection(linkMarkdown);
return true;
},
isDirty() {
return this.get('codeEditor').getDoc().isClean() === false;
},
onCancel() {
this.attrs.onCancel();
},
onAction(title) {
let page = this.get('page');
let meta = this.get('meta');
page.set('title', title);
meta.set('rawBody', this.getBody());
this.attrs.onAction(page, meta);
}
}
});

View file

@ -0,0 +1,14 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({});

View file

@ -0,0 +1,186 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../../mixins/notifier';
import TooltipMixin from '../../../mixins/tooltip';
import SectionMixin from '../../../mixins/section';
import netUtil from '../../../utils/net';
export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, {
sectionService: Ember.inject.service('section'),
isDirty: false,
waiting: false,
authenticated: false,
config: {},
items: {},
didReceiveAttrs() {
let config = {};
try {
config = JSON.parse(this.get('meta.config'));
} catch (e) {} // eslint-disable-line no-empty
if (is.empty(config)) {
config = {
APIToken: "",
query: "",
max: 10,
group: null,
system: null
};
}
this.set('config', config);
this.send('auth');
},
willDestroyElement() {
this.destroyTooltips();
},
displayError(reason) {
if (netUtil.isAjaxAccessError(reason)) {
this.showNotification(`Unable to authenticate`);
} else {
this.showNotification(`Something went wrong, try again!`);
}
},
actions: {
isDirty() {
return this.get('isDirty');
},
auth() {
let page = this.get('page');
let config = this.get('config');
let self = this;
this.set('waiting', true);
this.get('sectionService').fetch(page, "auth", config)
.then(function (response) {
self.set('authenticated', true);
self.set('items', response);
self.set('config.APIToken', '********'); // reset the api token once it has been sent to the host
self.get('sectionService').fetch(page, "options", config)
.then(function (response) {
self.set('options', response);
self.set('waiting', false);
let options = self.get('options');
let group = {};
if (is.not.null(config.group)) {
group = _.findWhere(options.groups, { id: config.group.id });
} else {
group = options.groups[0];
}
if (is.not.undefined(group)) {
Ember.set(config, 'group', group);
}
}, function (reason) {
self.set('authenticated', false);
self.set('waiting', false);
self.set('config.APIToken', ''); // clear the api token
self.displayError(reason);
console.log("get options call failed"); // eslint-disable-line no-console
});
}, function (reason) {
self.set('authenticated', false);
self.set('waiting', false);
self.set('config.APIToken', ''); // clear the api token
self.displayError(reason);
console.log("auth token invalid"); // eslint-disable-line no-console
});
},
onGroupsChange(group) {
let config = this.get('config');
let page = this.get('page');
let self = this;
this.set('isDirty', true);
this.set('config.group', group);
this.set('waiting', true);
this.get('sectionService').fetch(page, "auth", config)
.then(function (response) {
self.set('waiting', false);
self.set('items', response);
}, function (reason) { //jshint ignore: line
self.set('waiting', false);
self.displayError(reason);
});
},
onSystemsChange(system) {
let config = this.get('config');
let page = this.get('page');
let self = this;
this.set('isDirty', true);
this.set('config.system', system);
this.set('waiting', true);
this.get('sectionService').fetch(page, "auth", config)
.then(function (response) {
self.set('waiting', false);
self.set('items', response);
}, function (reason) { //jshint ignore: line
self.set('waiting', false);
self.displayError(reason);
});
},
onCancel() {
this.attrs.onCancel();
},
onAction(title) {
let self = this;
let page = this.get('page');
let meta = this.get('meta');
page.set('title', title);
meta.set('externalSource', true);
let config = this.get('config');
let max = 10;
if (is.number(parseInt(config.max))) {
max = parseInt(config.max);
}
Ember.set(config, 'max', max);
this.set('waiting', true);
this.get('sectionService').fetch(page, "auth", this.get('config'))
.then(function (response) {
self.set('items', response);
let items = self.get('items');
if (items.events.length > max) {
items.events = items.events.slice(0, max);
}
meta.set('config', JSON.stringify(config));
meta.set('rawBody', JSON.stringify(items));
self.set('waiting', false);
self.attrs.onAction(page, meta);
}, function (reason) { // eslint-disable-line no-unused-vars
self.set('authenticated', false);
self.set('waiting', false);
self.showNotification(`Something went wrong, try again!`);
});
}
}
});

View file

@ -0,0 +1,14 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({});

View file

@ -0,0 +1,73 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
isDirty: false,
pageBody: "",
editorId: Ember.computed('page', function () {
let page = this.get('page');
return `table-editor-${page.id}`;
}),
defaultTable: '<table class="wysiwyg-table" style="width: 100%;"><thead><tr><th><br></th><th><br></th><th><br></th><th><br></th></tr></thead><tbody><tr><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td></tr><tr><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td></tr><tr><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td></tr></tbody></table>',
didReceiveAttrs() {
this.set('pageBody', this.get('meta.rawBody'));
if (is.empty(this.get('pageBody'))) {
this.set('pageBody', this.get('defaultTable'));
}
},
didInsertElement() {
let id = '#' + this.get('editorId');
$(id).froalaEditor({
toolbarButtons: [],
toolbarInline: true,
tableResizerOffset: 10
});
$(id).on('froalaEditor.contentChanged', () => {
this.set('isDirty', true);
});
},
willDestroyElement() {
$('#' + this.get('editorId')).off('froalaEditor.contentChanged');
},
actions: {
isDirty() {
return this.get('isDirty');
},
onCancel() {
this.attrs.onCancel();
},
onAction(title) {
let page = this.get('page');
let meta = this.get('meta');
let body = $('#' + this.get('editorId')).froalaEditor('html.get', true);
page.set('title', title);
if (is.empty(body)) {
body = this.get('defaultTable');
}
meta.set('rawBody', body);
this.attrs.onAction(page, meta);
}
}
});

View file

@ -0,0 +1,14 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({});

View file

@ -0,0 +1,242 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
/*global Trello*/
import Ember from 'ember';
import NotifierMixin from '../../../mixins/notifier';
import TooltipMixin from '../../../mixins/tooltip';
import SectionMixin from '../../../mixins/section';
export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, {
sectionService: Ember.inject.service('section'),
isDirty: false,
busy: false,
authenticated: false,
config: {},
boards: null,
noBoards: false,
appKey: "",
boardStyle: Ember.computed('config.board', function () {
let board = this.get('config.board');
if (is.null(board) || is.undefined(board)) {
return "#4c4c4c";
}
let color = board.prefs.backgroundColor;
return Ember.String.htmlSafe("background-color: " + color);
}),
didReceiveAttrs() {
let page = this.get('page');
let config = {};
let self = this;
try {
config = JSON.parse(this.get('meta.config'));
} catch (e) {} // eslint-disable-line no-empty
if (is.empty(config)) {
config = {
token: "",
user: null,
board: null,
lists: []
};
}
this.set('config', config);
this.get('sectionService').fetch(page, "config", {})
.then(function (s) {
self.set('appKey', s.appKey);
self.set('config.token', s.token); // the user's own token has been stored in the DB
// On auth callback capture user token
let hashToken = window.location.hash;
if (is.not.undefined(hashToken) && is.not.null(hashToken)) {
let token = hashToken.replace("#token=", "");
if (is.not.empty(token)) {
self.set('config.token', token);
}
}
if (self.get('appKey') !== "" && self.get('config.token') !== "") {
self.send('auth');
} else {
Ember.$.getScript("https://api.trello.com/1/client.js?key=" + self.get('appKey'), function () {
Trello.deauthorize();
});
}
}, function (error) {
console.log(error); // eslint-disable-line no-console
});
},
willDestroyElement() {
this.destroyTooltips();
},
getBoardLists() {
this.set('busy', true);
let self = this;
let boards = this.get('boards');
let board = this.get('config.board');
let page = this.get('page');
if (is.null(boards) || is.undefined(boards) || boards.length === 0) {
this.set('noBoards', true);
return;
}
this.set('noBoards', false);
if (is.null(board) || is.undefined(board)) {
if (boards.length) {
board = boards[0];
this.set('config.board', board);
}
} else {
this.set('config.board', boards.findBy('id', board.id));
}
this.get('sectionService').fetch(page, "lists", self.get('config'))
.then(function (lists) {
let savedLists = self.get('config.lists');
if (savedLists === null) {
savedLists = [];
}
lists.forEach(function (list) {
let saved = savedLists.findBy("id", list.id);
let included = true;
if (is.not.undefined(saved)) {
included = saved.included;
}
list.included = included;
});
self.set('config.lists', lists);
self.set('busy', false);
}, function (error) { //jshint ignore: line
self.set('busy', false);
self.set('authenticated', false);
self.showNotification("Unable to fetch board lists");
console.log(error); // eslint-disable-line no-console
});
},
actions: {
isDirty() {
return this.get('isDirty');
},
onListCheckbox(id) {
let lists = this.get('config.lists');
let list = lists.findBy('id', id);
if (list !== null) {
Ember.set(list, 'included', !list.included);
}
},
auth() {
if (this.get('appKey') === "") {
$("#trello-appkey").addClass('error').focus();
this.set('authenticated', false);
return;
}
let self = this;
let page = this.get('page');
self.set('busy', true);
Ember.$.getScript("https://api.trello.com/1/client.js?key=" + this.get('appKey'), function () {
Trello.authorize({
type: "redirect",
interactive: true,
name: "Documize",
scope: {
read: true,
write: false
},
expiration: "never",
persist: true,
success: function () {
self.set('authenticated', true);
self.set('config.token', Trello.token());
self.set('busy', true);
Trello.members.get("me", function (user) {
self.set('config.user', user);
}, function (error) {
console.log(error); // eslint-disable-line no-console
});
self.get('sectionService').fetch(page, "boards", self.get('config'))
.then(function (boards) {
self.set('busy', false);
self.set('boards', boards);
self.getBoardLists();
}, function (error) { //jshint ignore: line
self.set('busy', false);
self.set('authenticated', false);
self.showNotification("Unable to fetch boards");
console.log(error); // eslint-disable-line no-console
});
},
error: function (error) {
self.set('busy', false);
self.set('authenticated', false);
self.showNotification("Unable to authenticate");
console.log(error); // eslint-disable-line no-console
}
});
});
},
onBoardChange(board) {
this.set('isDirty', true);
this.set('config.board', board);
this.set('config.lists', []);
this.getBoardLists();
},
onCancel() {
this.attrs.onCancel();
},
onAction(title) {
this.set('busy', true);
let self = this;
let page = this.get('page');
let meta = this.get('meta');
page.set('title', title);
meta.set('rawBody', '');
meta.set('config', JSON.stringify(this.get('config')));
meta.set('externalSource', true);
this.get('sectionService').fetch(page, "cards", this.get('config'))
.then(function (response) {
meta.set('rawBody', JSON.stringify(response));
self.set('busy', false);
self.attrs.onAction(page, meta);
}, function (reason) { // eslint-disable-line no-unused-vars
self.set('busy', false);
self.attrs.onAction(page, meta);
});
}
}
});

View file

@ -0,0 +1,14 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({});

View file

@ -0,0 +1,134 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
const {
inject: { service }
} = Ember;
export default Ember.Component.extend({
appMeta: service(),
link: service(),
pageBody: "",
editorId: Ember.computed('page', function () {
let page = this.get('page');
return `wysiwyg-editor-${page.id}`;
}),
didReceiveAttrs() {
this.set('pageBody', this.get('meta.rawBody'));
},
didInsertElement() {
let options = {
selector: "#" + this.get('editorId'),
relative_urls: false,
cache_suffix: "?v=443",
browser_spellcheck: false,
gecko_spellcheck: false,
theme: "modern",
skin: 'documize',
statusbar: false,
inline: true,
entity_encoding: "raw",
paste_data_images: true,
image_advtab: true,
image_caption: true,
media_live_embeds: true,
fontsize_formats: "8px 10px 12px 14px 17px 18px 24px 36px 40px 50px 60px",
formats: {
bold: {
inline: 'b'
},
italic: {
inline: 'i'
}
},
codesample_languages: [
{text: 'HTML/XML', value: 'markup'},
{text: 'JavaScript', value: 'javascript'},
{text: 'CSS', value: 'css'},
{text: 'PHP', value: 'php'},
{text: 'Ruby', value: 'ruby'},
{text: 'Python', value: 'python'},
{text: 'Java', value: 'java'},
{text: 'C', value: 'c'},
{text: 'C#', value: 'csharp'},
{text: 'C++', value: 'cpp'}],
extended_valid_elements: "b,i,b/strong,i/em",
plugins: [
'advlist autolink lists link image charmap print preview hr anchor pagebreak',
'searchreplace wordcount visualblocks visualchars code codesample fullscreen',
'insertdatetime media nonbreaking save table directionality',
'template paste textcolor colorpicker textpattern imagetools'
],
menu: {},
menubar: false,
toolbar1: "formatselect fontsizeselect | bold italic underline strikethrough superscript subscript | forecolor backcolor link unlink",
toolbar2: "outdent indent bullist numlist | alignleft aligncenter alignright alignjustify | table image media codesample",
save_onsavecallback: function () {
Mousetrap.trigger('ctrl+s');
}
};
if (typeof tinymce === 'undefined') {
$.getScript("/tinymce/tinymce.min.js?v=443", function () {
window.tinymce.dom.Event.domLoaded = true;
tinymce.baseURL = "//" + window.location.host + "/tinymce";
tinymce.suffix = ".min";
tinymce.init(options);
});
} else {
tinymce.init(options);
}
},
willDestroyElement() {
tinymce.EditorManager.execCommand('mceRemoveEditor', true, this.get('editorId'));
},
actions: {
onInsertLink(link) {
let editor = tinymce.EditorManager.get(this.get('editorId'));
let userSelection = editor.selection.getContent();
if (is.not.empty(userSelection)) {
Ember.set(link, 'title', userSelection);
}
let linkHTML = this.get('link').buildLink(link);
editor.insertContent(linkHTML);
return true;
},
isDirty() {
let editor = tinymce.EditorManager.get(this.get('editorId'));
return is.not.undefined(tinymce) && is.not.undefined(editor) && editor.isDirty();
},
onCancel() {
this.attrs.onCancel();
},
onAction(title) {
let page = this.get('page');
let meta = this.get('meta');
let editor = tinymce.EditorManager.get(this.get('editorId'));
page.set('title', title);
meta.set('rawBody', editor.getContent());
this.attrs.onAction(page, meta);
}
}
});

View file

@ -0,0 +1,14 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({});

View file

@ -9,11 +9,11 @@
//
// https://documize.com
import { reads } from '@ember/object/computed';
import Component from '@ember/component';
import Ember from 'ember';
export default Component.extend({
export default Ember.Component.extend({
cssClass: "",
content: [],
prompt: null,
optionValuePath: 'id',
optionLabelPath: 'name',
@ -22,7 +22,7 @@ export default Component.extend({
// shadow the passed-in `selection` to avoid
// leaking changes to it via a 2-way binding
_selection: reads('selection'),
_selection: Ember.computed.reads('selection'),
actions: {
change() {

View file

@ -0,0 +1,20 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import TooltipMixin from '../../mixins/tooltip';
export default Ember.Component.extend(TooltipMixin, {
didRender() {
let refId = this.get('refId');
this.addTooltip(document.getElementById(`avatar-${refId}`));
},
});

View file

@ -9,9 +9,9 @@
//
// https://documize.com
import Component from '@ember/component';
import Ember from 'ember';
export default Component.extend({
export default Ember.Component.extend({
tagName: 'span',
actions: {

View file

@ -0,0 +1,28 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'span',
value: '',
onClick: null,
actions: {
onCheck() {
if (this.get('onClick') !== null) {
this.attrs.onClick(this.get('value'));
} else {
this.set('selected', !this.get('selected'));
}
}
}
});

View file

@ -0,0 +1,15 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
});

View file

@ -0,0 +1,32 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Component.extend({
myWidth: Ember.computed('tabs', function() {
let count = this.get('tabs.length');
let width = 95 / count;
return Ember.String.htmlSafe("width: " + `${width}%;`);
}),
actions: {
onTabSelect(tab) {
this.get('tabs').forEach(t => {
Ember.set(t, 'selected', false);
});
Ember.set(tab, 'selected', true);
this.attrs.onTabSelect(this.get('tabs'));
}
}
});

View file

@ -0,0 +1,52 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import miscUtil from '../utils/misc';
export default Ember.Component.extend({
notifications: [],
didInsertElement() {
this.eventBus.subscribe('notifyUser', this, 'showNotification');
},
willDestroyElement() {
this.eventBus.unsubscribe('notifyUser');
},
showNotification(msg) {
let self = this;
let notifications = this.get('notifications');
notifications.pushObject(msg);
this.set('notifications', notifications);
let elem = this.$(".user-notification")[0];
Ember.run(() => {
self.$(elem).show();
// FIXME: need a more robust solution
miscUtil.interval(function() {
let notifications = self.get('notifications');
if (notifications.length > 0) {
notifications.removeAt(0);
self.set('notifications', notifications);
}
if (notifications.length === 0) {
self.$(elem).hide();
}
}, 2500, self.get('notifications').length);
});
},
});

View file

@ -0,0 +1,84 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
import AuthProvider from '../mixins/auth';
const {
computed,
isEmpty,
isEqual,
isPresent
} = Ember;
export default Ember.Component.extend(AuthProvider, {
password: { password: "", confirmation: "" },
hasFirstnameError: computed.empty('model.firstname'),
hasLastnameError: computed.empty('model.lastname'),
hasEmailError: computed.empty('model.email'),
hasPasswordError: computed('passwordError', 'password.password', {
get() {
if (isPresent(this.get('passwordError'))) {
return `error`;
}
if (isEmpty(this.get('password.password'))) {
return null;
}
}
}),
hasConfirmPasswordError: computed('confirmPasswordError', {
get() {
if (isPresent(this.get("confirmPasswordError"))) {
return `error`;
}
return;
}
}),
actions: {
save() {
let password = this.get('password.password');
let confirmation = this.get('password.confirmation');
if (isEmpty(this.get('model.firstname'))) {
return $("#firstname").focus();
}
if (isEmpty(this.get('model.lastname'))) {
return $("#lastname").focus();
}
if (isEmpty(this.get('model.email'))) {
return $("#email").focus();
}
if (isPresent(password) && isEmpty(confirmation)) {
Ember.set(this, 'confirmPasswordError', 'error');
return $("#confirmPassword").focus();
}
if (isEmpty(password) && isPresent(confirmation)) {
Ember.set(this, 'passwordError', 'error');
return $("#password").focus();
}
if (!isEqual(password, confirmation)) {
Ember.set(this, 'passwordError', 'error');
return $("#password").focus();
}
let passwords = this.get('password');
this.get('save')(passwords).finally(() => {
Ember.set(this, 'password.password', '');
Ember.set(this, 'password.confirmation', '');
});
}
}
});

View file

@ -0,0 +1,54 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
// Copyright (c) 2015 Documize Inc.
import Ember from 'ember';
import NotifierMixin from '../mixins/notifier';
export default Ember.Component.extend(NotifierMixin, {
drop1: null,
didInsertElement() {
this._super(...arguments);
new Tooltip({
target: document.getElementById("sample-1")
});
new Tooltip({
target: document.getElementById("sample-2")
});
new Tooltip({
target: document.getElementById("sample-3")
});
new Tooltip({
target: document.getElementById("sample-4")
});
let drop1 = new Drop({
target: document.getElementById('sample-dropdown-1'),
content: document.getElementById('sample-dropdown-content-1'),
classes: 'drop-theme-basic',
position: 'bottom middle',
openOn: 'click'
});
this.set('drop1', drop1);
},
actions: {
dropClose() {
this.get('drop1').close();
},
addFolder() {
return true;
}
}
});

View file

@ -9,8 +9,7 @@
//
// https://documize.com
import { helper } from '@ember/component/helper';
import { htmlSafe } from '@ember/string';
import Ember from 'ember';
export function documentFileIcon(params) {
let fileExtension = params[0].toLowerCase();
@ -107,7 +106,7 @@ export function documentFileIcon(params) {
case "xslt":
}
return new htmlSafe(html);
return new Ember.String.htmlSafe(html);
}
export default helper(documentFileIcon);
export default Ember.Helper.helper(documentFileIcon);

Some files were not shown because too many files have changed in this diff Show more