mirror of
https://github.com/documize/community.git
synced 2025-08-02 20:15:26 +02:00
moved emberjs to gui folder
This commit is contained in:
parent
6a18d18f91
commit
dc49dbbeff
999 changed files with 677 additions and 651 deletions
4
gui/.bowerrc
Normal file
4
gui/.bowerrc
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"directory": "bower_components",
|
||||
"analytics": false
|
||||
}
|
20
gui/.editorconfig
Normal file
20
gui/.editorconfig
Normal 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
|
3
gui/.ember-cli
Normal file
3
gui/.ember-cli
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"disableAnalytics": true
|
||||
}
|
6
gui/.eslintignore
Normal file
6
gui/.eslintignore
Normal file
|
@ -0,0 +1,6 @@
|
|||
public/tinymce/**
|
||||
public/tinymce/
|
||||
public/tinymce
|
||||
public/codemirror/**
|
||||
public/codemirror/
|
||||
public/codemirror
|
36
gui/.eslintrc.js
Normal file
36
gui/.eslintrc.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
parserOptions: {
|
||||
ecmaVersion: 2017,
|
||||
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
gui/.gitignore
vendored
Normal file
18
gui/.gitignore
vendored
Normal 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
|
21
gui/.travis.yml
Normal file
21
gui/.travis.yml
Normal file
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
language: node_js
|
||||
node_js:
|
||||
- "6"
|
||||
|
||||
sudo: false
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.npm
|
||||
|
||||
before_install:
|
||||
- npm config set spin false
|
||||
- npm install -g phantomjs-prebuilt
|
||||
- phantomjs --version
|
||||
|
||||
install:
|
||||
- npm install
|
||||
|
||||
script:
|
||||
- npm test
|
3
gui/.watchmanconfig
Normal file
3
gui/.watchmanconfig
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"ignore_dirs": ["tmp", "dist", "dist-prod"]
|
||||
}
|
53
gui/README.md
Normal file
53
gui/README.md
Normal 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/)
|
||||
|
0
gui/app/adapters/.gitkeep
Normal file
0
gui/app/adapters/.gitkeep
Normal file
34
gui/app/app.js
Normal file
34
gui/app/app.js
Normal 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';
|
||||
import Resolver from './resolver';
|
||||
import loadInitializers from 'ember-load-initializers';
|
||||
import config from './config/environment';
|
||||
|
||||
let App;
|
||||
|
||||
// Ember.MODEL_FACTORY_INJECTIONS = true;
|
||||
|
||||
// Ember.RSVP.on('error', function(error) {
|
||||
// console.log("App:");
|
||||
// console.log(error);
|
||||
// });
|
||||
|
||||
App = Ember.Application.extend({
|
||||
modulePrefix: config.modulePrefix,
|
||||
podModulePrefix: config.podModulePrefix,
|
||||
Resolver
|
||||
});
|
||||
|
||||
loadInitializers(App, config.modulePrefix);
|
||||
|
||||
export default App;
|
26
gui/app/authenticators/anonymous.js
Normal file
26
gui/app/authenticators/anonymous.js
Normal 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);
|
||||
}
|
||||
});
|
64
gui/app/authenticators/documize.js
Normal file
64
gui/app/authenticators/documize.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
// 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 encodingUtil from '../utils/encoding';
|
||||
import netUtil from '../utils/net';
|
||||
|
||||
const {
|
||||
isPresent,
|
||||
RSVP: { resolve, reject },
|
||||
inject: { service }
|
||||
} = Ember;
|
||||
|
||||
export default Base.extend({
|
||||
ajax: service(),
|
||||
appMeta: service(),
|
||||
localStorage: service(),
|
||||
|
||||
restore(data) {
|
||||
// TODO: verify authentication data
|
||||
if (data) {
|
||||
return resolve(data);
|
||||
}
|
||||
|
||||
return reject();
|
||||
},
|
||||
|
||||
authenticate(credentials) {
|
||||
let domain = netUtil.getSubdomain();
|
||||
let encoded;
|
||||
|
||||
if (typeof credentials === 'object') {
|
||||
let { password, email } = credentials;
|
||||
|
||||
if (!isPresent(password) || !isPresent(email)) {
|
||||
return Ember.RSVP.reject("invalid");
|
||||
}
|
||||
|
||||
encoded = encodingUtil.Base64.encode(`${domain}:${email}:${password}`);
|
||||
} else if (typeof credentials === 'string') {
|
||||
encoded = credentials;
|
||||
} else {
|
||||
return Ember.RSVP.reject("invalid");
|
||||
}
|
||||
|
||||
let headers = { 'Authorization': 'Basic ' + encoded };
|
||||
|
||||
return this.get('ajax').post('public/authenticate', { headers });
|
||||
},
|
||||
|
||||
invalidate() {
|
||||
this.get('localStorage').clearAll();
|
||||
return resolve();
|
||||
}
|
||||
});
|
54
gui/app/authenticators/keycloak.js
Normal file
54
gui/app/authenticators/keycloak.js
Normal 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();
|
||||
}
|
||||
});
|
15
gui/app/components/back-to-space.js
Normal file
15
gui/app/components/back-to-space.js
Normal 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({
|
||||
});
|
156
gui/app/components/customize/auth-settings.js
Normal file
156
gui/app/components/customize/auth-settings.js
Normal 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');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
59
gui/app/components/customize/general-settings.js
Normal file
59
gui/app/components/customize/general-settings.js
Normal 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,
|
||||
computed,
|
||||
set
|
||||
} = Ember;
|
||||
|
||||
export default Ember.Component.extend({
|
||||
titleEmpty: computed.empty('model.general.title'),
|
||||
messageEmpty: computed.empty('model.general.message'),
|
||||
conversionEndpointEmpty: computed.empty('model.general.conversionEndpoint'),
|
||||
hasTitleInputError: computed.and('titleEmpty', 'titleError'),
|
||||
hasMessageInputError: computed.and('messageEmpty', 'messageError'),
|
||||
hasConversionEndpointInputError: computed.and('conversionEndpointEmpty', 'conversionEndpointError'),
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
if (isEmpty(this.get('model.general.conversionEndpoint'))) {
|
||||
set(this, 'conversionEndpointError', true);
|
||||
return $("#conversionEndpoint").focus();
|
||||
}
|
||||
|
||||
let e = this.get('model.general.conversionEndpoint');
|
||||
if (is.endWith(e, '/')) {
|
||||
this.set('model.general.conversionEndpoint', e.substring(0, e.length-1));
|
||||
}
|
||||
|
||||
this.model.general.set('allowAnonymousAccess', Ember.$("#allowAnonymousAccess").prop('checked'));
|
||||
|
||||
this.get('save')().then(() => {
|
||||
set(this, 'titleError', false);
|
||||
set(this, 'messageError', false);
|
||||
set(this, 'conversionEndpointError', false);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
58
gui/app/components/customize/global-settings.js
Normal file
58
gui/app/components/customize/global-settings.js
Normal 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();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
202
gui/app/components/customize/user-admin.js
Normal file
202
gui/app/components/customize/user-admin.js
Normal 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;
|
||||
}
|
||||
}
|
||||
});
|
57
gui/app/components/customize/user-settings.js
Normal file
57
gui/app/components/customize/user-settings.js
Normal 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();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
53
gui/app/components/document/block-editor.js
Normal file
53
gui/app/components/document/block-editor.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
// 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({
|
||||
store: Ember.inject.service(),
|
||||
|
||||
didReceiveAttrs() {
|
||||
let p = this.get('store').createRecord('page');
|
||||
let m = this.get('store').createRecord('pageMeta');
|
||||
|
||||
p.set('id', this.get('block.id'));
|
||||
p.set('orgId', this.get('block.orgId'));
|
||||
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'));
|
||||
p.set('body', this.get('block.body'));
|
||||
p.set('rawBody', this.get('block.rawBody'));
|
||||
p.set('excerpt', this.get('block.excerpt'));
|
||||
|
||||
m.set('pageId', this.get('block.id'));
|
||||
m.set('orgId', this.get('block.orgId'));
|
||||
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'));
|
||||
|
||||
this.set('page', p);
|
||||
this.set('meta', m);
|
||||
|
||||
this.set('editorType', 'section/' + this.get('block.contentType') + '/type-editor');
|
||||
},
|
||||
|
||||
actions: {
|
||||
onCancel() {
|
||||
this.attrs.onCancel();
|
||||
},
|
||||
|
||||
onAction(page, meta) {
|
||||
this.attrs.onAction(page, meta);
|
||||
}
|
||||
}
|
||||
});
|
137
gui/app/components/document/content-linker.js
Normal file
137
gui/app/components/document/content-linker.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
28
gui/app/components/document/document-editor.js
Normal file
28
gui/app/components/document/document-editor.js
Normal 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({
|
||||
didReceiveAttrs() {
|
||||
this.set('editorType', 'section/' + this.get('page.contentType') + '/type-editor');
|
||||
},
|
||||
|
||||
actions: {
|
||||
onCancel() {
|
||||
this.attrs.onCancel();
|
||||
},
|
||||
|
||||
onAction(page, meta) {
|
||||
this.attrs.onAction(page, meta);
|
||||
}
|
||||
}
|
||||
});
|
66
gui/app/components/document/document-heading.js
Normal file
66
gui/app/components/document/document-heading.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
49
gui/app/components/document/document-history.js
Normal file
49
gui/app/components/document/document-history.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
92
gui/app/components/document/document-page.js
Normal file
92
gui/app/components/document/document-page.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
77
gui/app/components/document/document-tab.js
Normal file
77
gui/app/components/document/document-tab.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
316
gui/app/components/document/document-view.js
Normal file
316
gui/app/components/document/document-view.js
Normal 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;
|
||||
}
|
||||
}
|
||||
});
|
194
gui/app/components/document/page-heading.js
Normal file
194
gui/app/components/document/page-heading.js
Normal 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;
|
||||
}
|
||||
}
|
||||
});
|
24
gui/app/components/document/sidebar-view-activity.js
Normal file
24
gui/app/components/document/sidebar-view-activity.js
Normal 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);
|
||||
});
|
||||
}
|
||||
});
|
147
gui/app/components/document/sidebar-view-attachments.js
Normal file
147
gui/app/components/document/sidebar-view-attachments.js
Normal 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;
|
||||
}
|
||||
}
|
||||
});
|
24
gui/app/components/document/sidebar-view-index-entry.js
Normal file
24
gui/app/components/document/sidebar-view-index-entry.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
170
gui/app/components/document/sidebar-view-index.js
Normal file
170
gui/app/components/document/sidebar-view-index.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
148
gui/app/components/document/sidebar-zone.js
Normal file
148
gui/app/components/document/sidebar-zone.js
Normal 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;
|
||||
}
|
||||
}
|
||||
});
|
200
gui/app/components/document/tab-heading.js
Normal file
200
gui/app/components/document/tab-heading.js
Normal 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;
|
||||
}
|
||||
}
|
||||
});
|
109
gui/app/components/document/tag-editor.js
Normal file
109
gui/app/components/document/tag-editor.js
Normal 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);
|
||||
},
|
||||
}
|
||||
});
|
71
gui/app/components/documize-setup.js
Normal file
71
gui/app/components/documize-setup.js
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
130
gui/app/components/dropdown-dialog.js
Normal file
130
gui/app/components/dropdown-dialog.js
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
71
gui/app/components/dropdown-menu.js
Normal file
71
gui/app/components/dropdown-menu.js
Normal 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();
|
||||
}
|
||||
}
|
||||
});
|
18
gui/app/components/focus-input.js
Normal file
18
gui/app/components/focus-input.js
Normal 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')
|
||||
});
|
18
gui/app/components/focus-textarea.js
Normal file
18
gui/app/components/focus-textarea.js
Normal 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')
|
||||
});
|
39
gui/app/components/folder/document-tags.js
Normal file
39
gui/app/components/folder/document-tags.js
Normal 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({
|
||||
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);
|
||||
},
|
||||
|
||||
actions: {
|
||||
filterByTag(tag) {
|
||||
this.get('filterByTag')(tag);
|
||||
}
|
||||
}
|
||||
});
|
109
gui/app/components/folder/documents-list.js
Normal file
109
gui/app/components/folder/documents-list.js
Normal 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 });
|
||||
}
|
||||
}
|
||||
});
|
60
gui/app/components/folder/folder-heading.js
Normal file
60
gui/app/components/folder/folder-heading.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
91
gui/app/components/folder/folder-toolbar.js
Normal file
91
gui/app/components/folder/folder-toolbar.js
Normal 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;
|
||||
}
|
||||
}
|
||||
});
|
73
gui/app/components/folder/sidebar-folders-list.js
Normal file
73
gui/app/components/folder/sidebar-folders-list.js
Normal 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;
|
||||
}
|
||||
}
|
||||
});
|
135
gui/app/components/folder/sidebar-permissions.js
Normal file
135
gui/app/components/folder/sidebar-permissions.js
Normal 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');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
74
gui/app/components/folder/sidebar-share.js
Normal file
74
gui/app/components/folder/sidebar-share.js
Normal 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');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
101
gui/app/components/folder/sidebar-zone.js
Normal file
101
gui/app/components/folder/sidebar-zone.js
Normal 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;
|
||||
},
|
||||
}
|
||||
});
|
154
gui/app/components/folder/start-document.js
Normal file
154
gui/app/components/folder/start-document.js
Normal 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,.md,.markdown,.htm,.html",
|
||||
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);
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
41
gui/app/components/forgot-password.js
Normal file
41
gui/app/components/forgot-password.js
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
15
gui/app/components/layout/sidebar-intro.js
Normal file
15
gui/app/components/layout/sidebar-intro.js
Normal 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({
|
||||
});
|
27
gui/app/components/layout/zone-content.js
Normal file
27
gui/app/components/layout/zone-content.js
Normal 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 !!`);
|
||||
}
|
||||
}
|
||||
});
|
27
gui/app/components/layout/zone-document.js
Normal file
27
gui/app/components/layout/zone-document.js
Normal 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 !!`);
|
||||
}
|
||||
}
|
||||
});
|
163
gui/app/components/layout/zone-navigation.js
Normal file
163
gui/app/components/layout/zone-navigation.js
Normal 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');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
15
gui/app/components/layout/zone-sidebar.js
Normal file
15
gui/app/components/layout/zone-sidebar.js
Normal 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({
|
||||
});
|
127
gui/app/components/onboard/share-folder.js
Normal file
127
gui/app/components/onboard/share-folder.js
Normal 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 = "/";
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
59
gui/app/components/password-reset.js
Normal file
59
gui/app/components/password-reset.js
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
54
gui/app/components/search/search-results.js
Normal file
54
gui/app/components/search/search-results.js
Normal 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);
|
||||
}
|
||||
});
|
34
gui/app/components/search/tag-list.js
Normal file
34
gui/app/components/search/tag-list.js
Normal 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);
|
||||
}
|
||||
});
|
39
gui/app/components/section/airtable/type-editor.js
Normal file
39
gui/app/components/section/airtable/type-editor.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
14
gui/app/components/section/airtable/type-renderer.js
Normal file
14
gui/app/components/section/airtable/type-renderer.js
Normal 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({});
|
143
gui/app/components/section/base-editor-inline.js
Normal file
143
gui/app/components/section/base-editor-inline.js
Normal 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')();
|
||||
},
|
||||
}
|
||||
});
|
107
gui/app/components/section/base-editor.js
Normal file
107
gui/app/components/section/base-editor.js
Normal 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();
|
||||
}
|
||||
}
|
||||
});
|
15
gui/app/components/section/base-renderer.js
Normal file
15
gui/app/components/section/base-renderer.js
Normal 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({
|
||||
});
|
143
gui/app/components/section/code/type-editor.js
Normal file
143
gui/app/components/section/code/type-editor.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
85
gui/app/components/section/code/type-renderer.js
Normal file
85
gui/app/components/section/code/type-renderer.js
Normal 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);
|
||||
}
|
||||
});
|
228
gui/app/components/section/gemini/type-editor.js
Normal file
228
gui/app/components/section/gemini/type-editor.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
14
gui/app/components/section/gemini/type-renderer.js
Normal file
14
gui/app/components/section/gemini/type-renderer.js
Normal 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({});
|
263
gui/app/components/section/github/type-editor.js
Normal file
263
gui/app/components/section/github/type-editor.js
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
14
gui/app/components/section/github/type-renderer.js
Normal file
14
gui/app/components/section/github/type-renderer.js
Normal 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({});
|
129
gui/app/components/section/markdown/type-editor.js
Normal file
129
gui/app/components/section/markdown/type-editor.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
14
gui/app/components/section/markdown/type-renderer.js
Normal file
14
gui/app/components/section/markdown/type-renderer.js
Normal 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({});
|
186
gui/app/components/section/papertrail/type-editor.js
Normal file
186
gui/app/components/section/papertrail/type-editor.js
Normal 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!`);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
14
gui/app/components/section/papertrail/type-renderer.js
Normal file
14
gui/app/components/section/papertrail/type-renderer.js
Normal 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({});
|
73
gui/app/components/section/table/type-editor.js
Normal file
73
gui/app/components/section/table/type-editor.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
14
gui/app/components/section/table/type-renderer.js
Normal file
14
gui/app/components/section/table/type-renderer.js
Normal 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({});
|
242
gui/app/components/section/trello/type-editor.js
Normal file
242
gui/app/components/section/trello/type-editor.js
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
14
gui/app/components/section/trello/type-renderer.js
Normal file
14
gui/app/components/section/trello/type-renderer.js
Normal 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({});
|
134
gui/app/components/section/wysiwyg/type-editor.js
Normal file
134
gui/app/components/section/wysiwyg/type-editor.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
14
gui/app/components/section/wysiwyg/type-renderer.js
Normal file
14
gui/app/components/section/wysiwyg/type-renderer.js
Normal 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({});
|
47
gui/app/components/ui-select.js
Normal file
47
gui/app/components/ui-select.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
// 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({
|
||||
cssClass: "",
|
||||
content: [],
|
||||
prompt: null,
|
||||
optionValuePath: 'id',
|
||||
optionLabelPath: 'name',
|
||||
action() {}, // action to fire on change
|
||||
// action: Ember.K, // action to fire on change
|
||||
|
||||
// shadow the passed-in `selection` to avoid
|
||||
// leaking changes to it via a 2-way binding
|
||||
_selection: Ember.computed.reads('selection'),
|
||||
|
||||
actions: {
|
||||
change() {
|
||||
const selectEl = this.$('select')[0];
|
||||
const selectedIndex = selectEl.selectedIndex;
|
||||
const content = this.get('content');
|
||||
|
||||
// decrement index by 1 if we have a prompt
|
||||
const hasPrompt = !!this.get('prompt');
|
||||
const contentIndex = hasPrompt ? selectedIndex - 1 : selectedIndex;
|
||||
|
||||
const selection = content[contentIndex];
|
||||
|
||||
// set the local, shadowed selection to avoid leaking
|
||||
// changes to `selection` out via 2-way binding
|
||||
this.set('_selection', selection);
|
||||
|
||||
const changeCallback = this.get('action');
|
||||
changeCallback(selection);
|
||||
}
|
||||
}
|
||||
});
|
20
gui/app/components/ui/ui-avatar.js
Normal file
20
gui/app/components/ui/ui-avatar.js
Normal 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}`));
|
||||
},
|
||||
});
|
22
gui/app/components/ui/ui-checkbox.js
Normal file
22
gui/app/components/ui/ui-checkbox.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
// 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',
|
||||
|
||||
actions: {
|
||||
onCheck() {
|
||||
this.set('selected', !this.get('selected'));
|
||||
}
|
||||
}
|
||||
});
|
28
gui/app/components/ui/ui-radio.js
Normal file
28
gui/app/components/ui/ui-radio.js
Normal 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'));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
15
gui/app/components/ui/ui-selection.js
Normal file
15
gui/app/components/ui/ui-selection.js
Normal 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({
|
||||
});
|
32
gui/app/components/ui/ui-tab.js
Normal file
32
gui/app/components/ui/ui-tab.js
Normal 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'));
|
||||
}
|
||||
}
|
||||
});
|
52
gui/app/components/user-notification.js
Normal file
52
gui/app/components/user-notification.js
Normal 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);
|
||||
});
|
||||
},
|
||||
});
|
84
gui/app/components/user-profile.js
Normal file
84
gui/app/components/user-profile.js
Normal 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', '');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
54
gui/app/components/widget-sample.js
Normal file
54
gui/app/components/widget-sample.js
Normal 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;
|
||||
}
|
||||
}
|
||||
});
|
0
gui/app/controllers/.gitkeep
Normal file
0
gui/app/controllers/.gitkeep
Normal file
112
gui/app/helpers/document/file-icon.js
Normal file
112
gui/app/helpers/document/file-icon.js
Normal file
|
@ -0,0 +1,112 @@
|
|||
// 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 function documentFileIcon(params) {
|
||||
let fileExtension = params[0].toLowerCase();
|
||||
let html = "unknown.png";
|
||||
|
||||
switch (fileExtension) {
|
||||
case "7z":
|
||||
case "7zip":
|
||||
case "zipx":
|
||||
case "zip":
|
||||
case "war":
|
||||
case "rar":
|
||||
case "tar":
|
||||
case "gzip":
|
||||
html = "zip.png";
|
||||
break;
|
||||
case "avi":
|
||||
case "mov":
|
||||
case "mp4":
|
||||
html = "avi.png";
|
||||
break;
|
||||
|
||||
case "html":
|
||||
html = "html.png";
|
||||
break;
|
||||
case "css":
|
||||
html = "css.png";
|
||||
break;
|
||||
|
||||
case "bat":
|
||||
case "sh":
|
||||
case "ps":
|
||||
case "ps1":
|
||||
case "cs":
|
||||
case "vb":
|
||||
case "php":
|
||||
case "java":
|
||||
case "go":
|
||||
case "js":
|
||||
case "rb":
|
||||
case "py":
|
||||
case "json":
|
||||
case "config":
|
||||
case "xml":
|
||||
html = "code.png";
|
||||
break;
|
||||
case "bin":
|
||||
case "exe":
|
||||
case "dll":
|
||||
html = "bin.png";
|
||||
break;
|
||||
case "bmp":
|
||||
case "jpg":
|
||||
case "jpeg":
|
||||
case "gif":
|
||||
case "tiff":
|
||||
case "svg":
|
||||
case "png":
|
||||
case "psd":
|
||||
case "ai":
|
||||
case "sketch":
|
||||
html = "image.png";
|
||||
break;
|
||||
case "xls":
|
||||
case "xlsx":
|
||||
case "csv":
|
||||
html = "xls.png";
|
||||
break;
|
||||
case "log":
|
||||
case "txt":
|
||||
case "md":
|
||||
case "markdown":
|
||||
html = "txt.png";
|
||||
break;
|
||||
case "mp3":
|
||||
case "wav":
|
||||
html = "mp3.png";
|
||||
break;
|
||||
case "pdf":
|
||||
html = "pdf.png";
|
||||
break;
|
||||
case "ppt":
|
||||
case "pptx":
|
||||
html = "ppt.png";
|
||||
break;
|
||||
case "vsd":
|
||||
case "vsdx":
|
||||
html = "vsd.png";
|
||||
break;
|
||||
case "doc":
|
||||
case "docx":
|
||||
html = "doc.png";
|
||||
break;
|
||||
case "xslt":
|
||||
}
|
||||
|
||||
return new Ember.String.htmlSafe(html);
|
||||
}
|
||||
|
||||
export default Ember.Helper.helper(documentFileIcon);
|
19
gui/app/helpers/formatted-date.js
Normal file
19
gui/app/helpers/formatted-date.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
// 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 dateUtil from '../utils/date';
|
||||
|
||||
export function formattedDate(params) {
|
||||
return dateUtil.toIsoDate(params[0], params[1]);
|
||||
}
|
||||
|
||||
export default Ember.Helper.helper(formattedDate);
|
19
gui/app/helpers/generate-id.js
Normal file
19
gui/app/helpers/generate-id.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
// 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';
|
||||
|
||||
// Usage: {{generate-id 'admin-' 123}}
|
||||
export default Ember.Helper.helper(function(params) {
|
||||
let prefix = params[0];
|
||||
let id = params[1];
|
||||
return prefix + "-" + id;
|
||||
});
|
17
gui/app/helpers/is-equal.js
Normal file
17
gui/app/helpers/is-equal.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
// 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';
|
||||
|
||||
// Usage: {{is-equal item selection}}
|
||||
export default Ember.Helper.helper(function([leftSide, rightSide]) {
|
||||
return leftSide === rightSide;
|
||||
});
|
17
gui/app/helpers/is-not.js
Normal file
17
gui/app/helpers/is-not.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
// 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';
|
||||
|
||||
// Usage: {{is-not selection}}
|
||||
export default Ember.Helper.helper(function([value]) {
|
||||
return !value;
|
||||
});
|
16
gui/app/helpers/read-path.js
Normal file
16
gui/app/helpers/read-path.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
// 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.Helper.helper(function([object, path]) {
|
||||
return Ember.get(object, path);
|
||||
});
|
26
gui/app/helpers/time-ago.js
Normal file
26
gui/app/helpers/time-ago.js
Normal 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 dateUtil from '../utils/date';
|
||||
|
||||
// {{time-ago createdAt}}
|
||||
export function timeAgo(params) {
|
||||
let d = dateUtil.timeAgo(params[0]);
|
||||
|
||||
if (d === 'Invalid date'){
|
||||
d = '';
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
export default Ember.Helper.helper(timeAgo);
|
29
gui/app/helpers/user-initials.js
Normal file
29
gui/app/helpers/user-initials.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
// 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';
|
||||
|
||||
// {{user-initials firstname lastname}}
|
||||
export function userInitials(params) {
|
||||
let firstname = params[0];
|
||||
let lastname = params[1];
|
||||
|
||||
if (is.undefined(firstname)) {
|
||||
firstname = " ";
|
||||
}
|
||||
if (is.undefined(lastname)) {
|
||||
lastname = " ";
|
||||
}
|
||||
|
||||
return (firstname.substring(0, 1) + lastname.substring(0, 1)).toUpperCase();
|
||||
}
|
||||
|
||||
export default Ember.Helper.helper(userInitials);
|
31
gui/app/index.html
Normal file
31
gui/app/index.html
Normal file
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{{content-for 'head'}}
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Documize</title>
|
||||
<meta property="dbname" content="{{.DBname}}" />
|
||||
<meta property="dbhash" content="{{.DBhash}}" />
|
||||
<meta name="author" content="Documize" />
|
||||
<meta name="description" content="Documize">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<link rel="shortcut icon" href="/favicon.ico?v=1.1" />
|
||||
<link rel="icon" type="image/png" href="/favicon-32x32.png?v=1.1" sizes="32x32" />
|
||||
<link rel="stylesheet" href="/assets/vendor.css">
|
||||
<link rel="stylesheet" href="/assets/documize.css">
|
||||
{{content-for 'head-footer'}}
|
||||
</head>
|
||||
<body>
|
||||
{{content-for 'body'}}
|
||||
<script src="/assets/vendor.js"></script>
|
||||
<script src="/assets/documize.js"></script>
|
||||
<script src="/codemirror/lib/codemirror.js"></script>
|
||||
<script src="/codemirror/mode/meta.js"></script>
|
||||
<script src="/codemirror/addon/mode/loadmode.js"></script>
|
||||
<script src="/codemirror/addon/mode/overlay.js"></script>
|
||||
<script src="/codemirror/addon/runmode/runmode.js"></script>
|
||||
<script src="/codemirror/addon/runmode/colorize.js"></script>
|
||||
{{content-for 'body-footer'}}
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue