incorporate phraseanet-production-client into phraseanet

This commit is contained in:
aina esokia
2020-09-25 18:28:43 +03:00
parent 7df5e99c54
commit abc137bbe6
282 changed files with 66346 additions and 3020 deletions

View File

@@ -0,0 +1,19 @@
{
"ignore": [
"foo.js",
"bar/**/*.js"
],
"presets": [
"es2015", "stage-0"
],
"env": {
"start": {
/* TODO: */
/* fill with hmr settings when there is a new release */
/* to play nice with babel 6*/
}
},
/* Add plugins here**/
"plugins": ["babel-plugin-syntax-jsx"]
}

View File

@@ -0,0 +1,30 @@
# http://editorconfig.org
# A special property that should be specified at the top of the file outside of
# any sections. Set to true to stop .editor config file search on current file
root = true
[*]
# Indentation style
# Possible values - tab, space
indent_style = space
# Indentation size in single-spaced characters
# Possible values - an integer, tab
indent_size = 4
# Line ending file format
# Possible values - lf, crlf, cr
end_of_line = lf
# File character encoding
# Possible values - latin1, utf-8, utf-16be, utf-16le
charset = utf-8
# Denotes whether to trim whitespace at the end of lines
# Possible values - true, false
trim_trailing_whitespace = true
# Denotes whether file should end with a newline
# Possible values - true, false
insert_final_newline = true

View File

@@ -0,0 +1,3 @@
NODE_PATH=./src
NODE_ENV=development
PORT=80

View File

@@ -0,0 +1,4 @@
dist/*
node_modules/*
**/node_modules/*
config/**

View File

@@ -0,0 +1,186 @@
{
"root": true,
"parser": "babel-eslint",
"globals": {
"document": true,
"window": true,
"spy",
"mocha",
"stub",
"beforeEach",
"useFakeTimers": true,
"useFakeXMLHttpRequest": true,
"useFakeServer": true
},
"ecmaFeatures": {
"jsx": true,
"modules": true,
"es6": true
},
"env": {
"browser": true,
"es6": true,
"mocha": true,
"node": true
},
"rules": {
// /* airbnb javascript style guide rules */
// "strict": [2, "never"],
// // es6
// //"no-var": 2,
// // variables
//"no-shadow": 2,
"no-shadow-restricted-names": 2,
// "no-unused-vars": [2, {
// "vars": "all",
// "args": "none"
// }],
"no-undef": 2,
// "no-use-before-define": [2, "nofunc"],
// possible errors
"comma-dangle": 0,
//"no-cond-assign": [2, "always"],
"no-debugger": 1,
//"no-alert": 1,
"no-constant-condition": 1,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
//"no-empty": 2,
"no-ex-assign": 2,
"no-extra-boolean-cast": 0,
"no-extra-semi": 2,
"no-func-assign": 2,
"no-inner-declarations": 2,
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-obj-calls": 2,
"no-sparse-arrays": 2,
"no-unreachable": 2,
"use-isnan": 2,
"block-scoped-var": 2,
// best practices
//"consistent-return": 2,
"curly": [2, "multi-line"],
"default-case": 2,
"dot-notation": [2, {
"allowKeywords": true
}],
"eqeqeq": 2,
//"guard-for-in": 2,
"no-caller": 2,
"no-eq-null": 2,
"no-eval": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-fallthrough": 0,
"no-floating-decimal": 2,
"no-implied-eval": 2,
"no-lone-blocks": 2,
//"no-loop-func": 2,
//"no-multi-str": 2,
"no-native-reassign": 2,
//"no-new": 2,
"no-new-func": 2,
// "no-new-wrappers": 2,
"no-octal": 2,
"no-octal-escape": 2,
// "no-param-reassign": [2, {
// "props": false
// }],
"no-proto": 2,
"no-redeclare": 2,
"no-return-assign": 2,
"no-script-url": 2,
"no-self-compare": 2,
"no-sequences": 2,
//"no-throw-literal": 2,
"no-with": 2,
"radix": 2,
// "vars-on-top": 2,
//"wrap-iife": [2, "any"],
"yoda": 2,
// style
"indent": [0, 0],
"brace-style": [2,
"1tbs", {
"allowSingleLine": true
}
],
"quotes": [
2, "single", "avoid-escape"
],
// "camelcase": [2, {
// "properties": "never"
// }],
"comma-spacing": [2, {
"before": false,
"after": true
}],
"comma-style": [2, "last"],
"eol-last": 2,
"key-spacing": [2, {
"beforeColon": false,
"afterColon": true
}],
// "new-cap": [2, {
// "newIsCap": true
// }],
"no-multiple-empty-lines": [2, {
"max": 2
}],
//"no-nested-ternary": 2,
"no-new-object": 2,
"no-spaced-func": 2,
"no-trailing-spaces": 0,
//"no-extra-parens": 2,
"no-underscore-dangle": 0,
"one-var": [2, "never"],
"padded-blocks": 0,
"semi-spacing": [2, {
"before": false,
"after": true
}],
"keyword-spacing": 2,
"space-before-blocks": 2,
"space-infix-ops": 2,
//"spaced-comment": 2,
/* custom rules */
"no-console": 0,
"space-before-function-paren": [2, {
"named": "never",
"anonymous": "always"
}],
"func-names": 0,
//"consistent-this": [2, "this"],
"func-style": [0, "expression"],
//"max-nested-callbacks": [2, 3],
"new-parens": 2,
"no-array-constructor": 2,
"no-else-return": 0,
//"no-inline-comments": 2,
// "no-lonely-if": 2,
"no-mixed-spaces-and-tabs": 1,
"operator-assignment": 0,
"quote-props": [2, "as-needed"],
"sort-vars": [0, {
"ignoreCase": true
}],
"space-in-brackets": [0, "never", {
"arraysInArrays": false,
"arraysInObjects": false,
"singleValue": false,
"objectsInArrays": false,
"objectsInObjects": false,
"propertyName": false
}],
"space-in-parens": [2, "never"],
"space-unary-ops": [2, {
"words": true,
"nonwords": false
}],
"wrap-regex": 1
},
plugins: []
}

View File

@@ -0,0 +1,8 @@
*.log
node_modules
coverage
npm-debug.log
.DS_Store
dist
bower_components
.idea

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,26 @@
language: node_js
node_js:
- '13.13.0'
# Use container-based Travis infrastructure.
sudo: false
cache:
directories:
- node_modules
before_install:
- nvm install stable
notifications:
email: true
branches:
except:
- "/^v\\d+\\.\\d+\\.\\d+$/"
after_script:
- npm run coveralls
# Upload to coveralls, but don't _fail_ if coveralls is down.
- cat coverage/lcov.info | node_modules/.bin/coveralls || echo "Coveralls upload failed"

View File

@@ -0,0 +1,5 @@
# Changelog
## 0.1.0
- initial release

View File

@@ -0,0 +1,19 @@
##The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,15 @@
## Changelog
### Changed
- Breaking change
### Fixes
- PHRAS-XXX: Short description of bug and fix
- Short description of bug and fix without issue/ticket
### Adds
- PHRAS-XXX: Short feature description
- Short feature description without issue/ticket
### Removes
- PHRAS-XXX: Short feature removal description
- Short feature removal description without issue/ticket

View File

@@ -0,0 +1,49 @@
# Phraseanet Production Client
[![Build Status](https://travis-ci.org/alchemy-fr/Phraseanet-production-client.svg?branch=master)](https://travis-ci.org/alchemy-fr/Phraseanet-production-client)
[![devDependency Status](https://david-dm.org/alchemy-fr/Phraseanet-production-client/dev-status.svg)](https://david-dm.org/alchemy-fr/Phraseanet-production-client#info=devDependencies)
[![Dependency Status](https://david-dm.org/alchemy-fr/Phraseanet-production-client.svg)](https://david-dm.org/alchemy-fr/Phraseanet-production-client)
[![Coverage Status](https://coveralls.io/repos/github/alchemy-fr/Phraseanet-production-client/badge.svg?branch=master)](https://coveralls.io/github/alchemy-fr/Phraseanet-production-client?branch=master)
## Requirements
Node `^5.0.0`.
## Dev workflow
- Go to Phraseanet-production-client-folder
- make your modification
- Generate dist ```npm run dist```
- ```make install_asset``` to copy assets in www/assets folder
- If features is finished ```dist``` folder is to be commited
## Available commands
* `npm run production` - Build task that generate a minified script for production
* `npm run clean` - Remove the `dist` folder and it's files
* `npm run eslint:source` - Lint the source
* `npm run eslint:common` - Lint the unit tests shared by Karma and Mocha
* `npm run eslint:server` - Lint the unit tests for server
* `npm run eslint:browser` - Lint the unit tests for browser
* `npm run eslint:fix` - ESLint will try to fix as many issues as possible in your source files
* `npm run clean` - Remove the coverage report and the *dist* folder
* `npm run test` - Runs unit tests for both server and the browser
* `npm run test:browser` - Runs the unit tests for browser / client
* `npm run test:server` - Runs the unit tests on the server
* `npm run watch:server` - Run all unit tests for server & watch files for changes
* `npm run watch:browser` - Run all unit tests for browser & watch files for changes
* `npm run karma:firefox` - Run all unit tests with Karma & Firefox
* `npm run karma:chrome` - Run all unit tests with Karma & Chrome
* `npm run karma:ie` - Run all unit tests with Karma & Internet Explorer
* `npm run packages` - List installed packages
* `npm run package:purge` - Remove all dependencies
* `npm run package:reinstall` - Reinstall all dependencies
* `npm run package:check` - shows a list over dependencies with a higher version number then the current one - if any
* `npm run package:upgrade` - Automaticly upgrade all devDependencies & dependencies, and update package.json
* `npm run package:dev` - Automaticly upgrade all devDependencies and update package.json
* `npm run package:prod` - Automaticly upgrade all dependencies and update package.json
* `npm run asset-server` - starts a asset server with hot module replacement (WDS) on port 8080
## Credits
based on [Trolly](https://github.com/Kflash/trolly) an es6 boilerplate by [KFlash](https://github.com/kflash)

View File

@@ -0,0 +1,6 @@
import pkg from '../package.json';
export default [
pkg.name + '',
' version ' + pkg.version
];

View File

@@ -0,0 +1,15 @@
const _root = __dirname + '/../';
module.exports = {
// path helpers
_app: 'app',
minified: 'app.min.js',
dev: 'app.js',
eslintDir: _root + '.eslintrc',
distDir: _root + 'dist',
sourceDir: _root + 'src/',
testDir: _root + 'tests',
setupDir: _root + 'tests/setup/node.js',
karmaConf: _root + 'config/karma.conf.js'
};

View File

@@ -0,0 +1,45 @@
/* eslint-disable */
import dotenv from 'dotenv';
import path from 'path';
import {
defaults
}
from 'lodash';
dotenv.load({
silent: false,
path: path.resolve(__dirname, '../.env')
});
const {
ENVIRONMENT,
HOT_RELOAD,
NODE_ENV,
HOST,
PORT,
WEBPACK_DEV_SERVER_PORT
} = defaults(process.env, {
ENVIRONMENT: 'development',
// localhost
HOST: 'localhost',
// port to use with the asset server
PORT: '8000'
}),
IS_PROD = () => {
return ( NODE_ENV === 'production' || ENVIRONMENT === 'prod' || ENVIRONMENT === 'production' );
},
IS_DEV = !IS_PROD,
ENVIRONMENT_NAME = IS_PROD ? 'production' : 'development';
process.env.NODE_ENV = IS_PROD ? 'production' : 'development';
export default {
IS_PROD,
IS_DEV,
ENVIRONMENT_NAME,
HOST,
PORT,
WEBPACK_DEV_SERVER_PORT,
HOT_RELOAD
};
/* eslint-enable */

View File

@@ -0,0 +1,102 @@
import webpackConfig from './webpack/webpack.karma.config';
// Karma configuration here
module.exports = function(config) {
config.set({
// list of files to exclude
exclude: [],
// list of files / patterns to load in the browser
files: [
'./node_modules/jquery/dist/jquery.js',
'./node_modules/babel-polyfill/dist/polyfill.js',
'./node_modules/phantomjs-polyfill/bind-polyfill.js',
'./test/**/*.browser.js'
],
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: [
'sinon-chai',
'sinon',
'chai',
'mocha'
], //use mocha and sinon-chai as framework
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
// 'src/**/*.js': ['coverage'],
'test/**/*.browser.js': ['webpack', 'sourcemap']
},
// test results reporter to use
reporters: ['progress', 'mocha','coverage'],
coverageReporter: {
reporters: [{
type: 'text'
}, {
type: 'lcovonly',
subdir: '.'
}, {
type: 'html',
dir: 'coverage/'
}
]
},
webpack: webpackConfig,
webpackMiddleware: {
noInfo: true
},
plugins: [
'karma-sinon-chai',
'karma-sinon',
'karma-chai',
'karma-webpack',
'karma-mocha',
'karma-mocha-reporter',
'karma-phantomjs-launcher',
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-ie-launcher',
'karma-coverage',
'karma-sourcemap-loader'
],
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera (has to be installed with `npm install karma-opera-launcher`)
// - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
// - PhantomJS
// - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
browsers: ['PhantomJS'],
browserDisconnectTimeout: 10000,
browserDisconnectTolerance: 2,
// concurrency level how many browser should be started simultaneously
concurrency: 4,
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 100000,
browserNoActivityTimeout: 30000,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
});
if (process.env.TRAVIS) {
config.logLevel = config.LOG_DEBUG;
// Karma (with socket.io 1.x) buffers by 50 and 50 tests can take a long time on IEs;-)
config.browserNoActivityTimeout = 120000;
// Debug logging into a file, that we print out at the end of the build.
config.loggers.push({
type: 'file',
filename: 'logs/karma.log'
});
}
};

View File

@@ -0,0 +1,15 @@
/* eslint-disable */
process.env.NODE_ENV = 'development';
global.babel = require('babel-core/register');
global.chai = require("chai");
// global.$ = require("jquery");
global.chaiAsPromised = require("chai-as-promised");
global.chai.use(chaiAsPromised);
global.expect = global.chai.expect;
global.sinon = require('sinon');
global.BROWSER = false;

View File

@@ -0,0 +1,9 @@
./test/**/*.spec.js
--require ./config/mocha.conf.js
--reporter spec
--ui bdd
--compilers js:babel-core/register
--recursive
--timeout 15000
--bail

View File

@@ -0,0 +1,170 @@
/**
* WEBPACK CONFIG
*
*/
/* eslint-disable no-var */
require('babel-core/register');
// Webpack config for development
const webpack = require('webpack');
const path = require('path');
const pkg = require('../../package.json');
// const banner = require('../banner');
const WebpackNotifierPlugin = require('webpack-notifier');
const config = require('../config');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// add loader for external stylesheets:
var extractCSS = new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
});
module.exports = {
// entry points
entry: {
production: config.sourceDir + 'prod/index.js',
lightbox: config.sourceDir + 'lightbox/index.js',
'lightbox-mobile': config.sourceDir + 'lightbox-mobile/index.js',
permaview: config.sourceDir + 'permaview/index.js',
authenticate: [config.sourceDir + 'authenticate/index.js'],
account: [config.sourceDir + 'account/index.js'],
'skin-000000': [config.sourceDir + 'skins/skin-000000.js'],
'skin-959595': [config.sourceDir + 'skins/skin-959595.js'],
'skin-FFFFFF': [config.sourceDir + 'skins/skin-FFFFFF.js']
},
cache: true,
watch: true,
devtool: 'inline-source-map',
output: {
path: config.distDir,
filename: '[name].js',
chunkFilename: 'lazy-[name].js',
libraryTarget: 'umd',
library: config._app,
publicPath: '/assets/production/'
},
module: {
rules: [
{
test: /\.js$/,
enforce: 'pre',
loader: 'eslint-loader',
exclude: /node_modules/,
include: path.join(__dirname, '../../src')
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: { presets: ['es2015', 'stage-0'] },
}],
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:6].[ext]',
}
}
],
exclude: /node_modules/
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|jpeg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[hash:6].[ext]'
}
}
]
},
{
test: /\.css$/,
use: [
"style-loader",
"css-loader"
]
},
{
test: /videojs-flash\.js$/,
loader: 'script-loader'
},
// exclude skins as inline-css in dev env
// {
// test: /\.scss$/,
// exclude: /src\/skins\//,
// loaders: ['style', 'css', 'resolve-url', 'sass?sourceMap']
// },
// only skins are extracted as external file in dev env:
// every css should be exported as file in dev env
{
test: /\.scss$/,
// exclude: /src\/(?!skins)/,
// include: [path.join(__dirname, '../../src'), path.join(__dirname, '../../stylesheets')],
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
'css-loader',
'resolve-url-loader',
{ loader: 'sass-loader', options: { sourceMap: true } }
],
publicPath: './'
})
},{
test: require.resolve('jquery-lazyload'),
use: "imports-loader?this=>window"
}, {
test: require.resolve('geonames-server-jquery-plugin/jquery.geonames'),
use: "imports-loader?this=>window"
}, {
test: require.resolve('bootstrap-multiselect'),
use: "imports-loader?this=>window"
}
]
},
resolve: {
extensions: ['*', '.js', '.css', '.scss']
},
plugins: [
new WebpackNotifierPlugin({
alwaysNotify: true
}),
// new webpack.BannerPlugin(banner),
new webpack.ProvidePlugin({
"videojs": "video.js",
"window.videojs": "video.js"
}),
new webpack.DefinePlugin({
'__DEV__': true,
'process.env.NODE_ENV': JSON.stringify('development'),
VERSION: JSON.stringify(pkg.version)
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
chunks: ['production', 'lightbox'],
minChunks: 2
}),
new webpack.LoaderOptionsPlugin({
debug: true,
options: {
eslint: {
configFile: config.eslintDir
}
}
}),
extractCSS
// i18next
],
externals: {
jquery: 'jQuery',
ui: 'jQuery.ui'
}
};

View File

@@ -0,0 +1,37 @@
/* eslint-disable no-var, strict */
require('babel-core/register');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const environment = require('../environment');
const config = require('./webpack.development.config');
config.devServer = {
hot: true
}
config.plugins = [
// Used for hot-reload
new webpack.HotModuleReplacementPlugin()
];
new WebpackDevServer(webpack(config), {
publicPath: 'http://localhost:8080/assets/',
// Configure hot replacement
// The rest is terminal configurations
quiet: false,
noInfo: true,
historyApiFallback: {
index: './templates/index.html'
},
stats: {
colors: true
}
// We fire up the development server and give notice in the terminal
// that we are starting the initial bundle
}).listen(8080, environment.HOST, function(err, result) {
if (err) {
console.log(err);
}
console.log('The asset server is listening at localhost: 8080');
});

View File

@@ -0,0 +1,100 @@
// Webpack config for development
import webpack from 'webpack';
import path from 'path';
import config from '../config';
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// add loader for external stylesheets:
var extractCSS = new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
});
module.exports = {
cache: true,
devtool: 'inline-source-map',
output: {},
module: {
rules: [
{
test: /\.js$/,
enforce: 'post',
include: path.resolve('src/'),
use: 'istanbul-instrumenter-loader'
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.scss$/,
// exclude: /src\/(?!skins)/,
// include: [path.join(__dirname, '../../src'), path.join(__dirname, '../../stylesheets')],
use: ExtractTextPlugin.extract({
use: [
'css-loader',
'resolve-url-loader',
{ loader: 'sass-loader', options: { sourceMap: true } }
],
publicPath: './'
})
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:6].[ext]',
}
}
],
exclude: /node_modules/
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|jpeg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[hash:6].[ext]'
}
}
]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: { presets: ['es2015', 'stage-0'] },
}],
},
{
test: require.resolve('jquery-lazyload'),
use: "imports-loader?this=>window"
}
]
},
resolve: {
extensions: ['*', '.js', '.css']
},
externals: {
jquery: 'jQuery',
ui: 'jQuery.ui'
},
plugins: [
new webpack.NormalModuleReplacementPlugin(/\.css$/, path.resolve('./src', './empty.js')),
new webpack.LoaderOptionsPlugin({
debug: true
}),
extractCSS
],
devServer: {
hot: true
}
};

View File

@@ -0,0 +1,131 @@
require('babel-core/register');
// Webpack config for creating the production bundle.
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const WebpackNotifierPlugin = require('webpack-notifier');
const PKG_LOCATION = require(path.join(__dirname, '../../package.json'));
const config = require('../config');
const webpackConfig = require('./webpack.development.config');
// add loader for external stylesheets:
var extractCSS = new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
});
module.exports = Object.assign({}, webpackConfig, {
cache: false,
devtool: false,
watch: false,
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: { presets: ['es2015', 'stage-0'] },
}],
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:6].[ext]',
}
}
],
exclude: /node_modules/
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|jpeg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[hash:6].[ext]'
}
}
]
},
{
test: /\.css$/,
use: [
"style-loader",
"css-loader"
]
},
{
test: /videojs-flash\.js$/,
loader: 'script-loader'
},
// exclude skins as inline-css in dev env
// {
// test: /\.scss$/,
// exclude: /src\/skins\//,
// loaders: ['style', 'css', 'resolve-url', 'sass']
// },
// only skins are extracted as external file in dev env:
{
test: /\.scss$/,
// exclude: /src\/(?!skins)/,
// include: [path.join(__dirname, '../../src'), path.join(__dirname, '../../stylesheets')],
use: ExtractTextPlugin.extract({
use: [
'css-loader',
'resolve-url-loader',
{ loader: 'sass-loader', options: { sourceMap: true } }
],
publicPath: './'
})
},
{
test: require.resolve('jquery-lazyload'),
use: "imports-loader?this=>window"
}, {
test: require.resolve('geonames-server-jquery-plugin/jquery.geonames'),
use: "imports-loader?this=>window"
}, {
test: require.resolve('bootstrap-multiselect'),
use: "imports-loader?this=>window"
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"videojs": "video.js",
"window.videojs": "video.js"
}),
// Notifier
new WebpackNotifierPlugin({
title: PKG_LOCATION.name,
alwaysNotify: true
}),
// optimizations
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
'__DEV__': false,
'process.env.NODE_ENV': JSON.stringify('production'),
VERSION: JSON.stringify(PKG_LOCATION.version)
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
chunks: ['production', 'lightbox'],
minChunks: 2
}),
new webpack.LoaderOptionsPlugin({
debug: true
}),
extractCSS
],
devServer: {
hot: true
}
});

View File

@@ -0,0 +1,58 @@
require('babel-core/register');
// Webpack config for creating the minified production bundle.
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const WebpackNotifierPlugin = require('webpack-notifier');
const PKG_LOCATION = require(path.join(__dirname, '../../package.json'));
const config = require('../config');
const webpackConfig = require('./webpack.production.config')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
var extractCSS = new ExtractTextPlugin({
filename: '[name].min.css',
allChunks: true
});
module.exports = Object.assign({}, webpackConfig, {
output: {
path: config.distDir,
filename: '[name].min.js',
chunkFilename: 'lazy-[name].min.js',
libraryTarget: 'umd',
library: config._app,
publicPath: '/assets/production/'
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"videojs": "video.js",
"window.videojs": "video.js"
}),
// Notifier
new WebpackNotifierPlugin({
title: PKG_LOCATION.name,
alwaysNotify: true
}),
// optimizations
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
'__DEV__': false,
'process.env.NODE_ENV': JSON.stringify('production'),
VERSION: JSON.stringify(PKG_LOCATION.version)
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
chunks: ['production', 'lightbox'],
minChunks: 2
}),
extractCSS,
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.min\.css$/,
cssProcessorOptions: { discardComments: { removeAll: true }, zindex: false }
})
]
});

View File

@@ -0,0 +1,2 @@
require('babel-core/register');
module.exports = require('./config/karma.conf');

View File

@@ -0,0 +1,2 @@
*
!.gitignore

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
{
"name": "phraseanet-production-client",
"version": "0.34.272-d",
"description": "Phraseanet frontend dependencies",
"scripts": {
"clean": "rimraf dist",
"dev": "npm run clean && set NODE_ENV=devlopment && npx webpack --config ./config/webpack/webpack.development.config.js --progress --profile --colors",
"production": "npm run clean && set NODE_ENV=production && npx webpack --config ./config/webpack/webpack.production.config.js --progress --profile --colors",
"dist": "npm run clean && set NODE_ENV=production && npx webpack --config ./config/webpack/webpack.production.config.js --progress --profile --colors && npx webpack --config ./config/webpack/webpack.production.minified.config.js --progress --profile --colors",
"test": "npm run test:browser",
"test:server": "mocha --opts config/mocha.opts",
"test:browser": "./node_modules/.bin/karma start --single-run",
"watch:server": "npm run test:server -- --watch",
"watch:browser": "./node_modules/.bin/karma start --auto-watch --no-single-run",
"eslint:source": "eslint ./src/**/*.js",
"eslint:fix": "eslint --fix ./src/**/*.js",
"eslint:common": "eslint ./test/**/*.common.js",
"eslint:server": "eslint ./test/**/*.server.js",
"eslint:browser": "eslint ./test/**/*.browser.js",
"karma:firefox": "./node_modules/.bin/karma start --browsers=Firefox",
"karma:chrome": "./node_modules/.bin/karma start --browsers=Chrome",
"karma:ie": "./node_modules/.bin/karma start --browsers=IE",
"karma:all": "./node_modules/.bin/karma start --browsers=PhantomJS,Chrome,Firefox",
"packages": "npm list --depth=0",
"package:purge": "rm -rf node_modules",
"package:reinstall": "npm run package:purge && npm install",
"package:check": "./node_modules/.bin/ncu",
"package:upgrade": "./node_modules/.bin/ncu -u",
"package:prod": "./node_modules/.bin/ncu -u",
"package:dev": "./node_modules/.bin/ncu -p -u",
"asset-server": "node config/webpack/webpack.hot.assets.config",
"publish-patch": "git add -A && npm run dist && git commit && git push -u origin 4.1 && git push --tags && npm version patch && npm publish",
"publish-minor": "git add -A && npm run dist && git commit && git push -u origin 4.1 && git push --tags && npm version minor && npm publish",
"postpublish": "git push origin 4.1 --follow-tags"
},
"pre-commit": [
"test"
],
"repository": {
"type": "git",
"url": "git+https://github.com/alchemy-fr/Phraseanet-production-client.git"
},
"keywords": [
"phraseanet"
],
"files": [
"dist",
"src"
],
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-core": "^6.25.0",
"babel-eslint": "^7.2.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"chai": "^3.5.0",
"chai-as-promised": "^7.1.1",
"coveralls": "^2.13.1",
"css-loader": "^0.28.4",
"dotenv": "^4.0.0",
"eslint": "^4.18.2",
"eslint-config-airbnb": "^15.1.0",
"eslint-loader": "^1.9.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.1.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.2",
"imports-loader": "^0.7.1",
"istanbul-instrumenter-loader": "^3.0.0",
"karma": "^1.7.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-cli": "^1.0.1",
"karma-coverage": "^1.1.1",
"karma-firefox-launcher": "^1.0.1",
"karma-ie-launcher": "^1.0.0",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.3",
"karma-phantomjs-launcher": "^1.0.4",
"karma-sinon": "^1.0.5",
"karma-sinon-chai": "^1.3.1",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.31",
"karma-webpack": "^2.0.4",
"lodash": "^4.17.15",
"lolex": "^2.1.2",
"mocha": "^3.5.0",
"node-sass": "^4.14.0",
"nodemon": "^1.11.0",
"npm-check-updates": "^2.12.1",
"npmlog": "^4.1.2",
"optimize-css-assets-webpack-plugin": "^3.0.0",
"phantomjs-polyfill": "0.0.2",
"phantomjs-prebuilt": "^2.1.16",
"postcss-loader": "^2.0.6",
"pre-commit": "^1.2.2",
"resolve-url-loader": "^2.1.0",
"rimraf": "^2.6.1",
"sass-loader": "^6.0.6",
"sinon": "^2.1.0",
"sinon-chai": "^2.12.0",
"style-loader": "^0.18.2",
"url-loader": "^0.5.9",
"webpack": "^3.4.1",
"webpack-dev-server": "^2.6.1",
"webpack-notifier": "^1.5.0"
},
"babel": {
"ignore": [
"packages/babel-cli/src/babel-plugin/templates"
]
},
"devEngines": {
"node": ">=4.1 <6",
"npm": ">=3.1 <5"
},
"author": {
"name": "Florian Blouet",
"email": "florian.blouet@gmail.com"
},
"bugs": "https://github.com/alchemy-fr/Phraseanet-production-client/issues",
"homepage": "https://github.com/alchemy-fr/Phraseanet-production-client",
"license": "MIT",
"dependencies": {
"@mapbox/mapbox-gl-language": "^0.9.2",
"@turf/turf": "^5.1.6",
"axios": "^0.19.2",
"backbone": "^1.3.3",
"blueimp-file-upload": "^9.15.0",
"blueimp-load-image": "^2.14.0",
"bootstrap-multiselect": "^0.9.13-1",
"bootstrap-sass": "^2.3.2",
"es6-promise": "^4.1.1",
"geonames-server-jquery-plugin": "^0.2.2",
"humane-js": "^3.2.2",
"i18next": "^8.4.3",
"i18next-xhr-backend": "^1.4.2",
"jquery": "^3.2.1",
"jquery-lazyload": "^1.9.7",
"jquery-treeview": "https://github.com/alchemy-fr/jquery-treeview.git",
"jquery-ui": "^1.10.4",
"jquery-ui-datepicker-with-i18n": "^1.10.4",
"jquery.fancytree": "~2.7",
"jquery.tree": "0.0.5",
"js-cookie": "^2.1.0",
"leaflet": "^0.7.7",
"leaflet-contextmenu": "^1.0.0",
"leaflet-draw": "^0.3.0",
"lodash.merge": "^4.6.2",
"mapbox": "^1.0.0-beta10",
"mapbox-gl": "^1.11.0",
"mapbox-gl-circle": "^1.6.5",
"mapbox.js": "^2.4.0",
"nouislider": "^9.2.0",
"pym.js": "^1.3.1",
"rx": "^4.1.0",
"sprintf-js": "^1.1.1",
"underscore": "^1.8.3",
"video.js": "^7.5.5",
"videojs-flash": "^2.1.0",
"videojs-hotkeys": "^0.2.20",
"zxcvbn": "^4.4.2"
}
}

View File

@@ -0,0 +1,74 @@
import $ from 'jquery';
import ConfigService from './../components/core/configService';
import LocaleService from '../components/locale';
import merge from 'lodash.merge';
import defaultConfig from './config';
import Emitter from '../components/core/emitter';
import account from './../components/account';
$(document).ready(() => {
// hide or show callback url input whether user choose a web or dektop application
$('#form_create input[name=type]').bind('click', function () {
if ($(this).val() === 'desktop') {
$('#form_create .callback-control-group').hide().find('input').val('');
} else {
$('#form_create .callback-control-group').show();
}
});
});
class Bootstrap {
app;
configService;
localeService;
appServices;
constructor(userConfig) {
const configuration = merge({}, defaultConfig, userConfig);
this.appEvents = new Emitter();
this.configService = new ConfigService(configuration);
this.onConfigReady();
return this;
}
onConfigReady() {
this.appServices = {
configService: this.configService,
localeService: this.localeService,
appEvents: this.appEvents
};
/**
* add components
*/
$(document).ready(() => {
let accountService = account(this.appServices);
accountService.initialize({
$container: $('body')
});
switch (this.configService.get('state')) {
case 'editAccount':
accountService.editAccount();
break;
case 'editSession':
accountService.editSession();
break;
default:
}
});
}
}
const bootstrap = (userConfig) => {
return new Bootstrap(userConfig);
};
export default bootstrap;

View File

@@ -0,0 +1,7 @@
let defaultConfig = {
locale: 'fr',
basePath: '/',
translations: '/prod/language.json',
};
export default defaultConfig;

View File

@@ -0,0 +1,10 @@
import bootstrap from './bootstrap';
let accountApp = {
bootstrap
};
if (typeof window !== 'undefined') {
window.accountApp = accountApp;
}
module.exports = accountApp;

View File

@@ -0,0 +1,86 @@
import $ from 'jquery';
import ConfigService from './../components/core/configService';
import LocaleService from '../components/locale';
import merge from 'lodash.merge';
import defaultConfig from './config';
import Emitter from '../components/core/emitter';
import authentication from './../components/authentication';
class Bootstrap {
app;
configService;
localeService;
appServices;
constructor(userConfig) {
const configuration = merge({}, defaultConfig, userConfig);
this.appEvents = new Emitter();
this.configService = new ConfigService(configuration);
this.localeService = new LocaleService({
configService: this.configService
});
this.localeService.fetchTranslations()
.then(() => {
this.onConfigReady();
});
return this;
}
onConfigReady() {
this.appServices = {
configService: this.configService,
localeService: this.localeService,
appEvents: this.appEvents
};
// export translation for backward compatibility:
// window.language = this.localeService.getTranslations();
/**
* add components
*/
$(document).ready(() => {
let authService = authentication(this.appServices);
authService.initialize();
switch (this.configService.get('state')) {
case 'login':
authService.login();
break;
case 'forgotPassword':
authService.forgotPassword();
break;
case 'renewPassword':
authService.renewPassword();
break;
case 'register':
authService.register();
break;
case 'registerProvider':
authService.registerProvider();
break;
case 'renewEmail':
authService.renewEmail();
break;
case 'changePassword':
authService.changePassword();
break;
default:
}
});
}
}
const bootstrap = (userConfig) => {
return new Bootstrap(userConfig);
};
export default bootstrap;

View File

@@ -0,0 +1,7 @@
let defaultConfig = {
locale: 'fr',
basePath: '/',
translations: '/login/language.json',
};
export default defaultConfig;

View File

@@ -0,0 +1,10 @@
import bootstrap from './bootstrap';
let authenticateApp = {
bootstrap
};
if (typeof window !== 'undefined') {
window.authenticateApp = authenticateApp;
}
module.exports = authenticateApp;

View File

@@ -0,0 +1,236 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import geonames from './../authentication/common/geonames';
const account = (services) => {
const {configService, localeService, appEvents} = services;
const initialize = (options) => {
let {$container} = options;
$container.on('click', '.alert .alert-block-close a', function (e) {
e.preventDefault();
$(this).closest('.alert').alert('close');
return false;
});
// revoke third party application access
$('a.app-btn').bind('click', function (e) {
e.preventDefault();
var $this = $(this);
$.ajax({
type: 'GET',
url: $this.attr('href'),
dataType: 'json',
data: {revoke: $this.hasClass('authorize') ? 0 : 1},
success: function (data) {
if (data.success) {
var li = $this.closest('li');
var hidden = $('.app-btn.hidden , .status.hidden', li);
var notHidden = $('.app-btn:not(.hidden), .status:not(.hidden)', li);
hidden.removeClass('hidden');
notHidden.addClass('hidden');
}
}
});
});
// generate new access token
$('a#generate_access').bind('click', function (e) {
e.preventDefault();
var $this = $(this);
$.ajax({
type: 'POST',
url: $this.attr('href'),
dataType: 'json',
data: {
usr_id: $this.closest('div').attr('id')
},
success: function (data) {
if (data.success) {
$('#my_access_token').empty().append(data.token);
}
}
});
});
//modify application callback url
$('.modifier_callback').bind('click', function () {
var modifierBtn = $(this);
var saveBtn = $('a.save_callback');
var input = $('.url_callback_input');
var inputVal = input.html();
modifierBtn.hide();
saveBtn.show();
// wrapp current calback in an input
input
.empty()
.wrapInner(''
+ '<input value="' + inputVal + '"'
+ ' name="oauth_callback" size="50" type="text"/>'
);
$('.url_callback').off();
// save new callback
saveBtn.bind('click', function (e) {
e.preventDefault();
var callback = $('input[name=oauth_callback]').val();
$.ajax({
type: 'POST',
url: saveBtn.attr('href'),
dataType: 'json',
data: {callback: callback},
success: function (data) {
if (data.success) {
input.empty().append(callback);
} else {
input.empty().append(inputVal);
}
modifierBtn.show();
saveBtn.hide();
}
});
});
});
//modify application webhook url
$('.webhook-modify-btn').bind('click', function () {
var modifierBtn = $(this);
var saveBtn = $('a.save_webhook');
var input = $('.url_webhook_input');
var inputVal = input.html();
modifierBtn.hide();
saveBtn.show();
// wrapp current calback in an input
input
.empty()
.wrapInner(''
+ '<input value="' + inputVal + '"'
+ ' name="oauth_webhook" size="50" type="text"/>'
);
$('.url_webhook').off();
// save new callback
saveBtn.bind('click', function (e) {
e.preventDefault();
var webhook = $('input[name=oauth_webhook]').val();
$.ajax({
type: 'POST',
url: saveBtn.attr('href'),
dataType: 'json',
data: {webhook: webhook},
success: function (data) {
if (data.success) {
input.empty().append(webhook);
} else {
input.empty().append(inputVal);
}
modifierBtn.show();
saveBtn.hide();
}
});
});
});
// hide or show callback url input whether user choose a web or dektop application
/* $('#form_create input[name=type]').bind('click', function () {
if ($(this).val() === 'desktop') {
$('#form_create .callback-control-group').hide().find('input').val('');
} else {
$('#form_create .callback-control-group').show();
}
});*/
// authorize password grant type or not
$('.grant-type').bind('click', function () {
var $this = $(this);
$.ajax({
type: 'POST',
url: $this.attr('value'),
dataType: 'json',
data: {grant: $this.is(':checked') ? '1' : '0'},
success: function (data) {
}
});
});
// delete an application
/* $('a.delete-app').bind('click', function (e) {
e.preventDefault();
var $this = $(this);
var li = $this.closest('li');
$.ajax({
type: 'DELETE',
url: $this.attr('href'),
dataType: 'json',
data: {},
success: function (data) {
if (data.success) {
li.find('.modal').modal('hide');
li.remove();
}
}
});
});*/
};
const editAccount = () => {
$('legend').bind('click', function () {
$('.form-info').hide(200);
$($(this).data('target')).show();
});
geonames.init($('#form_geonameid'), {
server: configService.get('geonameServerUrl'),
limit: 40
});
};
const editSession = () => {
var modal = $('#modal-delete-confirm').modal({
show: false
});
$('a.delete-session').bind('click', function (e) {
e.preventDefault();
modal
.data('delete-url', $(this).prop('href'))
.modal('toggle');
return false;
});
$('a.confirm-delete').on('click', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: modal.data('delete-url'),
dataType: 'json',
success: function (data) {
if (data.success) {
$('#row-' + data.session_id).closest('tr').remove();
}
modal.modal('toggle');
}
});
});
};
return {initialize, editAccount, editSession}
};
export default account;

View File

@@ -0,0 +1,56 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import RenewPasswordForm from './common/forms/views/formType/passwordSetter';
const changePassword = (services) => {
const {configService, localeService, appEvents} = services;
const initialize = () => {
require.ensure([], () => {
services.zxcvbn = require('zxcvbn');
new RenewPasswordForm({
services,
el: $('form[name=passwordChangeForm]'),
rules: [
{
name: 'oldPassword',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'password[password]',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'password[password]',
rules: 'min_length[5]',
message: localeService.t('validation_length_min', {
postProcess: 'sprintf',
sprintf: ['5']
})
},
{
name: 'password[confirm]',
rules: 'matches[password[password]]',
message: localeService.t('password_match')
}
]
});
});
};
return {initialize};
};
export default changePassword;

View File

@@ -0,0 +1,278 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import _ from 'underscore';
var FormValidator = function (rules, handlers) {
// rules setted by user
this.rules = rules || [];
// custom callbacks
this.handlers = handlers || [];
// final fields to validate
this.fields = [];
var self = this;
_.each(this.rules, function (field) {
if ('name' in field && 'rules' in field) {
self._addField(field);
}
});
};
// Validate method, argument is the serialize form
FormValidator.prototype.validate = function (inputs) {
var self = this;
// possible errors
this.errors = [];
// inputs present in form
this.inputs = {};
_.each(_.groupBy(inputs, function (input) {
return input.name;
}), function (fields, name) {
self.inputs[name] = fields;
});
this._validateForm();
return this;
};
FormValidator.prototype.getErrors = function () {
return this.errors;
};
FormValidator.prototype.hasErrors = function () {
return this.errors.length > 0;
};
FormValidator.prototype.getRules = function () {
return this.rules;
};
FormValidator.prototype._addField = function (field) {
this.fields.push({
name: field.name,
rules: field.rules,
message: field.message || 'An error ocurred on input[name=' + field.name + '], you can edit this message by setting a "message" property in your rule definition object',
value: null,
type: field.type || 'text'
});
};
FormValidator.prototype._validateForm = function () {
var self = this;
this.errors = [];
_.each(this.fields, function (field) {
if (_.has(self.inputs, field.name)) {
// values can be multiple
var values = [];
_.each(self.inputs[field.name], function (field) {
return values.push(field.value);
});
field.value = values.join(',');
self._validateField(field);
} else if (field.type === 'checkbox' || field.type === 'radio' || field.type === 'select' || field.type === 'multiple') {
field.value = '';
self._validateField(field);
}
});
};
FormValidator.prototype._validateField = function (field) {
var self = this;
var ruleRegex = /^(.+?)\[(.+)\]$/;
var rules = field.rules.split('|');
// Run through the rules and execute the validation methods as needed
_.every(rules, function (method) {
var param = null;
var failed = false;
var parts = ruleRegex.exec(method);
// If the rule has a parameter (i.e. matches[param]) split it out
if (parts) {
method = parts[1];
param = parts[2];
}
// If the hook is defined, run it to find any validation errors
if (typeof self._hooks[method] === 'function') {
if (!self._hooks[method].apply(self, [field, param])) {
failed = true;
}
} else if (method.substring(0, 9) === 'callback_') {
// Custom method. Execute the handler if it was registered
method = method.substring(9, method.length);
if (typeof self.handlers[method] === 'function') {
if (this.handlers[method].apply(self, [field.value, param]) === false) {
failed = true;
}
}
}
// If the hook failed, add a message to the errors array
if (failed) {
self.errors.push({
name: field.name,
value: field.value,
message: field.message,
rule: method
});
}
// Breaks loop iteration
return failed;
});
};
FormValidator.prototype.Regexp = {
numericRegex: /^[0-9]+$/,
integerRegex: /^\-?[0-9]+$/,
decimalRegex: /^\-?[0-9]*\.?[0-9]+$/,
emailRegex: /^[^@]+@[^@]+\.[^@]+$/,
alphaRegex: /^[a-z]+$/i,
alphaNumericRegex: /^[a-z0-9]+$/i,
alphaDashRegex: /^[a-z0-9_\-]+$/i,
naturalRegex: /^[0-9]+$/i,
naturalNoZeroRegex: /^[1-9][0-9]*$/i,
// IP v6 a v4 or hostname, by Mikulas Dite see http://stackoverflow.com/a/9209720/96656
ipRegex: /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))$/i,
numericDashRegex: /^[\d\-\s]+$/,
urlRegex: /^((http|https):\/\/(\w+:{0,1}\w*@)?(\S+)|)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/
};
// Object containing all of the validation hooks
FormValidator.prototype._hooks = {
required: function (field) {
var value = field.value;
return (value !== null && value !== '');
},
equal: function (field, defaultName) {
return field.value === defaultName;
},
matches: function (field, matchName) {
if (typeof this.inputs[matchName] === 'undefined') {
return false;
}
var el = this.inputs[matchName].shift();
if (el) {
return field.value === el.value;
}
return false;
},
valid_email: function (field) {
return this.Regexp.emailRegex.test(field.value);
},
valid_emails: function (field) {
var result = field.value.split(',');
for (var i = 0; i < result.length; i++) {
if (!this.Regexp.emailRegex.test($.trim(result[i]))) {
return false;
}
}
return true;
},
min_length: function (field, length) {
if (field.type === 'multiple') {
return _.filter(field.value.split(','), function (value) {
return value !== '';
}).length >= parseInt(length, 10)
}
if (!this.Regexp.numericRegex.test(length)) {
return false;
}
return (field.value.length >= parseInt(length, 10));
},
max_length: function (field, length) {
if (field.type === 'multiple') {
return _.filter(field.value.split(','), function (value) {
return value !== '';
}).length <= parseInt(length, 10)
}
if (!this.Regexp.numericRegex.test(length)) {
return false;
}
return (field.value.length <= parseInt(length, 10));
},
exact_length: function (field, length) {
if (field.type === 'multiple') {
return _.filter(field.value.split(','), function (value) {
return value !== '';
}).length === parseInt(length, 10)
}
if (!this.Regexp.numericRegex.test(length)) {
return false;
}
return (field.value.length === parseInt(length, 10));
},
greater_than: function (field, param) {
if (!this.Regexp.decimalRegex.test(field.value)) {
return false;
}
return (parseFloat(field.value) > parseFloat(param));
},
less_than: function (field, param) {
if (!this.Regexp.decimalRegex.test(field.value)) {
return false;
}
return (parseFloat(field.value) < parseFloat(param));
},
alpha: function (field) {
return (this.Regexp.alphaRegex.test(field.value));
},
alpha_numeric: function (field) {
return (this.Regexp.alphaNumericRegex.test(field.value));
},
alpha_dash: function (field) {
return (this.Regexp.alphaDashRegex.test(field.value));
},
numeric: function (field) {
return (this.Regexp.numericRegex.test(field.value));
},
integer: function (field) {
return (this.Regexp.integerRegex.test(field.value));
},
decimal: function (field) {
return (this.Regexp.decimalRegex.test(field.value));
},
is_natural: function (field) {
return (this.Regexp.naturalRegex.test(field.value));
},
is_natural_no_zero: function (field) {
return (this.Regexp.naturalNoZeroRegex.test(field.value));
},
valid_ip: function (field) {
return (this.Regexp.ipRegex.test(field.value));
},
valid_url: function (field) {
return (this.Regexp.urlRegex.test(field.value));
}
};
export default FormValidator;

View File

@@ -0,0 +1,60 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import _ from 'underscore';
import Backbone from 'backbone';
var ErrorView = Backbone.View.extend({
tagName: 'div',
initialize: function (options) {
options = options || {};
if (options.name === undefined) {
throw 'Missing name attribute in error view';
}
if (options.errorTemplate === undefined) {
throw 'Missing errorTemplate attribute in error view';
}
this.name = options.name;
this.errorTemplate = options.errorTemplate;
this.errors = options.errors || {};
this.onRenderError = options.onRenderError || null;
},
render: function () {
if (this.errors.length > 0) {
var template = _.template($(this.errorTemplate).html(), {
errors: this.errors
});
this.$el.html(template);
if (_.isFunction(this.onRenderError)) {
this.onRenderError(this.name, this.$el);
}
} else {
this.reset();
}
return this;
},
renderErrors: function (errors) {
this.errors = errors;
this.render();
return this;
},
reset: function () {
this.$el.empty();
}
});
export default ErrorView;

View File

@@ -0,0 +1,89 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import _ from 'underscore';
import Backbone from 'backbone';
import Validator from './../validator';
import InputView from './input';
var Form = Backbone.View.extend({
events: {
submit: '_onSubmit'
},
initialize: function (options) {
options = options || {};
var self = this;
if (options.services !== undefined) {
this.services = options.services;
}
this.errorTemplate = options.errorTemplate || '#field_errors';
this.onRenderError = options.onRenderError || null;
// get a new validator defined rules
this.validator = new Validator(options.rules || []);
this.inputViews = {};
// creates input views for each input
_.each(this.$el.serializeArray(), function (input) {
self._addInputView(input);
});
},
_onSubmit: function (event) {
var self = this;
// reset previous errors in the view
this._resetInputErrors();
// validate new values
this.validator.validate(this.$el.serializeArray());
if (this.validator.hasErrors()) {
// cancel submit
event.preventDefault();
// group errors by input
_.each(_.groupBy(this.validator.getErrors(), function (error) {
return error.name;
}), function (errors, name) {
// show new errors in the views
if (name in self.inputViews) {
self.inputViews[name].showErrors(errors);
} else {
// Because serialize array do not serialize non checked input
// We must create view for errored input name on the fly
var input = {name: name};
self._addInputView(input);
self.inputViews[name].showErrors(errors);
}
});
}
},
_resetInputErrors: function () {
_.each(this.inputViews, function (view) {
view.resetErrors();
});
},
_addInputView: function (input) {
var name = input.name;
this.inputViews[name] = new InputView({
name: name,
el: $('input[name="' + name + '"], select[name="' + name + '"], textarea[name="' + name + '"]', this.$el).first().closest('div'),
errorTemplate: this.errorTemplate,
onRenderError: this.onRenderError
});
return this;
}
});
export default Form;

View File

@@ -0,0 +1,76 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import _ from 'underscore';
import FormView from './../form';
var PasswordSetterForm = FormView.extend({
events: function () {
return _.extend({}, FormView.prototype.events, {
'keyup input[type=password]': 'onPasswordKeyup'
});
},
onPasswordKeyup: function (event) {
var input = $(event.target);
var password = input.val();
var inputView = this.inputViews[input.attr('name')];
var bg = $('.password_strength_bg', inputView.$el);
var label = $('.password_strength_label', inputView.$el);
var desc = $('.password_strength_desc', inputView.$el);
var css = {
width: '0%',
'background-color': 'rgb(39, 39, 30)'
};
var result = '';
if (password.length > 0) {
var passMeter = this.services.zxcvbn(input.val());
switch (passMeter.score) {
case 0:
case 1:
css = {
width: '25%',
'background-color': 'rgb(200, 24, 24)'
};
result = this.services.localeService.t('weak');
break;
case 2:
css = {
width: '50%',
'background-color': 'rgb(255, 172, 29)'
};
result = this.services.localeService.t('ordinary');
break;
case 3:
css = {
width: '75%',
'background-color': 'rgb(166, 192, 96)'
};
result = this.services.localeService.t('good');
break;
case 4:
css = {
width: '100%',
'background-color': 'rgb(39, 179, 15)'
};
result = this.services.localeService.t('great');
break;
default:
}
}
bg.css(css);
label.css({color: css['background-color']});
desc.css({color: css['background-color']}).html(result);
}
});
export default PasswordSetterForm;

View File

@@ -0,0 +1,49 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import _ from 'underscore';
import Backbone from 'backbone';
import ErrorView from './error';
import MultiViews from './../../multiviews';
var InputView = Backbone.View.extend(_.extend({}, MultiViews, {
initialize: function (options) {
options = options || {};
if (options.name === undefined) {
throw 'Missing name attribute in input view';
}
if (options.errorTemplate === undefined) {
throw 'Missing errorTemplate attribute in input view';
}
this.name = options.name;
this.errorView = new ErrorView({
name: this.name,
errorTemplate: options.errorTemplate,
onRenderError: options.onRenderError || null
});
},
render: function () {
this._assignView({'.error-view': this.errorView});
},
showErrors: function (errors) {
this.render();
this.errorView.renderErrors(errors);
return this;
},
resetErrors: function () {
this.errorView.reset();
}
}));
export default InputView;

View File

@@ -0,0 +1,43 @@
import $ from 'jquery';
require('jquery-ui');
require('geonames-server-jquery-plugin/jquery.geonames.js');
const geonames = {
init: function ($field, options) {
var geocompleter = $field.geocompleter(options);
// On focus add select-state
geocompleter.geocompleter('autocompleter', 'on', 'autocompletefocus', function (event, ui) {
$('li', $(event.originalEvent.target)).closest('li').removeClass('selected');
$('a.ui-state-active, a.ui-state-hover, a.ui-state-focus', $(event.originalEvent.target)).closest('li').addClass('selected');
});
// On search request add loading-state
geocompleter.geocompleter('autocompleter', 'on', 'autocompletesearch', function (event, ui) {
$(this).attr('autocomplete', 'false');
$(this).addClass('input-loading');
$(this).removeClass('input-error');
});
// On response remove loading-state
geocompleter.geocompleter('autocompleter', 'on', 'autocompleteresponse', function (event, ui) {
$(this).removeClass('input-loading');
});
// On close menu remove loading-state
geocompleter.geocompleter('autocompleter', 'on', 'autocompleteclose', function (event, ui) {
$(this).removeClass('input-loading');
});
// On request error add error-state
geocompleter.geocompleter('autocompleter', 'on', 'geotocompleter.request.error', function (jqXhr, status, error) {
$(this).removeClass('input-loading');
$(this).addClass('input-error');
});
return geocompleter;
}
};
export default geonames;

View File

@@ -0,0 +1,26 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import _ from 'underscore';
export default {
// bind a subview to a DOM element
_assignView: function (selector, view) {
var selectors;
if (_.isObject(selector)) {
selectors = selector;
} else {
selectors = {};
selectors[selector] = view;
}
if (!selectors) return;
_.each(selectors, function (view, selector) {
view.setElement(this.$(selector)).render();
}, this);
}
};

View File

@@ -0,0 +1,36 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import ForgotPassWordForm from './common/forms/views/form';
const forgotPassword = (services) => {
const { configService, localeService, appEvents } = services;
const initialize = () => {
new ForgotPassWordForm({
el: $('form[name=forgottenPasswordForm]'),
rules: [
{
name: 'email',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'email',
rules: 'valid_email',
message: localeService.t('validation_email')
}
]
});
};
return {initialize};
};
export default forgotPassword;

View File

@@ -0,0 +1,87 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import loginService from './login';
import forgotPasswordService from './forgotPassword';
import renewPasswordService from './renewPassword';
import registerService from './register';
import registerProviderService from './registerProvider';
import renewEmailService from './renewEmail';
import changePasswordService from './changePassword';
require('bootstrap-multiselect'); // multiselect
const authentication = (services) => {
const { configService, localeService, appEvents } = services;
const initialize = () => {
// close alerts
$(document).on('click', '.alert .alert-block-close a', function (e) {
e.preventDefault();
$(this).closest('.alert').alert('close');
return false;
});
$('select[multiple="multiple"]').multiselect({
buttonWidth: '100%',
buttonClass: 'btn btn-inverse',
maxHeight: 185,
includeSelectAllOption: true,
selectAllValue: 'all',
selectAllText: localeService.t('all_collections'),
buttonText: function (options, select) {
if (options.length === 0) {
return localeService.t('no_collection_selected') + '<b class="caret"></b>';
} else {
return localeService.t(
options.length === 1 ? 'one_collection_selected' : 'collections_selected', {
postProcess: 'sprintf',
sprintf: [options.length]
}) + ' <b class="caret"></b>';
}
}
});
$('form[name="registerForm"]').on('submit', function () {
// must deselect the 'select all' checkbox for server side validation.
$('select[multiple="multiple"]').multiselect('deselect', 'all');
});
};
const login = () => {
// init login form
loginService(services).initialize();
};
const forgotPassword = () => {
// init login form
forgotPasswordService(services).initialize();
};
const renewPassword = () => {
// init login form
renewPasswordService(services).initialize();
};
const register = () => {
// init login form
registerService(services).initialize();
};
const registerProvider = () => {
// init login form
registerProviderService(services).initialize();
};
const renewEmail = () => {
// init login form
renewEmailService(services).initialize();
};
const changePassword = () => {
// init login form
changePasswordService(services).initialize();
};
return { initialize, login, forgotPassword, renewPassword, register, registerProvider, renewEmail, changePassword}
};
export default authentication;

View File

@@ -0,0 +1,37 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import LoginForm from './common/forms/views/form';
const login = (services) => {
const {configService, localeService, appEvents} = services;
const initialize = () => {
new LoginForm({
el: $('form[name=loginForm]'),
rules: [
{
name: 'login',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'password',
rules: 'required',
message: localeService.t('validation_blank')
}
]
});
};
return {initialize};
};
export default login;

View File

@@ -0,0 +1,133 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
// launch application
import $ from 'jquery';
import _ from 'underscore';
import RegisterForm from './common/forms/views/formType/passwordSetter';
import geonames from './common/geonames';
const regiser = (services) => {
const {configService, localeService, appEvents} = services;
const initialize = () => {
var fieldsConfiguration = [];
$.when.apply($, [
$.ajax({
url: '/login/registration-fields/',
success: function (config) {
fieldsConfiguration = config;
}
})
]).done(function () {
var rules = [];
var defaultRules = [
{
name: 'email',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'email',
rules: 'valid_email',
message: localeService.t('validation_email')
},
{
name: 'password[password]',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'password[password]',
rules: 'min_length[5]',
message: localeService.t('validation_length_min', {
postProcess: 'sprintf',
sprintf: ['5']
})
},
{
name: 'password[confirm]',
rules: 'matches[password[password]]',
message: localeService.t('password_match')
},
{
name: 'accept-tou',
rules: 'required',
message: localeService.t('accept_tou'),
type: 'checkbox'
},
{
name: 'collections[]',
rules: 'min_length[1]',
message: localeService.t('validation_choice_min', {
postProcess: 'sprintf',
sprintf: ['1']
}),
type: 'multiple'
}
];
_.each(fieldsConfiguration, function (field) {
if (field.required) {
var rule = {
name: field.name,
rules: 'required',
message: localeService.t('validation_blank')
};
defaultRules.push(rule);
}
});
_.each(defaultRules, function (rule) {
// add rule if element exists
if ($('[name="' + rule.name + '"]').length >= 1) {
}
});
var $form = $('form[name=registerForm]');
require.ensure([], () => {
services.zxcvbn = require('zxcvbn');
new RegisterForm({
el: $form,
rules: rules,
services
});
});
var geocompleter = geonames.init($('#geonameid'), {
server: $form.data('geonames-server-adress'),
limit: 40,
'init-input': false,
onInit: function (input, autoinput) {
// Set default name to geonameid-completer
autoinput.prop('name', 'geonameid-completer');
}
});
// Positioning menu below input
geocompleter.geocompleter('autocompleter', 'option', 'position', {
of: geocompleter.closest('.input-table'),
my: 'left top',
at: 'left bottom'
});
// On open menu calculate max-width
geocompleter.geocompleter('autocompleter', 'on', 'autocompleteopen', function (event, ui) {
$(this).autocomplete('widget').css('min-width', geocompleter.closest('.input-table').outerWidth());
});
});
};
return {initialize};
};
export default regiser;

View File

@@ -0,0 +1,105 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
// launch application
import $ from 'jquery';
import _ from 'underscore';
import RegisterForm from './common/forms/views/form';
const registerProvider = (services) => {
const {configService, localeService, appEvents} = services;
const initialize = () => {
var fieldsConfiguration = [];
$.when.apply($, [
$.ajax({
url: '/login/registration-fields/',
success: function (config) {
fieldsConfiguration = config;
}
})
]).done(function () {
var rules = [];
var defaultRules = [
{
name: 'email',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'email',
rules: 'valid_email',
message: localeService.t('validation_email')
},
{
name: 'password',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'password',
rules: 'min_length[5]',
message: localeService.t('validation_length_min', {
postProcess: 'sprintf',
sprintf: ['5']
})
},
{
name: 'passwordConfirm',
rules: 'matches[password]',
message: localeService.t('password_match')
},
{
name: 'accept-tou',
rules: 'required',
message: localeService.t('accept_tou'),
type: 'checkbox'
},
{
name: 'collections[]',
rules: 'min_length[1]',
message: localeService.t('validation_choice_min', {
postProcess: 'sprintf',
sprintf: ['1']
}),
type: 'multiple'
}
];
_.each(fieldsConfiguration, function (field) {
if (field.required) {
var rule = {
name: field.name,
rules: 'required',
message: localeService.t('validation_blank')
};
defaultRules.push(rule);
}
});
_.each(defaultRules, function (rule) {
// add rule if element exists
if ($('[name="' + rule.name + '"]').length >= 1) {
rules.push(rule);
}
});
new RegisterForm({
el: $('form[name=registerForm]'),
rules: rules
});
});
};
return {initialize};
};
export default registerProvider;

View File

@@ -0,0 +1,50 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import RenewEmailForm from './common/forms/views/form';
const renewEmail = (services) => {
const {configService, localeService, appEvents} = services;
const initialize = () => {
new RenewEmailForm({
el: $('form[name=changeEmail]'),
errorTemplate: '#field_errors_block',
onRenderError: function (name, $el) {
$el.closest('.control-group').addClass('error');
},
rules: [
{
name: 'form_password',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'form_email',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'form_email',
rules: 'email',
message: localeService.t('validation_email')
},
{
name: 'form_email_confirm',
rules: 'matches[form_email]',
message: localeService.t('email_match')
}
]
});
};
return {initialize};
};
export default renewEmail;

View File

@@ -0,0 +1,48 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import RenewPasswordForm from './common/forms/views/formType/passwordSetter';
const renewPassword = (services) => {
const {configService, localeService, appEvents} = services;
const initialize = () => {
require.ensure([], () => {
services.zxcvbn = require('zxcvbn');
new RenewPasswordForm({
services,
el: $('form[name=passwordRenewForm]'),
rules: [
{
name: 'password[password]',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'password[password]',
rules: 'min_length[5]',
message: localeService.t('validation_length_min', {
postProcess: 'sprintf',
sprintf: ['5']
})
},
{
name: 'password[confirm]',
rules: 'matches[password[password]]',
message: localeService.t('password_match')
}
]
});
});
};
return {initialize};
};
export default renewPassword;

View File

@@ -0,0 +1,55 @@
import $ from 'jquery';
const archiveBasket = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
let $container = null;
const initialize = () => {
$container = $('body');
$container.on('click', '.basket-archive-action', function (event) {
event.preventDefault();
let $el = $(event.currentTarget);
doArchive($el.data('basket-id'));
});
};
function doArchive(basketId) {
$.ajax({
type: 'POST',
url: `${url}prod/baskets/${basketId}/archive/?archive=1`,
dataType: 'json',
beforeSend: function () {
},
success: function (data) {
if (data.success) {
const basket = $('#SSTT_' + basketId);
const next = basket.next();
if (next.data('ui-droppable')) {
next.droppable('destroy');
}
next.slideUp().remove();
if (basket.data('ui-droppable')) {
basket.droppable('destroy');
}
basket.slideUp().remove();
if ($('#baskets .SSTT').length === 0) {
appEvents.emit('workzone.refresh');
}
} else {
alert(data.message);
}
return;
}
});
}
return {initialize};
};
export default archiveBasket;

View File

@@ -0,0 +1,276 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
require('./../../phraseanet-common/components/tooltip');
import merge from 'lodash.merge';
const humane = require('humane-js');
const basketBrowse = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const initialize = () => {
$('body').on('click', '.basket-browse-action', (event) => {
event.preventDefault();
const $el = $(event.currentTarget);
let dialogOptions = {};
if ($el.attr('title') !== undefined) {
dialogOptions.title = $el.attr('title');
dialogOptions.width = 920;
}
openModal(dialogOptions);
});
};
const openModal = (options = {}) => {
let dialogOptions = merge({
size: 'Medium',
loading: false
}, options);
const $dialog = dialog.create(services, dialogOptions);
return $.get(`${url}prod/WorkZone/Browse/`, function (data) {
$dialog.setContent(data);
_onDialogReady();
return;
});
};
const _onDialogReady = () => {
const $container = $('#BasketBrowser');
let results = null;
function loadResults(datas, url) {
let $results = $('.results', $container);
results = $.ajax({
type: 'GET',
url: url,
dataType: 'html',
data: datas,
beforeSend: function () {
if (results && results.abort && typeof results.abort === 'function') {
results.abort();
}
$results.addClass('loading').empty();
},
error: function () {
$results.removeClass('loading');
},
timeout: function () {
$results.removeClass('loading');
},
success: function (data) {
$results.removeClass('loading').append(data);
activateLinks($results);
active_archiver($results);
return;
}
});
}
function loadBasket(url) {
results = $.ajax({
type: 'GET',
url,
dataType: 'html',
beforeSend: function () {
if (results && results.abort && typeof results.abort === 'function') {
results.abort();
}
$('.Browser', $container).hide();
$('.Basket', $container).addClass('loading').empty().show();
},
error: function () {
$('.Browser', $container).show();
$('.Basket', $container).removeClass('loading').hide();
},
timeout: function () {
$('.Browser', $container).show();
$('.Basket', $container).removeClass('loading').hide();
},
success: function (data) {
$('.Basket', $container).removeClass('loading').append(data);
$('.Basket a.back', $container).bind('click', function () {
$('.Basket', $container).hide();
$('.Browser', $container).show();
return false;
});
active_archiver($('.Basket', $container));
return;
}
});
}
function activateLinks($scope) {
let confirmBox = {};
let buttons = {};
$('a.result', $scope).bind('click', function (event) {
event.preventDefault();
var $this = $(this);
loadResults({}, $this.attr('href'));
return false;
});
$('.result_page').bind('click', function (event) {
event.preventDefault();
var $this = $(this);
loadResults({}, $this.attr('href'));
return false;
});
$('a.basket_link', $scope).bind('click', function (event) {
event.preventDefault();
var $this = $(this);
loadBasket($this.attr('href'));
return false;
});
$('a.delete-basket', $scope).bind('click', function (event) {
event.preventDefault();
var $this = $(this);
var buttons = {};
buttons[localeService.t('valider')] = function () {
$.ajax({
type: 'POST',
dataType: 'json',
url: $this.attr('href'),
data: {},
success: function (datas) {
if (datas.success) {
confirmBox.close();
$('form[name="BasketBrowser"]', $container).trigger('submit');
appEvents.emit('workzone.refresh');
} else {
confirmBox.close();
var alertBox = dialog.create(services, {
size: 'Alert',
closeOnEscape: true,
closeButton: true
}, 2);
alertBox.setContent(datas.message);
}
},
error: function () {
confirmBox.close();
var alertBox = dialog.create(services, {
size: 'Alert',
closeOnEscape: true,
closeButton: true
}, 2);
alertBox.setContent("{{'Something wrong happened, please retry or contact an admin.'|trans|e('js') }}");
}
});
};
confirmBox = dialog.create(services, {
size: 'Alert',
closeOnEscape: true,
cancelButton: true,
buttons: buttons
}, 2);
confirmBox.setContent("{{'You are about to delete this basket. Would you like to continue ?'|trans|e('js') }}");
return false;
});
}
function active_archiver($scope) {
$('a.UserTips', $scope).bind('click', function () {
return false;
}).tooltip();
$('.infoTips, .previewTips', $scope).tooltip();
$('a.archive_toggler', $scope).bind('click', function (event) {
event.preventDefault();
const $this = $(this);
const parent = $this.parent();
$.ajax({
type: 'POST',
url: $this.attr('href'),
dataType: 'json',
beforeSend: function () {
$('.loader', parent).show();
$('.archive_toggler:visible', parent).addClass('last_act').hide();
},
error: function () {
$('.loader', parent).hide();
$('.last_act', parent).removeClass('last_act').show();
},
timeout: function () {
$('.loader', parent).hide();
$('.last_act', parent).removeClass('last_act').show();
},
success: function (data) {
$('.loader', parent).hide();
$('.last_act', parent).removeClass('last_act');
if (!data.success) {
humane.error(data.message);
return;
}
if (data.archive === true) {
$('.unarchiver', parent).show();
$('.archiver', parent).hide();
$($this).closest('.result').removeClass('unarchived');
} else {
$('.unarchiver', parent).hide();
$('.archiver', parent).show();
$($this).closest('.result').addClass('unarchived');
}
appEvents.emit('workzone.refresh');
return;
}
});
return false;
});
}
$('form[name="BasketBrowser"]', $container).bind('submit', function () {
let $this = $(this);
loadResults($this.serializeArray(), $this.attr('action'));
return false;
}).trigger('submit').find('label').bind('click', function () {
const input = $(this).prev('input');
let inputs = $('input[name="' + $(this).prev('input').attr('name') + '"]', $container);
inputs.prop('checked', false).next('label').removeClass('selected');
input.prop('checked', true).next('label').addClass('selected');
$('form[name="BasketBrowser"]', $container).trigger('submit');
});
};
return {initialize};
};
export default basketBrowse;

View File

@@ -0,0 +1,101 @@
/**
* triggered via workzone > Basket > context menu
*/
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
import merge from 'lodash.merge';
const basketCreate = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
let searchSelectionSerialized = '';
appEvents.listenAll({
'broadcast.searchResultSelection': (selection) => {
searchSelectionSerialized = selection.serialized;
}
});
const initialize = () => {
$('body').on('click', '.basket-create-action', (event) => {
event.preventDefault();
const $el = $(event.currentTarget);
let dialogOptions = {};
if ($el.attr('title') !== undefined) {
dialogOptions.title = $el.attr('title');
}
openModal(dialogOptions);
});
};
const openModal = (options = {}) => {
let dialogOptions = merge({
size: 'Small',
loading: false
}, options);
const $dialog = dialog.create(services, dialogOptions);
return $.get(`${url}prod/baskets/create/`, function (data) {
$dialog.setContent(data);
_onDialogReady();
return;
});
};
const _onDialogReady = () => {
// recordBridge(services).initialize();
var $dialog = dialog.get(1);
var $dialogBox = $dialog.getDomElement();
$('input[name="lst"]', $dialogBox).val(searchSelectionSerialized);
var buttons = $dialog.getOption('buttons');
buttons[localeService.t('create')] = function () {
$('form', $dialogBox).trigger('submit');
};
$dialog.setOption('buttons', buttons);
$('form', $dialogBox).bind('submit', function (event) {
var $form = $(this);
var $dialog = $dialogBox.closest('.ui-dialog');
var buttonPanel = $dialog.find('.ui-dialog-buttonpane');
// @TODO should be in a service:
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
data: $form.serializeArray(),
dataType: 'json',
beforeSend: function () {
$(":button:contains('" + localeService.t('create') + "')", buttonPanel)
.attr('disabled', true).addClass('ui-state-disabled');
},
success: function (data) {
appEvents.emit('workzone.refresh', {
basketId: data.basket.id
});
dialog.close(1);
return;
},
error: function () {
$(":button:contains('" + localeService.t('create ') + "')", buttonPanel)
.attr('disabled', false).removeClass('ui-state-disabled');
},
timeout: function () {
}
});
return false;
});
};
return {initialize};
};
export default basketCreate;

View File

@@ -0,0 +1,122 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
const deleteBasket = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
let $container = null;
const initialize = () => {
$container = $('body');
$container.on('click', '.basket-delete-action', function (event) {
event.preventDefault();
let $el = $(event.currentTarget);
deleteConfirmation($el, $el.data('context'));
});
};
const deleteConfirmation = ($el, type) => {
switch (type) {
/*case 'IMGT':
case 'CHIM':
var lst = '';
if (type === 'IMGT') {
lst = p4.Results.Selection.serialize();
}
if (type === 'CHIM') {
lst = p4.WorkZone.Selection.serialize();
}
_deleteRecords(lst);
break;
*/
case 'SSTT':
var buttons = {};
buttons[localeService.t('valider')] = function (e) {
_deleteBasket($el);
};
$('#DIALOG').empty().append(localeService.t('confirmDel')).attr('title', localeService.t('attention')).dialog({
autoOpen: false,
resizable: false,
modal: true,
draggable: false
}).dialog('open').dialog('option', 'buttons', buttons);
$('#tooltip').hide();
break;
/*case 'STORY':
lst = $el.val();
_deleteRecords(lst);
break;*/
default:
}
};
const _deleteBasket = (item) => {
if ($('#DIALOG').data('ui-dialog')) {
$('#DIALOG').dialog('destroy');
}
// id de chutier
var k = $(item).attr('id').split('_').slice(1, 2).pop();
$.ajax({
type: 'POST',
url: `${url}prod/baskets/${k}/delete/`,
dataType: 'json',
success: function (data) {
if (data.success) {
var basket = $('#SSTT_' + k);
var next = basket.next();
if (next.data('ui-droppable')) {
next.droppable('destroy');
}
next.slideUp().remove();
if (basket.data('ui-droppable')) {
basket.droppable('destroy');
}
basket.slideUp().remove();
if ($('#baskets .SSTT').length === 0) {
appEvents.emit('workzone.refresh');
}
} else {
alert(data.message);
}
return;
}
});
};
/*const _deleteRecords = (lst) => {
if (lst.split(';').length === 0) {
alert(localeService.t('nodocselected'));
return false;
}
let $dialog = dialog.create(services, {
size: 'Small',
title: localeService.t('deleteRecords')
});
$.ajax({
type: 'POST',
url: '../prod/records/delete/what/',
dataType: 'html',
data: {lst: lst},
success: function (data) {
$dialog.setContent(data);
}
});
return false;
};*/
return {initialize, deleteConfirmation};
};
export default deleteBasket;

View File

@@ -0,0 +1,40 @@
import $ from 'jquery';
import ui from '../ui';
import notify from '../notify';
const basket = () => {
const onUpdatedContent = (data) => {
if (data.changed.length > 0) {
let current_open = $('.SSTT.ui-state-active');
let main_open = false;
for (let i = 0; i !== data.changed.length; i++) {
var sstt = $('#SSTT_' + data.changed[i]);
if (sstt.size() === 0) {
if (main_open === false) {
$('#baskets .bloc').animate({top: 30}, function () {
$('#baskets .alert_datas_changed:first').show();
});
main_open = true;
}
} else {
if (!sstt.hasClass('active')) {
sstt.addClass('unread');
} else {
$('.alert_datas_changed', $('#SSTT_content_' + data.changed[i])).show();
}
}
}
}
};
const subscribeToEvents = {
'notification.refresh': onUpdatedContent
};
return {subscribeToEvents};
};
export default basket;

View File

@@ -0,0 +1,259 @@
/**
* triggered via workzone > Basket > context menu
*/
import $ from 'jquery';
import * as _ from 'underscore';
import dialog from './../../phraseanet-common/components/dialog';
import Selectable from '../utils/selectable';
import merge from 'lodash.merge';
const basketReorderContent = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
let searchSelectionSerialized = '';
appEvents.listenAll({
'broadcast.searchResultSelection': (selection) => {
searchSelectionSerialized = selection.serialized;
}
});
const initialize = () => {
$('body').on('click', '.basket-reorder-content-action', (event) => {
event.preventDefault();
const $el = $(event.currentTarget);
let dialogOptions = {};
if ($el.attr('title') !== undefined) {
dialogOptions.title = $el.attr('title');
}
openModal($el.data('basket-id'), dialogOptions);
});
};
const openModal = (basketId, options = {}) => {
let dialogOptions = merge({
size: 'Medium',
loading: false
}, options);
const $dialog = dialog.create(services, dialogOptions);
return $.get(`${url}prod/baskets/${basketId}/reorder/`, function (data) {
$dialog.setContent(data);
_onDialogReady();
return;
});
};
const _onDialogReady = () => {
var container = $('#reorder_box');
$('button.autoorder', container).bind('click', function () {
autoorder();
return false;
});
$('button.reverseorder', container).bind('click', function () {
reverse_order();
return false;
});
function autoorder() {
var val = $.trim($('#auto_order').val());
if (val === '') {
return;
}
var diapos = [];
$('#reorder_box .diapo form').each(function (i, n) {
diapos.push({
title: $('input[name=title]', n).val(),
order: parseInt($('input[name=default]', n).val(), 10),
id: $('input[name=id]', n).val(),
date_created: new Date($('input[name=date_created]', n).val()),
date_updated: new Date($('input[name=date_updated]', n).val()),
});
});
var elements = [];
var sorterCallback;
if (val === 'default') {
sorterCallback = function (diapo) {
return diapo.order;
};
elements = sorting(sorterCallback, diapos, false);
} else if(val === 'date_updated' || val === 'date_created'){
sorterCallback = function(diapo) {
if(val === 'date_created') {
return diapo.date_created;
}
return diapo.date_updated;
};
elements = sorting(sorterCallback, diapos, true);
} else {
sorterCallback = function(diapo) {return diapo.title.toLowerCase();};
elements = sorting(sorterCallback, diapos, false);
}
$('#reorder_box .elements').append(elements);
}
function sorting(sorterCallback, diapos, reverse) {
var elements = [];
if(reverse == true) {
_.chain(diapos)
.sortBy(sorterCallback)
.reverse()
.each(function(diapo) {
elements.push($('#ORDER_'+ diapo.id));
});
}else {
_.chain(diapos)
.sortBy(sorterCallback)
.each(function(diapo) {
elements.push($('#ORDER_'+ diapo.id));
});
}
return elements;
}
function reverse_order() {
var $container = $('#reorder_box .elements');
$('#reorder_box .diapo').each(function () {
$(this).prependTo($container);
});
}
('.elements div', container).bind('click', function(){
$(this).addClass("selected").siblings().removeClass("selected");
return false;
});
$('.elements', container).sortable({
appendTo: container,
placeholder: 'diapo ui-sortable-placeholder',
distance: 20,
cursorAt: {
top: 10,
left: -20
},
items: 'div.diapo',
scroll: true,
scrollSensitivity: 40,
scrollSpeed: 30,
start: function (event, ui) {
var selected = $('.selected', container);
selected.each(function (i, n) {
$(n).attr('position', i);
});
var n = selected.length - 1;
$('.selected:visible', container).hide();
while (n > 0) {
$('<div style="height:130px;" class="diapo ui-sortable-placeholderfollow"></div>').after($('.diapo.ui-sortable-placeholder', container));
n--;
}
},
stop: function (event, ui) {
$('.diapo.ui-sortable-placeholderfollow', container).remove();
let main_id = $(ui.item[0]).attr('id');
let selected = $('.selected', container);
let sorter = [];
selected.each(function (i, n) {
var position = parseInt($(n).attr('position'), 10);
if (position !== '') {
sorter[position] = $(n);
}
var id = $(n).attr('id');
if (id === main_id) {
return;
}
});
var before = true;
var last_moved = $(ui.item[0]);
$(sorter).each(function (i, n) {
$(n).show().removeAttr('position');
if ($(n).attr('id') === main_id) {
before = false;
} else {
if (before) {
$(n).before($(ui.item[0]));
} else {
$(n).after($(last_moved));
}
}
last_moved = sorter[i];
});
},
change: function () {
$('.diapo.ui-sortable-placeholderfollow', container).remove();
var n = OrderSelection.length() - 1;
while (n > 0) {
$('<div style="height:130px;" class="diapo ui-sortable-placeholderfollow"></div>').after($('.diapo.ui-sortable-placeholder', container));
n--;
}
}
}).disableSelection();
var OrderSelection = new Selectable(services, $('.elements', container), {
selector: '.CHIM'
});
$('form[name="reorder"] .btn').bind('click', function (event) {
//$this.SetLoader(true);
var $form =$(this).closest('form');
$('.elements form', container).each(function (i, el) {
var id = $('input[name="id"]', $(el)).val();
$('input[name="element[' + id + ']"]', $form).val(i + 1);
});
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
data: $form.serializeArray(),
dataType: 'json',
beforeSend: function () {
},
success: function (data) {
if (!data.success) {
alert(data.message);
}
appEvents.emit('workzone.refresh', {
basketId: 'current'
});
dialog.get(1).close();
return;
}
});
return false;
});
};
return {initialize};
};
export default basketReorderContent;

View File

@@ -0,0 +1,91 @@
/**
* triggered via workzone > Basket > context menu
*/
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
import merge from 'lodash.merge';
const humane = require('humane-js');
const basketUpdate = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
let basketId = false;
let searchSelectionSerialized = '';
appEvents.listenAll({
'broadcast.searchResultSelection': (selection) => {
searchSelectionSerialized = selection.serialized;
}
});
const initialize = () => {
$('body').on('click', '.basket-update-action', (event) => {
event.preventDefault();
const $el = $(event.currentTarget);
let dialogOptions = {};
if ($el.attr('title') !== undefined) {
dialogOptions.title = $el.attr('title');
}
basketId = $el.data('basket-id');
openModal(dialogOptions);
});
};
const openModal = (options = {}) => {
let dialogOptions = merge({
size: 'Medium',
loading: false
}, options);
const $dialog = dialog.create(services, dialogOptions);
return $.get(`${url}prod/baskets/${basketId}/update/`, (data) => {
$dialog.setContent(data);
_onDialogReady();
return;
});
};
const _onDialogReady = () => {
$('form[name="basket-rename-box"]').on('submit', function (event) {
event.preventDefault();
onSubmitRenameForm(event);
});
$('#basket-rename-box button').on('click', function (event) {
event.preventDefault();
onSubmitRenameForm(event);
});
var onSubmitRenameForm = function (event) {
var $form = $(event.currentTarget).closest('form');
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
dataType: 'json',
data: $form.serializeArray(),
beforeSend: function () {
},
success: function (data) {
dialog.get(1).close();
if (data.success) {
humane.info(data.message);
appEvents.emit('workzone.refresh', {
basketId: basketId
});
} else {
humane.error(data.message);
return false;
}
}
});
return false;
};
};
return {initialize};
};
export default basketUpdate;

View File

@@ -0,0 +1,62 @@
import $ from 'jquery';
import * as appCommons from './../../phraseanet-common';
const humane = require('humane-js');
const cgu = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const initialize = (options = {}) => {
const { $container } = options;
var $this = $('.cgu-dialog:first');
$this.dialog({
autoOpen: true,
closeOnEscape: false,
draggable: false,
modal: true,
resizable: false,
width: 800,
height: 500,
open: function () {
$this.parents('.ui-dialog:first').find('.ui-dialog-titlebar-close').remove();
$('.cgus-accept', $(this)).bind('click', function () {
acceptCgus($('.cgus-accept', $this).attr('id'), $('.cgus-accept', $this).attr('date'));
$this.dialog('close').remove();
initialize(services, options);
});
$('.cgus-cancel', $(this)).bind('click', function () {
if (confirm(localeService.t('warningDenyCgus'))) {
cancelCgus($('.cgus-cancel', $this).attr('id').split('_').pop());
}
});
}
});
};
function acceptCgus(name, value) {
appCommons.userModule.setPref(name, value);
}
function cancelCgus(id) {
$.ajax({
type: 'POST',
url: `${url}prod/TOU/deny/${id}/`,
dataType: 'json',
success: function (data) {
if (data.success) {
alert(localeService.t('cgusRelog'));
self.location.replace(self.location.href);
} else {
humane.error(data.message);
}
}
});
}
return {
initialize
};
};
export default cgu;

View File

@@ -0,0 +1,91 @@
let instance = null;
import * as _ from 'underscore';
export default class ApplicationConfigService {
configuration;
constructor(config) {
// if( !instance ) {
// instance = this;
// }
this.configuration = config;
// return instance;
}
get(configKey) {
if (configKey !== undefined) {
var foundValue = this._findKeyValue(configKey || this.configuration);
switch (typeof foundValue) {
case 'string':
return foundValue;
default:
return foundValue ? foundValue : null;
}
}
return this.configuration;
}
set(configKey, value) {
if (configKey !== undefined) {
if (typeof this.configuration[configKey] === 'object') {
// merge
this.configuration[configKey] = _.extend({}, this.configuration[configKey], value);
} else {
this.configuration[configKey] = value;
}
}
}
// @TODO cast
_findKeyValue(configName) {
if (!configName) {
return undefined;
}
let isStr = _.isString(configName);
let name = isStr ? configName : configName.name;
let path = configName.indexOf('.') > 0 ? true : false;
if (path) {
return this._search(this.configuration, name);
}
var state = this.configuration[name];
if (state && (isStr || (!isStr && state === configName))) {
return state;
} else if (isStr) {
return state;
}
return undefined;
}
// @TODO cast
_search(obj, path) {
if (_.isNumber(path)) {
path = [path];
}
if (_.isEmpty(path)) {
return obj;
}
if (_.isEmpty(obj)) {
return null;
}
if (_.isString(path)) {
return this._search(obj, path.split('.'));
}
var currentPath = path[0];
if (path.length === 1) {
if (obj[currentPath] === void 0) {
return null;
}
return obj[currentPath];
}
return this._search(obj[currentPath], path.slice(1));
}
}

View File

@@ -0,0 +1,17 @@
import ApplicationConfigService from './applicationConfigService';
let instance = null;
class ConfigService extends ApplicationConfigService {
constructor(configuration) {
super(configuration);
if (!instance) {
instance = this;
}
return instance;
}
}
export default ConfigService;

View File

@@ -0,0 +1,56 @@
import * as Rx from 'rx';
var hasOwnProp = {}.hasOwnProperty;
function createName(name) {
return '$' + name;
}
let Emitter = function () {
this.subjects = {};
};
Emitter.prototype.emit = function (name, data) {
var fnName = createName(name);
this.subjects[fnName] || (this.subjects[fnName] = new Rx.Subject());
this.subjects[fnName].onNext(data);
return this.subjects[fnName];
};
Emitter.prototype.listen = function (name, handler) {
var fnName = createName(name);
this.subjects[fnName] || (this.subjects[fnName] = new Rx.Subject());
return this.subjects[fnName].subscribe(handler);
};
Emitter.prototype.listenAll = function (group, name, handler) {
for (let prop in group) {
var fnName = createName(prop);
this.subjects[fnName] || (this.subjects[fnName] = new Rx.Subject());
this.subjects[fnName].subscribe(group[prop]);
}
};
Emitter.prototype.disposeOf = function (startWith) {
var search = new RegExp('^\\$' + startWith);
var subjects = this.subjects;
for (let prop in subjects) {
if (hasOwnProp.call(subjects, prop)) {
if (search.test(prop)) {
subjects[prop].dispose();
}
}
}
this.subjects = {};
};
Emitter.prototype.dispose = function () {
var subjects = this.subjects;
for (let prop in subjects) {
if (hasOwnProp.call(subjects, prop)) {
subjects[prop].dispose();
}
}
this.subjects = {};
};
export default Emitter;

View File

@@ -0,0 +1,155 @@
import _ from 'underscore';
/**
* Set a provider
*
*/
const provider = (services) => {
const {configService, localeService, eventEmitter} = services;
let accessToken;
let defaultPosition;
let defaultZoom;
let markerDefaultZoom;
let activeProvider;
let fieldPosition;
let defaultMapProvider;
let transitionOptions = Object.create(null);
let mapLayers = [{name: 'streets', value: 'mapbox://styles/mapbox/streets-v9'}];
const initialize = () => {
let isValid = false;
// select geocoding provider:
let geocodingProviders = configService.get('geocodingProviders');
_.each(geocodingProviders, (provider) => {
if (provider.enabled === true) {
activeProvider = provider;
accessToken = provider['public-key'];
let fieldMapping = provider['position-fields'] !== undefined ? provider['position-fields'] : [];
fieldPosition = {};
if (fieldMapping.length > 0) {
_.each(fieldMapping, (mapping) => {
// latitude and longitude are combined in a composite field
if (mapping.type === 'latlng') {
fieldPosition = {
latitude: (poi) => extractFromPosition('lat', poi[mapping.name]),
longitude: (poi) => extractFromPosition('lon', poi[mapping.name])
};
} else if (mapping.type === 'lat') {
// if latitude field mapping is provided, fallback:
fieldPosition.latitude = (poi) => isNaN(parseFloat(poi[mapping.name], 10)) ? false : parseFloat(poi[mapping.name], 10);
} else if (mapping.type === 'lon') {
// if longitude field mapping is provided, fallback:
fieldPosition.longitude = (poi) => isNaN(parseFloat(poi[mapping.name], 10)) ? false : parseFloat(poi[mapping.name], 10);
}
});
if (fieldPosition.latitude !== undefined && fieldPosition.longitude !== undefined) {
isValid = true;
}
} else {
fieldPosition = {
latitude: (poi) => getCoordinatesFromTechnicalInfo(poi, 'lat'),
longitude: (poi) => getCoordinatesFromTechnicalInfo(poi, 'lng')
};
isValid = true;
}
// set default values:
var defaultPositionValue = $('#map-position-from-setting').val();
if(defaultPositionValue != '') {
defaultPositionValue = defaultPositionValue.split('"');
var arr = [];
arr.push(defaultPositionValue[1]);
arr.push(defaultPositionValue[3]);
defaultPosition = arr ;
} else {
defaultPosition = provider['default-position'];
}
defaultZoom = $('#map-zoom-from-setting').val()!='' ? $('#map-zoom-from-setting').val() : provider['default-zoom'] || 2;
markerDefaultZoom = provider['marker-default-zoom'] || 12;
defaultMapProvider = provider['map-provider'] || "mapboxWebGL";
if (provider['map-layers'] && provider['map-layers'].length > 0) {
//update map layer;
mapLayers = provider['map-layers'];
}
if (provider['transition-mapboxgl'] !== undefined) {
var options = provider['transition-mapboxgl'][0] || [];
transitionOptions.animate = options['animate'] !== undefined ? options['animate'] : true;
transitionOptions.speed = options['speed'] || 1.2;
transitionOptions.curve = options['curve'] || 1.42;
}
}
});
if (accessToken === undefined) {
isValid = false;
}
return isValid;
}
const getCoordinatesFromTechnicalInfo = (poi, fieldMapping) => {
if (poi["technicalInfo"] !== undefined) {
if (fieldMapping == 'lat') {
return isNaN(parseFloat(poi["technicalInfo"].latitude, 10)) ? false : parseFloat(poi["technicalInfo"].latitude, 10)
} else {
return isNaN(parseFloat(poi["technicalInfo"].longitude, 10)) ? false : parseFloat(poi["technicalInfo"].longitude, 10)
}
}
return false;
}
/**
* extract latitude or longitude from a position
* @param name
* @param source
* @returns {*}
*/
const extractFromPosition = (name, source) => {
if (source === undefined || source === null) {
return false;
}
let position = source.split(' ');
if (position.length !== 2) {
position = source.split(',');
}
// ok parse lat
if (position.length === 2) {
if (name === 'lat' || name === 'latitude') {
return parseFloat(position[0])
}
return parseFloat(position[1])
} else {
// invalid
return false;
}
};
const getConfiguration = () => {
return {
defaultPosition,
defaultZoom,
markerDefaultZoom,
fieldPosition,
accessToken,
defaultMapProvider,
mapLayers,
provider: activeProvider,
transitionOptions
}
};
return {
initialize, getConfiguration
}
}
export default provider;

View File

@@ -0,0 +1,97 @@
const leafletLocaleFr = {
draw: {
toolbar: {
actions: {
title: 'Annulez le dessin',
text: 'Annuler'
},
finish: {
title: 'Terminer le dessin',
text: 'Terminer'
},
undo: {
title: 'Supprimer le dernier point',
text: 'Supprimer le dernier point'
},
buttons: {
polyline: 'Dessiner une polyligne',
polygon: 'Dessiner un polygone',
rectangle: 'Dessiner un rectangle',
circle: 'Dessiner un cercle',
marker: 'Dessiner un marqueur'
}
},
handlers: {
circle: {
tooltip: {
start: 'Cliquez et déplacez pour dessiner un cercle.'
}
},
marker: {
tooltip: {
start: 'Cliquez sur la carte pour placer un marqueur.'
}
},
polygon: {
tooltip: {
start: 'Cliquez pour commencer à dessiner une forme.',
cont: 'Cliquez pour continuer à dessiner une forme.',
end: 'Cliquez sur le dernier point pour fermer cette forme.'
}
},
polyline: {
error: '<strong>Erreur:</strong> Les arrêtes de la forme ne doivent pas se croiser!',
tooltip: {
start: 'Cliquez pour commencer à dessiner d\'une ligne.',
cont: 'Cliquez pour continuer à dessiner une ligne.',
end: 'Cliquez sur le dernier point pour terminer la ligne.'
}
},
rectangle: {
tooltip: {
start: 'Cliquez et déplacez pour dessiner un rectangle.'
}
},
simpleshape: {
tooltip: {
end: 'Relachez la souris pour finir de dessiner.'
}
}
}
},
edit: {
toolbar: {
actions: {
save: {
title: 'Sauvegardez les changements.',
text: 'Sauver'
},
cancel: {
title: 'Annulez l\'édition, ignorer tous les changements.',
text: 'Annuler'
}
},
buttons: {
edit: 'Editer les couches.',
editDisabled: 'Pas de couches à éditer.',
remove: 'Supprimer les couches.',
removeDisabled: 'Pas de couches à supprimer.'
}
},
handlers: {
edit: {
tooltip: {
text: 'Déplacez les ancres, ou le marqueur pour éditer l\'objet.',
subtext: 'Cliquez sur Annuler pour revenir sur les changements.'
}
},
remove: {
tooltip: {
text: 'Cliquez sur l\'objet à enlever'
}
}
}
}
};
export default leafletLocaleFr;

View File

@@ -0,0 +1,279 @@
.ui-widget-content .leaflet-popup-content {
color: #555555;
}
.mapbox-logo {
display: none;
}
.phrasea-popup .leaflet-popup-content-wrapper {
background: #3b3b3b;
color: #fff;
font-size: 16px;
line-height: 24px;
border-radius: 3px;
}
.phrasea-popup .leaflet-popup-content-wrapper a {
color: rgba(255, 255, 255, 0.5);
}
.phrasea-popup .leaflet-popup-tip-container {
width: 30px;
height: 15px;
}
.phrasea-popup .leaflet-popup-content p {
color: #FFF;
}
.phrasea-popup .leaflet-popup-content p.help {
text-align: center;
font-style: italic;
}
.phrasea-popup .leaflet-popup-tip {
border-top: 10px solid #3b3b3b;
}
.updated-position {
text-align: center;
}
.ui-widget-content .leaflet-container {
color: #555555;
}
.ui-widget-content .leaflet-container label {
color: #555555;
display: block;
font-size: 12px;
padding: 0 15px;
}
.ui-widget-content .leaflet-container form {
margin: 10px 0 0 0;
}
.ui-widget-content .leaflet-container input[type="radio"] {
margin: -4px 0 0 0;
padding: 0;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-mapbox-geocoder .leaflet-control-mapbox-geocoder-form input {
box-shadow: none;
font-size: 12px;
}
.ui-widget-content .leaflet-container form {
margin-top: 0;
}
.mapboxgl-popup-content {
background: #555555;
width: 200px;
font-size: 15px;
}
.mapboxgl-popup-anchor-top .mapboxgl-popup-tip {
border-bottom-color: #555555;
}
.mapboxgl-popup-anchor-top-left .mapboxgl-popup-tip {
border-bottom-color: #555555;
}
.mapboxgl-popup-anchor-top-right .mapboxgl-popup-tip {
border-bottom-color: #555555;
}
.mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip {
border-top-color: #555555;
}
.mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-tip {
border-top-color: #555555;
}
.mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-tip {
border-top-color: #555555;
}
.mapboxgl-popup-anchor-left .mapboxgl-popup-tip {
border-right-color: #555555;
}
.mapboxgl-popup-anchor-right .mapboxgl-popup-tip {
border-left-color: #555555;
}
.map-selection-container {
position: absolute;
width: 30px;
height: 30px;
top: 130px;
right: 10px;
border-radius: 5px;
border: 2px solid #ccc;
background-color: #fff;
cursor: pointer;
box-sizing: border-box;
}
.map-selection-container:hover {
background-color: #eee;
}
.map-dropdown-content {
display: none;
min-width: 80px;
position: absolute;
right: 0;
background: #FFF;
padding: 10px;
border: 1px solid #ccc;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.map-dropdown-content label {
color: #555555;
display: block;
font-size: 13px;
}
.map-drop-btn {
background: transparent;
width: 100%;
height: 100%;
box-sizing: border-box;
border: none;
margin: 0;
padding: 0;
}
.map-drop-btn i {
padding: 6px;
margin: 0;
}
.circle-control-container {
position: absolute;
top: 170px;
right: 10px;
}
#map-notice-btn {
position: absolute;
top: 6px;
left: 6px;
background: transparent;
cursor: pointer;
border: none;
width: 30px;
height: 30px;
margin: 0;
padding: 0;
display: none;
}
#map-notice-btn:focus {
outline: 0;
}
#notice-box {
display: block;
position: absolute;
top: 6px;
left: 6px;
width: 305px;
border-radius: 6px;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
background-color: #ffffff;
border: solid 1px #8f8f8f;
padding: 4px 5px 5px 6px;
}
.notice-header {
display: block;
}
.notice-title {
font-family: Roboto;
font-size: 15px;
font-weight: 500;
letter-spacing: 0px;
color: #3e3d3d;
margin-left: 6px;
line-height: 20px;
vertical-align: middle;
margin-right: 20px;
}
.notice-desc {
display: block;
font-family: Roboto;
font-size: 12px;
line-height: 1.17;
letter-spacing: 0px;
color: #3e3d3d;
margin: 6px 10px 0px 10px;
}
.notice-close-btn {
position: absolute;
top: 0px;
right: 2px;
font-family: Roboto;
font-size: 16px;
color: #3e3d3d;
cursor: pointer;
padding: 4px;
}
.draw-icon {
margin-bottom: 5px;
padding: 0;
position: relative;
border-radius: 5px;
border: 2px solid #ccc;
background-color: #fff;
cursor: pointer;
box-sizing: border-box;
display: block;
}
.draw-icon:hover {
background-color: rgba(0, 0, 0, 0.05);
}
.draw-icon.selected {
background-color: #aaa;
}
.draw-icon i {
font-size: 20px;
line-height: 26px;
}
.map-dropdown-content label input[type="radio"] {
margin: 0px 0 0 0;
padding: 0;
}
.map-dropdown-content.show {
display: block;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,122 @@
import $ from 'jquery';
const markerCollection = (services) => {
const {configService, localeService, eventEmitter} = services;
let markerCollection = {};
let cachedGeoJson;
let featureLayer;
let map;
let geoJsonPoiCollection;
let editable;
const initialize = (params) => {
let initWith = {map, featureLayer, geoJsonPoiCollection} = params;
editable = params.editable || false;
setCollection(geoJsonPoiCollection)
};
const setCollection = (geoJsonPoiCollection) => {
featureLayer.setGeoJSON(geoJsonPoiCollection);
cachedGeoJson = featureLayer.getGeoJSON();
featureLayer.eachLayer(function (layer) {
setMarkerPopup(layer);
});
};
const triggerRefresh = () => {
setCollection(cachedGeoJson);
cachedGeoJson = featureLayer.getGeoJSON();
};
const setMarkerPopup = (marker) => {
switch (marker.feature.geometry.type) {
case 'Polygon':
break;
case 'Point':
setPoint(marker);
break;
default:
}
};
const setPoint = (marker) => {
markerCollection[marker._leaflet_id] = marker;
let $content = $('<div style="min-width: 200px"/>');
let template = `<p>${marker.feature.properties.title}</p> `;
if (editable === true && marker.dragging !== undefined) {
template += `
<div class="view-mode">
<button class="edit-position btn btn-inverse btn-small btn-block" data-marker-id="${marker._leaflet_id}">${localeService.t('mapMarkerEdit')}</button>
</div>
<div class="edit-mode">
<p class="help">${localeService.t('mapMarkerMoveLabel')}</p>
<p><span class="updated-position"></span></p>
<div>
<button class="cancel-position btn btn-inverse btn-small btn-block" data-marker-id="${marker._leaflet_id}">${localeService.t('mapMarkerEditCancel')}</button>
<button class="submit-position btn btn-inverse btn-small btn-block" data-marker-id="${marker._leaflet_id}">${localeService.t('mapMarkerEditSubmit')}</button>
</div>
</div>`;
}
$content.append(template);
$content.find('.edit-mode').hide();
$content.on('click', '.edit-position', (event) => {
let $el = $(event.currentTarget);
let marker = getMarker($el.data('marker-id'));
marker._originalPosition = marker.getLatLng().wrap();
marker.dragging.enable();
$content.find('.view-mode').hide();
$content.find('.edit-mode').show();
$content.find('.help').show();
});
$content.on('click', '.submit-position', (event) => {
let $el = $(event.currentTarget);
let marker = getMarker($el.data('marker-id'));
marker.dragging.disable();
$content.find('.view-mode').show();
$content.find('.help').hide();
$content.find('.edit-mode').hide();
marker._originalPosition = marker.getLatLng().wrap();
eventEmitter.emit('markerChange', {marker, position: marker.getLatLng().wrap()});
});
$content.on('click', '.cancel-position', (event) => {
let $el = $(event.currentTarget);
let marker = getMarker($el.data('marker-id'));
marker.dragging.disable();
$content.find('.view-mode').show();
marker.setLatLng(marker._originalPosition);
triggerRefresh();
});
marker.bindPopup($content.get(0));
marker.on('dragend', () => {
let position = marker.getLatLng().wrap();
$content.find('.updated-position').html(`${position.lat}<br>${position.lng}`);
$content.find('.edit-mode').show();
marker.bindPopup($content.get(0));
marker.openPopup();
})
}
const getMarker = (markerId) => {
return markerCollection[markerId];
}
return {
initialize, setCollection
}
}
export default markerCollection;

View File

@@ -0,0 +1,231 @@
import $ from 'jquery';
let mapboxgl = require('mapbox-gl');
const markerGLCollection = (services) => {
const {configService, localeService, eventEmitter} = services;
let markerCollection = {};
let cachedGeoJson;
let map;
let geojson;
let editable;
let isDraggable = false;
let isCursorOverPoint = false;
let isDragging = false;
let popup = {};
let popupDialog;
const initialize = (params) => {
let initWith = {map, geojson} = params;
editable = params.editable || false;
setCollection(geojson)
};
const setCollection = (geojson) => {
cachedGeoJson = geojson;
geojson.features.forEach(function (marker) {
setMarkerPopup(marker);
});
};
const setMarkerPopup = (marker) => {
switch (marker.geometry.type) {
case 'Polygon':
break;
case 'Point':
setPoint(marker);
break;
default:
}
};
const setPoint = (marker) => {
let $content = $('<div style="min-width: 200px"/>');
let template = `<p>${marker.properties.title}</p> `;
if (editable === true) {
template += `
<div class="view-mode">
<button class="edit-position btn btn-inverse btn-small btn-block" data-marker-id="${marker.properties.recordIndex}">${localeService.t('mapMarkerEdit')}</button>
</div>
<div class="edit-mode">
<p class="help" style="font-size: 12px;font-style: italic;">${localeService.t('mapMarkerMoveLabel')}</p>
<p><span class="updated-position" style="font-size: 12px;"></span></p>
<div>
<button class="cancel-position btn btn-inverse btn-small btn-block" data-marker-id="${marker.properties.recordIndex}">${localeService.t('mapMarkerEditCancel')}</button>
<button class="submit-position btn btn-inverse btn-small btn-block" data-marker-id="${marker.properties.recordIndex}">${localeService.t('mapMarkerEditSubmit')}</button>
</div>
</div>`;
}
$content.append(template);
$content.find('.edit-mode').hide();
//
$content.on('click', '.edit-position', (event) => {
let $el = $(event.currentTarget);
let marker = getMarker($el.data('marker-id'));
marker._originalPosition = marker.lngLat.wrap();
$content.find('.view-mode').hide();
$content.find('.edit-mode').show();
$content.find('.help').show();
isDraggable = true;
map.on('mousedown', mouseDown);
});
$content.on('click', '.submit-position', (event) => {
let $el = $(event.currentTarget);
let marker = getMarker($el.data('marker-id'));
isDraggable = false;
$content.find('.view-mode').show();
$content.find('.help').hide();
$content.find('.updated-position').html('');
$content.find('.edit-mode').hide();
var popup = document.getElementsByClassName('mapboxgl-popup');
if (popup[0]) popup[0].parentElement.removeChild(popup[0]);
marker.lngLat = {
lng: cachedGeoJson.features[0].geometry.coordinates[0],
lat: cachedGeoJson.features[0].geometry.coordinates[1]
};
marker.feature = marker.features[0];
eventEmitter.emit('markerChange', {marker, position: marker.lngLat});
});
$content.on('click', '.cancel-position', (event) => {
let $el = $(event.currentTarget);
let marker = getMarker($el.data('marker-id'));
isDraggable = false;
$content.find('.view-mode').show();
$content.find('.updated-position').html('');
$content.find('.edit-mode').hide();
$content.find('.help').hide();
var popup = document.getElementsByClassName('mapboxgl-popup');
if (popup[0]) popup[0].parentElement.removeChild(popup[0]);
cachedGeoJson.features[0].geometry.coordinates = [marker._originalPosition.lng, marker._originalPosition.lat];
map.getSource('data').setData(cachedGeoJson);
});
// When the cursor enters a feature in the point layer, prepare for dragging.
map.on('mouseenter', 'points', function () {
if (!isDraggable) {
return;
}
map.getCanvas().style.cursor = 'move';
isCursorOverPoint = true;
map.dragPan.disable();
});
map.on('mouseleave', 'points', function () {
if (!isDraggable) {
return;
}
map.getCanvas().style.cursor = '';
isCursorOverPoint = false;
map.dragPan.enable();
});
map.on('click', 'points', function (e) {
markerCollection[e.features[0].properties.recordIndex] = e;
var coordinates = e.features[0].geometry.coordinates.slice();
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
var popup = document.getElementsByClassName('mapboxgl-popup');
// Check if there is already a popup on the map and if so, remove it
if (popup[0]) popup[0].parentElement.removeChild(popup[0]);
popupDialog = new mapboxgl.Popup({closeOnClick: false}).setLngLat(coordinates)
.setDOMContent($content.get(0))
.addTo(map);
popupDialog.on('close', function (event) {
if (editable) {
resetMarkerPosition($content);
}
});
});
function mouseDown() {
if (!isCursorOverPoint) return;
isDragging = true;
// Set a cursor indicator
map.getCanvas().style.cursor = 'grab';
// Mouse events
map.on('mousemove', onMove);
map.once('mouseup', onUp);
var popup = document.getElementsByClassName('mapboxgl-popup');
if (popup[0]) popup[0].parentElement.removeChild(popup[0]);
}
function onMove(e) {
if (!isDragging) return;
var coords = e.lngLat;
// Set a UI indicator for dragging.
map.getCanvas().style.cursor = 'grabbing';
// Update the Point feature in `geojson` coordinates
// and call setData to the source layer `point` on it.
cachedGeoJson.features[0].geometry.coordinates = [coords.lng, coords.lat];
map.getSource('data').setData(cachedGeoJson);
}
function onUp(e) {
if (!isDragging) return;
let position = e.lngLat;
map.getCanvas().style.cursor = '';
isDragging = false;
// Unbind mouse events
map.off('mousemove', onMove);
$content.find('.updated-position').html(`${position.lat}<br>${position.lng}`);
popupDialog = new mapboxgl.Popup({closeOnClick: false}).setLngLat(position)
.setDOMContent($content.get(0))
.addTo(map);
popupDialog.on('close', function (event) {
if (editable) {
resetMarkerPosition($content);
}
});
}
}
const resetMarkerPosition = ($content) => {
let marker = getMarker($content.find('.edit-position').data('marker-id'))
$content.find('.view-mode').show();
$content.find('.updated-position').html('');
$content.find('.edit-mode').hide();
$content.find('.help').hide();
isDraggable = false;
if (marker._originalPosition !== undefined) {
cachedGeoJson.features[0].geometry.coordinates = [marker._originalPosition.lng, marker._originalPosition.lat];
map.getSource('data').setData(cachedGeoJson);
}
}
const getMarker = (markerId) => {
return markerCollection[markerId];
}
return {
initialize, setCollection
}
}
export default markerGLCollection;

View File

@@ -0,0 +1,471 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
const humane = require('humane-js');
const download = (services) => {
const {configService, localeService, appEvents} = services;
const url = configService.get('baseUrl');
let $container = null;
const initialize = (options) => {
$container = options.$container;
$container.on('click', '.basket_downloader', (event) => {
event.preventDefault();
_downloadBasket();
})
};
const openModal = (datas) => {
$('body').addClass('dialog-open');
var $dialog = dialog.create(services, {
size: 'Medium',
title: localeService.t('export'),
});
$('#DIALOG1').on('dialogclose', function(event) {
$('body').removeClass('dialog-open');
});
$.ajax({
type: 'POST',
data: 'lst=' + datas,
url: `${url}prod/export/multi-export/`,
success: function (data) {
$dialog.setContent(data);
_onDownloadReady($dialog, window.exportConfig);
}
});
return true;
}
const _onDownloadReady = ($dialog, dataConfig) => {
$('.tabs', $dialog.getDomElement()).tabs();
$('.close_button', $dialog.getDomElement()).bind('click', function () {
$dialog.close();
});
var tabs = $('.tabs', $dialog.getDomElement());
if (dataConfig.haveFtp === true) {
$('#ftp_form_selector')
.bind('change', function () {
$('#ftp .ftp_form').hide();
$('#ftp .ftp_form_' + $(this).val()).show();
$('.ftp_folder_check', dialog.get(1).getDomElement())
.unbind('change')
.bind('change', function () {
if ($(this).prop('checked')) {
$(this).next().prop('disabled', false);
} else {
$(this).next().prop('disabled', true);
}
});
})
.trigger('change');
}
$('a.TOUview').bind('click', function (event) {
event.preventDefault();
let $el = $(event.currentTarget);
var options = {
size: 'Medium',
closeButton: true,
title: dataConfig.msg.termOfUseTitle
};
let termOfuseDialog = dialog.create(services, options, 2);
$.get($el.attr('href'), function (content) {
termOfuseDialog.setContent(content);
});
});
$('.close_button').bind('click', function () {
$dialog.close();
});
$('#download .download_button').bind('click', function () {
if (!check_subdefs($('#download'), dataConfig)) {
return false;
}
if (!check_TOU($('#download'), dataConfig)) {
return false;
}
var total = 0;
var count = 0;
$('input[name="obj[]"]', $('#download')).each(function () {
var total_el = $(
'#download input[name=download_' + $(this).val() + ']'
);
var count_el = $(
'#download input[name=count_' + $(this).val() + ']'
);
if ($(this).prop('checked')) {
total += parseInt($(total_el).val(), 10);
count += parseInt($(count_el).val(), 10);
}
});
if (count > 1 && total / 1024 / 1024 > dataConfig.maxDownload) {
if (
confirm(
`${dataConfig.msg.fileTooLarge} \n ${dataConfig.msg
.fileTooLargeAlt}`
)
) {
$(
'input[name="obj[]"]:checked',
$('#download')
).each(function (i, n) {
$(
'input[name="obj[]"][value="' + $(n).val() + '"]',
$('#sendmail')
).prop('checked', true);
});
$(document).find('input[name="taglistdestmail"]').tagsinput('add', dataConfig.user.email);
var tabs = $('.tabs', $dialog.getDomElement());
tabs.tabs('option', 'active', 1);
}
return false;
}
$('#download form').submit();
$dialog.close();
});
$('#order .order_button').bind('click', function () {
let title = '';
if (!check_TOU($('#order'), dataConfig)) {
return false;
}
$('#order .order_button_loader').css('visibility', 'visible');
var options = $('#order form').serialize();
var $this = $(this);
$this.prop('disabled', true).addClass('disabled');
$.post(
`${url}prod/order/`,
options,
function (data) {
$this.prop('disabled', false).removeClass('disabled');
$('#order .order_button_loader').css(
'visibility',
'hidden'
);
if (!data.error) {
title = dataConfig.msg.success;
} else {
title = dataConfig.msg.warning;
}
var options = {
size: 'Alert',
closeButton: true,
title: title
};
dialog.create(services, options, 2).setContent(data.msg);
if (!data.error) {
showHumane(data.msg);
$dialog.close();
} else {
alert(data.msg);
}
return;
},
'json'
);
});
$('#ftp .ftp_button').bind('click', function () {
if (!check_subdefs($('#ftp'), dataConfig)) {
return false;
}
if (!check_TOU($('#ftp'), dataConfig)) {
return false;
}
$('#ftp .ftp_button_loader').show();
$('#ftp .ftp_form:hidden').remove();
var $this = $(this);
var options_addr = $('#ftp_form_stock form:visible').serialize();
var options_join = $('#ftp_joined').serialize();
$this.prop('disabled', true);
$.post(
`${url}prod/export/ftp/`,
options_addr + '&' + options_join,
function (data) {
$this.prop('disabled', false);
$('#ftp .ftp_button_loader').hide();
if (data.success) {
showHumane(data.message);
$dialog.close();
} else {
var alert = dialog.create(
services,
{
size: 'Alert',
closeOnEscape: true,
closeButton: true,
title: dataConfig.msg.warning
},
2
);
alert.setContent(data.message);
}
return;
},
'json'
);
});
$('#ftp .tryftp_button').bind('click', function () {
$('#ftp .tryftp_button_loader').css('visibility', 'visible');
var $this = $(this);
$this.prop('disabled', true);
var options_addr = $('#ftp_form_stock form:visible').serialize();
$.post(
`${url}prod/export/ftp/test/`,
// no need to include 'ftp_joined' checkboxes to test ftp
options_addr,
function (data) {
$('#ftp .tryftp_button_loader').css('visibility', 'hidden');
var options = {
size: 'Alert',
closeButton: true,
title: data.success
? dataConfig.msg.success
: dataConfig.msg.warning
};
dialog
.create(services, options, 3)
.setContent(data.message);
$this.prop('disabled', false);
return;
}
);
});
function showHumane(data) {
$('body').append('<div class="humane humane-libnotify-info">Email sending request submitted </div>');
$('body').find('.humane-libnotify-info').html(data);
setTimeout(hideHumane, 3000);
}
function hideHumane() {
$('body').find('.humane').remove();
}
$('#sendmail .sendmail_button').bind('click', function () {
if(!validEmail($('input[name="taglistdestmail"]', $('#sendmail')).val(), dataConfig)) {
return false;
}
if (!check_subdefs($('#sendmail'), dataConfig)) {
return false;
}
if (!check_TOU($('#sendmail'), dataConfig)) {
return false;
}
if ($('iframe[name=""]').length === 0) {
$('body').append(
'<iframe style="display:none;" name="sendmail_target"></iframe>'
);
}
$('#sendmail form').submit();
showHumane($('#export-send-mail-notif').val());
$dialog.close();
});
$('.datepicker', $dialog.getDomElement()).datepicker({
changeYear: true,
changeMonth: true,
dateFormat: 'yy-mm-dd'
});
$(
'a.undisposable_link',
$dialog.getDomElement()
).bind('click', function () {
$(this).parent().parent().find('.undisposable').slideToggle();
return false;
});
$(
'input[name="obj[]"]',
$('#download, #sendmail, #ftp')
).bind('change', function () {
var $form = $(this).closest('form');
if ($('input.caption[name="obj[]"]:checked', $form).length > 0) {
$('div.businessfields', $form).show();
} else {
$('div.businessfields', $form).hide();
}
});
};
function validateEmail(email) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
function validEmail(emailList, dataConfig) {
//split emailList by ; , or whitespace and filter empty element
let emails = emailList.split(/[ ,;]+/).filter(Boolean);
let alert;
for(let i=0; i < emails.length; i++) {
if (!validateEmail(emails[i])) {
alert = dialog.create(
services,
{
size: 'Alert',
closeOnEscape: true,
closeButton: true,
title: dataConfig.msg.warning
},
2
);
alert.setContent(dataConfig.msg.invalidEmail);
return false;
}
}
return true;
}
function check_TOU(container, dataConfig) {
let checkbox = $('input[name="TOU_accept"]', $(container));
let go = checkbox.length === 0 || checkbox.prop('checked');
let alert;
if (!go) {
alert = dialog.create(
services,
{
size: 'Small',
closeOnEscape: true,
closeButton: true,
title: dataConfig.msg.warning
},
2
);
alert.setContent(dataConfig.msg.termOfUseAgree);
return false;
}
return true;
}
function check_subdefs(container, dataConfig) {
let go = false;
let required = false;
let alert;
$('input[name="obj[]"]', $(container)).each(function () {
if ($(this).prop('checked')) {
go = true;
}
});
$('input.required, textarea.required', container).each(function (i, n) {
if ($.trim($(n).val()) === '') {
required = true;
$(n).addClass('error');
} else {
$(n).removeClass('error');
}
});
if (required) {
alert = dialog.create(
services,
{
size: 'Alert',
closeOnEscape: true,
closeButton: true,
title: dataConfig.msg.warning
},
2
);
alert.setContent(dataConfig.msg.requiredFields);
return false;
}
if (!go) {
alert = dialog.create(
services,
{
size: 'Alert',
closeOnEscape: true,
closeButton: true,
title: dataConfig.msg.warning
},
2
);
alert.setContent(dataConfig.msg.missingSubdef);
return false;
}
return true;
}
function _downloadBasket() {
var ids = $.map($('#sc_container .download_form').toArray(), function (el, i) {
return $('input[name="basrec"]', $(el)).val();
});
openModal(ids.join(';'));
}
/*function download(value) {
var $dialog = dialog.create({title: localeService.t('export')});
$.post('/prod/export/multi-export/', 'lst=' + value, function (data) {
$dialog.setContent(data);
$('.tabs', $dialog.getDomElement()).tabs();
$('.close_button', $dialog.getDomElement()).bind('click', function () {
$dialog.close();
});
return false;
});
}*/
return {initialize, openModal}
}
export default download;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
import $ from 'jquery';
const listEditor = (services, options) => {
const { configService, localeService, appEvents } = services;
const { $container, listManagerInstance } = options;
const $editor = $('#list-editor-search-results');
const $form = $('#ListManager .editor').find('form[name="list-editor-search"]');
$('a.next, a.prev', $editor).bind('click', function (event) {
event.preventDefault();
const page = $(this).attr('value');
$('input[name="page"]', $form).val(page);
$form.trigger('submit');
});
$('input[name="page"]', $form).val('');
$('th.sortable', $editor).bind('click', function () {
let $this = $(this);
let sort = $('input', $this).val();
let ord = 'asc';
if ((sort === $('input[name="srt"]', $form).val()) && ($('input[name="ord"]', $form).val() === 'asc')) {
ord = 'desc';
}
$('input[name="srt"]', $form).val(sort);
$('input[name="ord"]', $form).val(ord);
$form.trigger('submit');
})
.bind('mouseover', function () {
$(this).addClass('hover');
})
.bind('mouseout', function () {
$(this).removeClass('hover');
});
$('tbody tr', $editor).bind('click', function () {
let $this = $(this);
let usr_id = $('input[name="usr_id"]', $this).val();
let counters = $('#ListManager .counter.current, #ListManager .lists .list.selected .counter');
if ($this.hasClass('selected')) {
$this.removeClass('selected');
listManagerInstance.getList().removeUser(usr_id);
counters.each(function (i, el) {
let n = parseInt($(el).text().split(' ')[0], 10);
if($(el).hasClass('current'))
$(el).text(n - 1 + ' people');
else
$(el).text(n - 1);
});
} else {
$this.addClass('selected');
listManagerInstance.getList().addUser(usr_id);
counters.each(function (i, el) {
let n = parseInt($(el).text(), 10);
if($(el).hasClass('current'))
$(el).text(n + 1 + ' people');
else
$(el).text(n + 1);
});
}
});
};
export default listEditor;

View File

@@ -0,0 +1,605 @@
import $ from 'jquery';
import {Lists, List} from './model/index';
import listEditor from './listEditor';
import listShare from './listShare';
import dialog from './../../phraseanet-common/components/dialog';
import Selectable from '../utils/selectable';
import pushAddUser from '../record/recordPush/addUser';
import * as _ from 'underscore';
const humane = require('humane-js');
const ListManager = function (services, options) {
const { configService, localeService, appEvents } = services;
const { containerId } = options;
const url = configService.get('baseUrl');
let $container;
const _this = this;
this.list = null;
this.container = $container = $(containerId);
this.userList = new Lists();
this.removeUserItemsArray = [];
this.addUserItemsArray = [];
this.removeUserMethod = '';
this.addUserMethod = '';
pushAddUser(services).initialize({$container: this.container});
$container.on('click', '.back_link', function () {
$('#PushBox').show();
$('#ListManager').hide();
return false;
})
.on('click', '.push-list-share-action', (event) => {
event.preventDefault();
let $el = $(event.currentTarget);
const listId = $el.data('list-id');
listShare(services).openModal({
listId, modalOptions: {
size: '288x500',
closeButton: true,
title: $el.attr('title')
}, modalLevel: 2
});
return false;
})
.on('click', 'a.user_adder', function () {
var $this = $(this);
$.ajax({
type: 'GET',
url: $this.attr('href'),
dataType: 'html',
beforeSend: function () {
var options = {
size: 'Medium',
title: $this.html()
};
dialog.create(services, options, 2).getDomElement().addClass('loading');
},
success: function (data) {
dialog.get(2).getDomElement().removeClass('loading').empty().append(data);
return;
},
error: function () {
dialog.get(2).close();
return;
},
timeout: function () {
dialog.get(2).close();
return;
}
});
return false;
})
.on('mouseenter', '.list-trash-btn', function (event) {
var $el = $(event.currentTarget);
$el.find('.image-normal').hide();
$el.find('.image-hover').show();
})
.on('mouseleave', '.list-trash-btn', function (event) {
var $el = $(event.currentTarget);
$el.find('.image-normal').show();
$el.find('.image-hover').hide();
})
.on('click', '.list-trash-btn', function (event) {
var $el = $(event.currentTarget);
var list_id = $el.parent().data('list-id');
appEvents.emit('push.removeList', {
list_id: list_id,
container: containerId
}
);
});
var initLeft = () => {
$container.on('click', '.push-refresh-list-action', (event) => {
event.preventDefault();
//$('a.list_refresh', $container).bind('click', (event) => {
// /prod/lists/all/
var selectedList = $('.lists_manager_list.selected').data('list-id');
var callback = function (datas, selected) {
$('.all-lists', $container).removeClass('loading').append(datas);
if (typeof selected === 'number') {
$('.all-lists').find('.lists_manager_list[data-list-id="' + selected + '"]').addClass('selected');
}
// initLeft();
};
$('.all-lists', $container).empty().addClass('loading');
this.userList.get(callback, 'html', selectedList);
});
$container.on('click', '.push-add-list-action', (event) => {
event.preventDefault();
var makeDialog = (box) => {
var buttons = {};
buttons[localeService.t('valider')] = () => {
var callbackOK = function () {
$('a.list_refresh', $container).trigger('click');
dialog.get(2).close();
};
var name = $('input[name="name"]', dialog.get(2).getDomElement()).val();
if ($.trim(name) === '') {
alert($('#push-list-name-empty').val());
return;
}
this.userList.create(name, callbackOK);
};
// /prod/lists/list/
var options = {
cancelButton: true,
buttons: buttons,
title: $('#push-new-list-title').val(),
size: '450x170'
};
const $dialog = dialog.create(services, options, 2);
$dialog.getDomElement().closest('.ui-dialog').addClass('dialog_container dialog_add_list')
.find('.ui-dialog-buttonset button:first-child .ui-button-text').text($('#btn-add').val());
$dialog.setContent(box);
};
var html = _.template($('#list_editor_dialog_add_tpl').html());
makeDialog(html);
return false;
});
/*$('li.list a.list_link', $container).bind('click', function (event) {
var $this = $(this);
$this.closest('.lists').find('.list.selected').removeClass('selected');
$this.parent('li.list').addClass('selected');
return false;
});*/
$container.on('click', '.list-edit-action', (event) => {
event.preventDefault();
_this.removeUserItemsArray = [];
_this.addUserItemsArray = [];
_this.removeUserMethod = '';
_this.addUserMethod = '';
let $el = $(event.currentTarget);
const listId = $el.data('list-id');
const el_url = $el.attr('href');
const callbackList = function (list) {
for (let i in list.entries) {
this.selectUser(list.entries[i].User);
}
};
$el.closest('.lists').find('.list').removeClass('selected');
$el.parent().addClass('selected');
$.ajax({
type: 'GET',
url: `${url}prod/push/edit-list/${listId}/`,
dataType: 'html',
success: (data) => {
this.workOn(listId);
$('.editor', $container).removeClass('loading').append(data);
this.loadList(el_url, callbackList);
initRight();
listEditor(services, {
$container, listManagerInstance: _this
});
},
beforeSend: function () {
$('.editor', $container).empty().addClass('loading');
}
});
});
$container.on('click', '.listmanager-delete-list-user-action', (event) => {
event.preventDefault();
let $el = $(event.currentTarget);
const listId = $el.data('list-id');
const userId = $el.data('user-id');
var badge = $(this).closest('.badge');
// var usr_id = badge.find('input[name="id"]').val();
this.getList().removeUser(userId, function (list, data) {
badge.remove();
});
});
};
var initRight = function () {
var $container = $('#ListManager .editor');
var selection = new Selectable(services, $('.user_content .badges', _this.container), {
selector: '.badge'
});
$('form[name="list-editor-search"]', $container).bind('submit', function (event) {
event.preventDefault();
var $this = $(this);
var dest = $('.list-editor-results', $container);
$.ajax({
url: $this.attr('action'),
type: $this.attr('method'),
dataType: 'html',
data: $this.serializeArray(),
beforeSend: function () {
dest.empty().addClass('loading');
},
success: function (datas) {
dest.empty().removeClass('loading').append(datas);
listEditor(services, {
$container, listManagerInstance: _this
});
}
});
});
$('form[name="list-editor-search"] select, form[name="list-editor-search"] input[name="ListUser"]', $container).bind('change', function () {
$(this).closest('form').trigger('submit');
});
$('.EditToggle', $container).bind('click', function (event) {
event.preventDefault();
$('.content.readselect, .content.readwrite, .editor_header', $('#ListManager')).toggle();
});
$('.Refresher', $container).bind('click', function (event) {
event.preventDefault();
$('#ListManager ul.lists .list.selected a').trigger('click');
});
$('form[name="SaveName"]', $container).bind('submit', function () {
var $this = $(this);
$.ajax({
type: $this.attr('method'),
url: $this.attr('action'),
dataType: 'json',
data: $this.serializeArray(),
beforeSend: function () {
},
success: function (data) {
if (data.success) {
humane.info(data.message);
$('#ListManager .lists .list_refresh').trigger('click');
} else {
humane.error(data.message);
}
return;
},
error: function () {
return;
},
timeout: function () {
return;
}
});
return false;
});
// //button.deleter
// $('.listmanager-delete-list-action', $container).bind('click', function (event) {
// var list_id = $(this).data('list-id');
// var makeDialog = function (box) {
// var buttons = {};
// buttons[localeService.t('valider')] = function () {
// var callbackOK = function () {
// $('#ListManager .all-lists a.list_refresh').trigger('click');
// dialog.get(2).close();
// };
// var List = new List(list_id);
// List.remove(callbackOK);
// };
// var options = {
// cancelButton: true,
// buttons: buttons,
// size: 'Alert'
// };
// dialog.create(services, options, 2).setContent(box);
// };
// var html = _.template($('#list_editor_dialog_delete_tpl').html());
// makeDialog(html);
// return false;
// });
$('input[name="users-search"]', $container).autocomplete({
minLength: 2,
source: function (request, response) {
$.ajax({
url: `${url}prod/push/search-user/`,
dataType: 'json',
data: {
query: request.term
},
success: function (data) {
response(data);
}
});
},
focus: function (event, ui) {
// $('input[name="users-search"]').val(ui.item.label);
},
select: function (event, ui) {
if (ui.item.type === 'USER') {
_this.selectUser(ui.item);
_this.updateUsersHandler('add', ui.item.usr_id);
} else if (ui.item.type === 'LIST') {
for (let e in ui.item.entries) {
_this.selectUser(ui.item.entries[e].User);
_this.updateUsersHandler('add', ui.item.entries[e].User.usr_id);
}
}
$('#saveListFooter').show();
return false;
}
})
.data('ui-autocomplete')._renderItem = function (ul, item) {
var html = '';
if (item.type === 'USER') {
html = _.template($('#list_user_tpl').html())({
item: item
});
} else if (item.type === 'LIST') {
html = _.template($('#list_list_tpl').html())({
item: item
});
}
return $(html).data('ui-autocomplete-item', item).appendTo(ul);
};
$('.user_content .badges', _this.container).disableSelection();
$container.on('click', '.content .options .select-all', function () {
selection.selectAll();
});
$container.on('click', '.content .options .unselect-all', function () {
selection.empty();
});
$container.on('click', '.content .options .delete-selection', function () {
var $elems = $('#ListManager .badges.selectionnable .badge.selected');
_.each($elems, function(item) {
var $elem = $(item);
var $elemID = $elem.find('input[name=id]').val();
if($elem.hasClass('selected')
&& _this.removeUserItemsArray.indexOf($elemID) === -1) {
_this.updateUsersHandler('remove', $elemID);
}
});
$elems.fadeOut(300, 'swing', function() {
$(this).remove();
$('#saveListFooter').show();
});
});
$container.on('submit', 'form.list_saver', function (event) {
event.preventDefault();
var $form = $(event.currentTarget);
var name = $('.header h2', $container).text();
var users = _this.getUsers();
if (users.length === 0) {
humane.error('No users');
return false;
}
else {
if (_this.removeUserMethod === 'remove' && _this.removeUserItemsArray.length > 0) {
var $editor = $('#list-editor-search-results');
_.each(_this.removeUserItemsArray, function (item) {
$('tbody tr', $editor).each(function(i, el) {
var $el = $(el);
var $elID = $('input[name="usr_id"]', $el).val();
if(item == $elID)
$el.removeClass('selected');
});
_this.getList().removeUser(item);
});
var ListCounter = $('#ListManager .counter.current, #ListManager .lists .list.selected .counter');
ListCounter.each(function (i, el) {
var n = parseInt($(el).text(), 10);
if($(el).hasClass('current'))
$(el).text(n - _this.removeUserItemsArray.length + ' people');
else
$(el).text(n - _this.removeUserItemsArray.length);
});
$('#saveListFooter').hide();
_this.removeUserItemsArray = [];
_this.removeUserMethod = '';
}
else if (_this.addUserMethod === 'add' && _this.addUserItemsArray.length > 0) {
var $editor = $('#list-editor-search-results');
_.each(_this.addUserItemsArray, function (item) {
$('tbody tr', $editor).each(function(i, el) {
var $el = $(el);
var $elID = $('input[name="usr_id"]', $el).val();
if(item == $elID)
$el.addClass('selected');
});
_this.getList().addUser(item);
});
var ListCounter = $('#ListManager .counter.current, #ListManager .lists .list.selected .counter');
ListCounter.each(function (i, el) {
var n = parseInt($(el).text(), 10);
if($(el).hasClass('current'))
$(el).text(n + _this.addUserItemsArray.length + ' people');
else
$(el).text(n + _this.addUserItemsArray.length);
});
$('#saveListFooter').hide();
_this.addUserItemsArray = [];
_this.addUserMethod = '';
}
}
});
$container.on('click', '.badges a.deleter', function (event) {
var badge = $(event.currentTarget).closest('.badge');
var usr_id = badge.find('input[name="id"]').val();
var ListCounter = $('#ListManager .counter.current, #ListManager .lists .list.selected .counter');
var $editor = $('#list-editor-search-results');
var callback = function callback(list, datas) {
ListCounter.each(function (i, el) {
var n = parseInt($(el).text(), 10);
if($(el).hasClass('current'))
$(el).text(n - 1 + ' people');
else
$(el).text(n - 1);
});
badge.fadeOut('300', 'swing', function() {
badge.remove();
});
};
_this.getList().removeUser(usr_id, callback);
$('tbody tr', $editor).each(function(i, el) {
var $el = $(el);
var $elID = $('input[name="usr_id"]', $el).val();
if(usr_id === $elID)
$el.removeClass('selected');
});
return false;
});
};
initLeft();
return this;
};
ListManager.prototype = {
selectUser: function (user) {
if (typeof user !== 'object') {
if (window.console) {
console.log('trying to select a user with wrong datas');
}
}
if ($('.badge_' + user.usr_id, this.container).length > 0) {
humane.info('User already selected');
return;
}
else {
var html = _.template($('#list_manager_badge_tpl').html())({
user: user
});
// p4.Feedback.appendBadge(html);
// this.getList().addUser(user.usr_id);
this.appendBadge(html);
}
},
workOn: function (list_id) {
this.list = new List(list_id);
},
getList: function () {
return this.list;
},
appendBadge: function (datas) {
$('#ListManager .badges').append(datas);
},
createList: function (options) {
let { name, collection } = options;
this.userList.create(name, function (list) {
list.addUsers(collection);
});
},
removeList: function (list_id, callback) {
this.list = new List(list_id);
this.list.remove(callback);
},
loadList: function (url, callback) {
var $this = this;
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success: function (data) {
if (typeof callback === 'function') {
callback.call($this, data);
}
}
});
},
updateUsers: function (action) {
if(action === 'remove') {
}
return removedItems;
},
getUsers: function () {
return $('.user_content .badge', this.container).map(function () {
return $('input[name="id"]', $(this)).val();
});
},
updateUsersHandler: function (method, item) {
if (method === 'remove') {
this.removeUserItemsArray.push(item);
this.removeUserMethod = method;
}
else if (method === 'add') {
this.addUserItemsArray.push(item);
this.addUserMethod = method;
}
}
};
export default ListManager;

View File

@@ -0,0 +1,149 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
import * as _ from 'underscore';
const humane = require('humane-js');
const listShare = (services, options) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
let $dialog = null;
const initialize = () => {
};
const openModal = (options) => {
let { listId, modalOptions, modalLevel } = options;
$dialog = dialog.create(services, modalOptions, modalLevel);
$dialog.getDomElement().closest('.ui-dialog').addClass('dialog_container dialog_share_list');
return $.get(`${url}prod/lists/list/${listId}/share/`, function (data) {
$dialog.setContent(data);
onModalReady(listId);
});
};
const onModalReady = (listId) => {
let $container = $('#ListShare');
let $completer_form = $('form[name="list_share_user"]', $container);
let $owners_form = $('form[name="owners"]', $container);
let $autocompleter = $('input[name="user"]', $completer_form);
let $dialog = dialog.get(2);
$completer_form.bind('submit', function () {
return false;
});
$('select[name="role"]', $owners_form).bind('change', function (event) {
event.preventDefault();
let $el = $(event.currentTarget);
const userId = $el.data('user-id');
shareWith(userId, $el.val());
return false;
});
$container.on('click', '.listmanager-share-delete-user-action', (event) => {
event.preventDefault();
let $el = $(event.currentTarget);
const userId = $el.data('user-id');
let $owner = $el.closest('.owner');
unShareWith(userId, function (data) {
$owner.remove();
});
return false;
});
function shareWith(userId, role) {
role = typeof role === 'undefined' ? 1 : role;
$.ajax({
type: 'POST',
url: `${url}prod/lists/list/${listId}/share/${userId}/`,
dataType: 'json',
data: {role: role},
beforeSend: function () {
},
success: function (data) {
if (data.success) {
humane.info(data.message);
} else {
humane.error(data.message);
}
$('.push-list-share-action').trigger('click');
$dialog.refresh();
return;
}
});
}
function unShareWith(userId, callback) {
$.ajax({
type: 'POST',
url: `${url}prod/lists/list/${listId}/unshare/${userId}/`,
dataType: 'json',
data: {},
beforeSend: function () {
},
success: function (data) {
if (data.success) {
humane.info(data.message);
callback(data);
} else {
humane.error(data.message);
}
$dialog.refresh();
return;
}
});
}
$autocompleter.autocomplete({
minLength: 2,
source: function (request, response) {
$.ajax({
url: `${url}prod/push/search-user/`,
dataType: 'json',
data: {
query: request.term
},
success: function (data) {
response(data);
}
});
},
select: function (event, ui) {
if (ui.item.type === 'USER') {
shareWith(ui.item.usr_id);
}
return false;
}
})
.data('ui-autocomplete')._renderItem = function (ul, item) {
if (item.type === 'USER') {
var html = _.template($('#list_user_tpl').html())({
item: item
});
return $(html).data('ui-autocomplete-item', item).appendTo(ul);
}
};
};
return {
openModal
};
};
export default listShare;

View File

@@ -0,0 +1,199 @@
import $ from 'jquery';
const humane = require('humane-js');
var Lists = function () {
};
var List = function (id) {
if (parseInt(id, 10) <= 0) {
throw 'Invalid list id';
}
this.id = id;
};
Lists.prototype = {
create: function (name, callback) {
$.ajax({
type: 'POST',
// @TODO - load baseUrl from configService
url: '/prod/lists/list/',
dataType: 'json',
data: {name: name},
success: function (data) {
if (data.success) {
humane.info(data.message);
if (typeof callback === 'function') {
var list = new List(data.list_id);
callback(list);
}
} else {
humane.error(data.message);
}
}
});
},
get: function (callback, type, selectedList) {
type = typeof type === 'undefined' ? 'json' : type;
$.ajax({
type: 'GET',
// @TODO - load baseUrl from configService
url: '/prod/lists/all/',
dataType: type,
data: {},
success: function (data) {
if (type === 'json') {
if (data.success) {
humane.info(data.message);
if (typeof callback === 'function') {
callback(data.result);
}
} else {
humane.error(data.message);
}
} else {
if (typeof callback === 'function') {
callback(data, selectedList);
}
}
}
});
}
};
List.prototype = {
addUsers: function (arrayUsers, callback) {
if (!arrayUsers instanceof Array) {
throw 'addUsers takes array as argument';
}
var $this = this;
var data = {usr_ids: $(arrayUsers).toArray()};
$.ajax({
type: 'POST',
// @TODO - load baseUrl from configService
url: '/prod/lists/list/' + $this.id + '/add/',
dataType: 'json',
data: data,
success: function (data) {
if (data.success) {
humane.info(data.message);
if (typeof callback === 'function') {
callback($this, data);
}
} else {
humane.error(data.message);
}
}
});
},
addUser: function (usr_id, callback) {
this.addUsers([usr_id], callback);
},
remove: function (callback) {
var $this = this;
$.ajax({
type: 'POST',
// @TODO - load baseUrl from configService
url: '/prod/lists/list/' + this.id + '/delete/',
dataType: 'json',
data: {},
success: function (data) {
if (data.success) {
humane.info(data.message);
if (typeof callback === 'function') {
callback($this);
}
} else {
humane.error(data.message);
}
}
});
},
update: function (name, callback) {
var $this = this;
$.ajax({
type: 'POST',
// @TODO - load baseUrl from configService
url: '/prod/lists/list/' + this.id + '/update/',
dataType: 'json',
data: {name: name},
success: function (data) {
if (data.success) {
humane.info(data.message);
if (typeof callback === 'function') {
callback($this);
}
} else {
humane.error(data.message);
}
}
});
},
removeUser: function (usr_id, callback) {
var $this = this;
$.ajax({
type: 'POST',
// @TODO - load baseUrl from configService
url: '/prod/lists/list/' + this.id + '/remove/' + usr_id + '/',
dataType: 'json',
data: {},
success: function (data) {
if (data.success) {
humane.info(data.message);
if (typeof callback === 'function') {
callback($this, data);
}
} else {
humane.error(data.message);
}
}
});
},
get: function (callback) {
var $this = this;
$.ajax({
type: 'GET',
// @TODO - load baseUrl from configService
url: '/prod/lists/list/' + this.id + '/',
dataType: 'json',
data: {},
success: function (data) {
if (data.success) {
humane.info(data.message);
if (typeof callback === 'function') {
callback($this, data);
}
} else {
humane.error(data.message);
}
}
});
}
};
export {Lists, List};

View File

@@ -0,0 +1,73 @@
import i18next from 'i18next';
import Backend from 'i18next-xhr-backend';
import $ from 'jquery';
import * as Rx from 'rx';
let instance = null;
class LocaleService {
constructor(options) {
if (!options) {
options = {};
}
// can be instanciated only once
if (!instance) {
instance = this;
}
if (options.locale === undefined) {
options.locale = 'fr';
}
this.locale = options.locale;
this.isCached = false;
this.cachedTranslations = {};
this.configService = options.configService;
this.path = this.configService.get('translations');
return instance;
}
t(key) {
if (this.isCached && this.translate !== undefined) {
return this.translate(key);
} else {
throw new Error('locale not loaded');
}
}
getLocale() {
return this.locale;
}
getTranslations() {
return this.cachedTranslations;
}
fetchTranslations(data) {
data = data || {};
let i18nPromise = $.Deferred();
i18next
.use(Backend)
.init({
lng: this.locale,
backend: {
loadPath: this.path,
}
}, (err, t) => {
this.isCached = true;
this.translate = t;
this.cachedTranslations = i18next.getResourceBundle(this.locale);
i18nPromise.resolve(instance);
if (data.callback !== undefined) {
data.callback();
}
//resolve(this.i18n);
});
// });
this.i18n = i18nPromise.promise();
this.stream = Rx.Observable.fromPromise(this.i18n);
return this.i18n;
}
}
export default LocaleService;

View File

@@ -0,0 +1,49 @@
import $ from 'jquery';
require('./../../phraseanet-common/components/vendors/contextMenu');
const mainMenu = (services) => {
const { configService, localeService, appEvents } = services;
const $container = $('body');
const initialize = () => {
_bindEvents();
return true;
};
const _bindEvents = () => {
/**
* mainMenu > Publication link
*/
$container.on('click', '.state-navigation', function (event) {
event.preventDefault();
let $el = $(event.currentTarget);
// @TODO loop through each state args:
_stateNavigator($el.data('state'));
});
/**
* mainMenu > help context menu
*/
/* $('body').on('click', '#help-trigger', function (event) {
$('#mainMenu .helpcontextmenu').toggleClass('shown');
});*/
};
const _stateNavigator = (...state) => {
let [stateName, stateArgs] = state;
switch (stateName) {
case 'publication':
appEvents.emit(`${stateName}.activeState`); // fetch
break;
default:
console.log('navigation state error: state "' + stateName + '" not found');
}
};
return { initialize };
};
export default mainMenu;

View File

@@ -0,0 +1,98 @@
import $ from 'jquery';
// import user from '../user/index.js';
import notifyLayout from './notifyLayout';
import notifyService from './notifyService';
import * as Rx from 'rx';
import merge from 'lodash.merge';
const notify = (services) => {
const { configService, localeService, appEvents } = services;
const defaultPollingTime = 10000;
const defaultConfig = {
url: null,
moduleId: null,
userId: null,
_isValid: false
};
const initialize = () => {
notifyLayout(services).initialize();
};
const createNotifier = (state) => {
if (state === undefined) {
return defaultConfig;
}
if (state.url === undefined) {
return defaultConfig;
}
return merge({}, defaultConfig, {
url: state.url,
moduleId: state.moduleId,
userId: state.userId,
_isValid: true
});
};
//const appendNotifications = (content) => notifyUiComponent().addNotifications(content);
const isValid = (notificationInstance) => notificationInstance._isValid || false;
const poll = (notificationInstance) => {
let notificationSource = Rx.Observable
.fromPromise(notifyService({
configService: configService
}).getNotification({
module: notificationInstance.moduleId,
usr: notificationInstance.userId
}));
notificationSource.subscribe(
x => onPollSuccess(x, notificationInstance),
e => onPollError(e, notificationInstance),
() => {}
);
};
const onPollSuccess = (data, notificationInstance) => {
// broadcast session refresh event
appEvents.emit('session.refresh', data);
// broadcast notification refresh event
if (data.changed.length > 0) {
appEvents.emit('notification.refresh', data);
}
// append notification content
notifyLayout(services).addNotifications(data.notifications);
let t = 120000;
if (data.apps && parseInt(data.apps, 10) > 1) {
t = Math.round((Math.sqrt(parseInt(data.apps, 10) - 1) * 1.3 * 60000));
}
window.setTimeout(poll, t, notificationInstance);
return true;
};
const onPollError = (data, notificationInstance) => {
if (data.status === 'disconnected' || data.status === 'session') {
appEvents.emit('user.disconnected', data);
return false;
}
window.setTimeout(poll, defaultPollingTime, notificationInstance);
};
return {
initialize,
/*appendNotifications: (content) => {
notifyLayout().addNotifications(content)
},*/
createNotifier,
isValid,
poll
};
};
export default notify;

View File

@@ -0,0 +1,245 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
// import user from '../user/index.js';
const notifyLayout = (services) => {
const { configService, localeService, appEvents } = services;
const $notificationBoxContainer = $('#notification_box');
const $notificationTrigger = $('.notification_trigger');
let $notificationDialog = $('#notifications-dialog');
const initialize = () => {
$notificationTrigger.on('mousedown', (event) => {
event.stopPropagation();
const $target = $(event.currentTarget);
if ($target.hasClass('open')) {
$notificationBoxContainer.hide();
$target.removeClass('open');
clear_notifications();
} else {
$notificationBoxContainer.show();
setBoxHeight();
$target.addClass('open');
read_notifications();
}
});
$(document).on('mousedown', () => {
if ($notificationTrigger.hasClass('open')) {
$notificationTrigger.trigger('click');
}
if ($notificationTrigger.hasClass('open')) {
$notificationBoxContainer.hide();
$notificationTrigger.removeClass('open');
clear_notifications();
}
});
$notificationBoxContainer
.on('mousedown', (event) => {
event.stopPropagation();
})
.on('mouseover', '.notification', (event) => {
$(event.currentTarget).addClass('hover');
})
.on('mouseout', '.notification', (event) => {
$(event.currentTarget).removeClass('hover');
})
.on('click', '.notification__print-action', (event) => {
event.preventDefault();
const $el = $(event.currentTarget);
const page = $el.data('page');
print_notifications(page);
});
$(window).bind('resize', function () {
setBoxPosition();
});
setBoxPosition();
};
const addNotifications = (notificationContent) => {
// var box = $('#notification_box');
$notificationBoxContainer.empty().append(notificationContent);
if ($notificationBoxContainer.is(':visible')) {
setBoxHeight();
}
if ($('.notification.unread', $notificationBoxContainer).length > 0) {
$('.counter', $notificationTrigger)
.empty()
.append($('.notification.unread', $notificationBoxContainer).length);
$('.counter', $notificationTrigger).css('visibility', 'visible');
} else {
$('.notification_trigger .counter').css('visibility', 'hidden').empty();
}
};
const setBoxHeight = () => {
//var box = $('#notification_box');
var not = $('.notification', $notificationBoxContainer);
var n = not.length;
var not_t = $('.notification_title', $notificationBoxContainer);
var n_t = not_t.length;
var h = not.outerHeight() * n + not_t.outerHeight() * n_t;
h = h > 350 ? 350 : h;
$notificationBoxContainer.stop().animate({height: h});
};
const setBoxPosition = () => {
if ($notificationTrigger.length > 0) {
var leftOffset = Math.round($notificationTrigger.offset().left);
if(leftOffset == 0) {
$notificationBoxContainer.css({
left: 20
});
}else {
$notificationBoxContainer.css({
left: Math.round($notificationTrigger.offset().left - 1)
});
}
}
};
const print_notifications = (page) => {
page = parseInt(page, 10);
var buttons = {};
buttons[localeService.t('fermer')] = function () {
$notificationDialog.dialog('close');
};
if ($notificationDialog.length === 0) {
$('body').append('<div id="notifications-dialog" class="loading"></div>');
$notificationDialog = $('#notifications-dialog');
}
$notificationDialog
.dialog({
title: $('#notification-title').val(),
autoOpen: false,
closeOnEscape: true,
resizable: false,
draggable: false,
modal: true,
width: 500,
height: 400,
overlay: {
backgroundColor: '#000',
opacity: 0.7
},
close: function (event, ui) {
$notificationDialog.dialog('destroy').remove();
}
}).dialog('option', 'buttons', buttons).dialog('open').on('click','.notification_next .notification__print-action', function (event) {
event.preventDefault();
var $el = $(event.currentTarget);
var page = $el.data('page');
print_notifications(page);
});
$.ajax({
type: 'GET',
url: '/user/notifications/',
dataType: 'json',
data: {
page: page
},
error: function (data) {
$notificationDialog.removeClass('loading');
},
timeout: function (data) {
$notificationDialog.removeClass('loading');
},
success: function (data) {
$notificationDialog.removeClass('loading');
if (page === 0) {
$notificationDialog.empty();
} else {
$('.notification_next', $notificationDialog).remove();
}
let i = 0;
for (i in data.notifications) {
var id = 'notif_date_' + i;
var date_cont = $('#' + id);
if (date_cont.length === 0) {
$notificationDialog.append('<div id="' + id + '"><div class="notification_title">' + data.notifications[i].display + '</div></div>');
date_cont = $('#' + id);
}
let j = 0;
for (j in data.notifications[i].notifications) {
var loc_dat = data.notifications[i].notifications[j];
var html = '<div style="position:relative;" id="notification_' + loc_dat.id + '" class="notification">' +
'<table style="width:100%;" cellspacing="0" cellpadding="0" border="0"><tr><td style="width:25px;">' +
loc_dat.icon +
'</td><td>' +
'<div style="position:relative;" class="' + loc_dat.classname + '">' +
loc_dat.text + ' <span class="time">' + loc_dat.time + '</span></div>' +
'</td></tr></table>' +
'</div>';
date_cont.append(html);
}
}
var next_ln = $.trim(data.next);
if (next_ln !== '') {
$notificationDialog.append('<div class="notification_next">' + next_ln + '</div>');
}
}
});
};
const read_notifications = () => {
var notifications = [];
$('#notification_box .unread').each(function () {
notifications.push($(this).attr('id').split('_').pop());
});
$.ajax({
type: 'POST',
url: '/user/notifications/read/',
data: {
notifications: notifications.join('_')
},
success: function (data) {
$('.notification_trigger .counter').css('visibility', 'hidden').empty();
}
});
};
const clear_notifications = () => {
var unread = $('#notification_box .unread');
if (unread.length === 0) {
return;
}
unread.removeClass('unread');
$('.notification_trigger .counter').css('visibility', 'hidden').empty();
};
return {
initialize,
addNotifications
};
};
export default notifyLayout;

View File

@@ -0,0 +1,46 @@
import {Observable} from 'rx';
// import {ajax} from 'jquery';
import $ from 'jquery';
let notifyService = (services) => {
const {configService} = services;
const url = configService.get('baseUrl');
const notificationEndPoint = 'session/notifications/';
let initialize = () => {
};
let getNotification = (data) => {
/*return ajax({
type: 'POST',
url: `${notificationEndPoint}`,
data: data,
dataType: 'json'
}).promise();*/
let notificationPromise = $.Deferred();
$.ajax({
type: 'POST',
url: `${url}${notificationEndPoint}`,
data: data,
dataType: 'json'
}).done((data) => {
data.status = data.status || false;
if (data.status === 'ok') {
notificationPromise.resolve(data);
} else {
notificationPromise.reject(data);
}
})
.fail((data) => {
notificationPromise.reject(data);
});
return notificationPromise.promise();
};
let stream = Observable.fromPromise(getNotification);
return {
initialize,
getNotification,
stream
};
};
export default notifyService;

View File

@@ -0,0 +1,257 @@
import $ from 'jquery';
import orderItem from './orderItem';
import dialog from './../../phraseanet-common/components/dialog';
const order = services => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const initialize = (options = {}) => {
const { $container } = options;
$container.on('click', '.order-open-action', function (event) {
event.preventDefault();
orderModal(event);
});
$container.on('click', '.order-notif', function (event) {
event.preventDefault();
$('#notification_box').hide();
orderModal(event, this);
});
};
const orderModal = (event, id) => {
var $dialog = dialog.create(services, {
size: 'Full',
title: $(event).attr('title')
});
$.ajax({
type: 'GET',
url: `${url}prod/order/`,
success: function (data) {
$dialog.setContent(data);
_onOrderReady($dialog);
if ($(id).length) {
$('#order_manager').css('opacity',0).hide(function () {
console.log($(id).data("id"));
$('#order_' + $(id).data("id")).trigger('click');
});
}
}
});
return true;
};
const _onOrderReady = $dialog => {
let filterDateSelected = false;
let perPage = window.orderData.perPage;
let date = window.orderData.date;
let dateSelection = window.orderData.dateSelection;
let dateSelectionText = window.orderData.dateSelectionText;
let info = window.orderData.info;
let tabSelection = window.orderData.tabSelection;
const FilterTodo = {
TODO: 'pending',
PROCESSED: 'processed'
};
const FilterDate = {
NO_FILTER: 'no_filter',
CURRENT_WEEK: 'current_week',
PAST_WEEK: 'past_week',
PAST_MONTH: 'past_month',
BEFORE: 'before',
AFTER: 'after'
};
/******** functions *********/
const setDateInPicker = date => {
if (date !== '') {
$('#datepicker').val(date);
}
};
const setDateSelection = element => {
var selection = $(element).attr('name');
dateSelection = FilterDate[selection];
setSelectionText(dateSelection);
clearAll();
$(element).addClass('active');
};
const setSelectionText = dateSelection => {
if (dateSelection === undefined) {
return;
}
$('.reset-btn').hide();
if (dateSelection !== FilterDate.NO_FILTER) {
if (
dateSelection === FilterDate.BEFORE ||
dateSelection === FilterDate.AFTER
) {
dateSelectionText =
$(
`#filter_box tbody tr td button[name=${dateSelection.toUpperCase()}]`
).html() +
' ' +
$('#datepicker').val();
var obj = {};
obj.date = $('#datepicker').val();
obj.type = dateSelection;
info.limit = obj;
} else {
dateSelectionText = $(
`#filter_box tbody tr td button[name=${dateSelection.toUpperCase()}]`
).html();
info.limit = null;
}
$('#filter-text').text(dateSelectionText);
$('.reset-btn').show();
} else {
$('#filter-text').text(window.orderData.noFilterText);
info.limit = null;
}
info.todo = tabSelection;
info.start = dateSelection;
};
const clearAll = () => {
$('#filter_box tbody tr td').children('button').each(function () {
$(this).removeClass('active');
});
};
const performRequest = () => {
$.ajax({
type: 'GET',
url: '../prod/order/',
data: info,
success: function (data) {
$dialog.setContent(data);
_onOrderReady($dialog);
}
});
};
const toggleFilterDate = () => {
if (!filterDateSelected) {
filterDateSelected = true;
$('#filter-date').addClass('active');
$('#filter_box').css('display', 'block');
} else {
filterDateSelected = false;
$('#filter-date').removeClass('active');
$('#filter_box').css('display', 'none');
}
};
$('#datepicker').datepicker({
beforeShow: () => {
setTimeout(() => {
$('.ui-datepicker').css('z-index', 999999);
}, 0);
},
changeYear: true,
changeMonth: true,
dateFormat: 'yy/mm/dd',
onSelect: value => {
date = value;
setSelectionText(dateSelection);
}
});
$('.reset-btn', $dialog.getDomElement()).bind('click', function (e) {
info.start = FilterDate.NO_FILTER;
setSelectionText(FilterDate.NO_FILTER);
$('#date-form').trigger('submit');
});
$('#ORDERPREVIEW').tabs({
activate: function (event, ui) {
if (ui.newPanel.selector === '#PROCESSED-ORDER') {
$('.pager-processed').show();
$('.pager-todo').hide();
tabSelection = FilterTodo.PROCESSED;
} else {
$('.pager-processed').hide();
$('.pager-todo').show();
tabSelection = FilterTodo.TODO;
}
}
});
$('#ORDERPREVIEW').tabs(
'option',
'active',
tabSelection === FilterTodo.PROCESSED ? 1 : 0
);
$('.pager-processed').hide();
$('a.self-ajax', $dialog.getDomElement()).bind('click', function (e) {
e.preventDefault();
var url = $(this).attr('href');
dialog.load(url);
});
$(
'#date-form .toggle-button-text',
$dialog.getDomElement()
).bind('click', function (e) {
setDateSelection(this);
//trigger request immediately for this week, past week, past month
if (
$(this).attr('name') !== 'BEFORE' &&
$(this).attr('name') !== 'AFTER'
) {
$('#date-form').trigger('submit');
}
});
$('.pager li', $dialog.getDomElement()).bind('click', function (e) {
info.todo = tabSelection;
info.start = dateSelection;
info['per-page'] = perPage;
info.page = $(this).find('a').attr('data-page');
performRequest();
});
$('tr.order_row', $dialog.getDomElement())
.bind('click', function (event) {
event.preventDefault();
let orderId = $(this).attr('id').split('_').pop();
orderItem(services).openModal(orderId);
})
.addClass('clickable');
$('#filter-date a').click(function () {
toggleFilterDate();
});
$('#date-form').submit(function (e) {
e.preventDefault();
performRequest();
toggleFilterDate();
});
setDateInPicker(date);
setSelectionText(dateSelection);
if (dateSelection !== FilterDate.NO_FILTER) {
let element = $(
`#filter_box tbody tr td button[name='${dateSelection.toUpperCase()}]`
);
setDateSelection(element);
}
};
return {
initialize,
orderModal
};
};
export default order;

View File

@@ -0,0 +1,938 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
import * as appCommons from './../../phraseanet-common';
import order from './index';
import _ from 'underscore';
import pym from 'pym.js';
const orderItem = services => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const openModal = orderId => {
let $dialog = dialog.create(services, {
size: 'Full'
});
$.ajax({
type: 'GET',
url: `${url}prod/order/${orderId}`,
success: function (data) {
$dialog.setContent(data);
_onOrderItemReady($dialog);
}
});
return true;
};
const _onOrderItemReady = $dialog => {
let userInfoIsVisible = false;
let itemCount = 0;
let elementsForValidation = [];
let readyForValidation = false;
let lastItemChosen = null;
const ELEMENT_TYPE = {
VALIDATED: 'validated',
DENIED: 'denied',
SELECTABLE: 'selectable',
SELECTED: 'selected',
WAITINGFORVALIDATION: 'waitingForValidation'
};
let trs = $('.order_list .order_row', $dialog.getDomElement());
let lastSelectedRow;
if ($('#notification_box').is(':visible')) {
$('.notification_trigger').trigger('mousedown');
}
$('.order_launcher', $dialog.getDomElement()).on('click', function (event) {
if (readyForValidation) {
if (confirm(window.orderItemData.translatedText.message)) {
order(services).orderModal(event);
}
} else {
order(services).orderModal(event);
}
});
$('#email-btn', $dialog.getDomElement()).on('click', function () {
let email = window.orderItemData.userEmail;
let subject = window.orderItemData.subject;
let body = window.orderItemData.body;
if (email !== null) {
let link =
'mailto:' +
email +
'?subject=' +
encodeURIComponent(subject) +
'&body=' +
encodeURIComponent(body);
window.location.href = link;
}
});
$(
'input[name="select-all"]',
$dialog.getDomElement()
).bind('click', function () {
let checkboxElement = this;
itemCount = 0;
let selectable = [];
$('.table-order .order_row').each(function () {
let el = $(this);
if (
checkboxElement.checked &&
el.hasClass(ELEMENT_TYPE.SELECTABLE)
) {
el.addClass(ELEMENT_TYPE.SELECTED);
itemCount++;
selectable.push(el);
} else {
el.removeClass(ELEMENT_TYPE.SELECTED);
}
});
//load preview for single item selected
if (selectable.length === 1) {
loadPreviewAndCaption(selectable[0]);
}
renderOrderDetailView(itemCount);
});
$(
'.order_list .order_row',
$dialog.getDomElement()
).bind('click', function (event) {
let $this = $(this);
lastItemChosen = $this;
//disable select all checkbox if selected
if ($('input[name="select-all"]').is(':checked')) {
$('input[name="select-all"]').prop('checked', false);
}
if (appCommons.utilsModule.is_ctrl_key(event)) {
if (!$this.hasClass(ELEMENT_TYPE.SELECTABLE)) {
return;
}
if ($this.hasClass(ELEMENT_TYPE.SELECTED)) {
$this.removeClass(ELEMENT_TYPE.SELECTED);
itemCount--;
} else {
$this.addClass(ELEMENT_TYPE.SELECTED);
itemCount++;
}
} else if (appCommons.utilsModule.is_shift_key(event)) {
if (!$this.hasClass(ELEMENT_TYPE.SELECTABLE)) {
return;
}
let currentIndex = $this.index('.order_list .order_row');
let prevIndex = lastSelectedRow.index('.order_list .order_row');
$(
'.order_list .selectable.selected',
$dialog.getDomElement()
).removeClass(ELEMENT_TYPE.SELECTED);
itemCount = 0;
selectRowsBetweenIndexes([prevIndex, currentIndex]);
} else {
$(
'.order_list .selectable.selected',
$dialog.getDomElement()
).removeClass(ELEMENT_TYPE.SELECTED);
if ($this.hasClass(ELEMENT_TYPE.SELECTABLE)) {
$this.addClass(ELEMENT_TYPE.SELECTED);
lastSelectedRow = $this;
}
itemCount = 1;
}
if (itemCount === 1) {
let selected = $(
'.order_list .selected',
$dialog.getDomElement()
);
loadPreviewAndCaption(selected);
}
renderOrderDetailView(itemCount);
});
function selectRowsBetweenIndexes(indexes) {
indexes.sort(function (a, b) {
return a - b;
});
for (let i = indexes[0]; i <= indexes[1]; i++) {
if ($(trs[i]).hasClass(ELEMENT_TYPE.SELECTABLE)) {
$(trs[i]).addClass(ELEMENT_TYPE.SELECTED);
itemCount++;
}
}
}
$(
'.captionTips, .captionRolloverTips, .infoTips',
$dialog.getDomElement()
).tooltip({
delay: 0
});
$('.previewTips', $dialog.getDomElement()).tooltip({
fixable: true
});
$('button.send', $dialog.getDomElement()).bind('click', function () {
updateValidation(ELEMENT_TYPE.VALIDATED);
//send_documents(order_id);
});
$('button.deny', $dialog.getDomElement()).bind('click', function () {
updateValidation(ELEMENT_TYPE.DENIED);
//deny_documents(order_id);
});
$('button.reset', $dialog.getDomElement()).bind('click',function(){
var itemsToBeReset = [];
$('.order_list .order_row.selected.waitingForValidation', $dialog.getDomElement()).each(function(i,n){
itemsToBeReset.push($(n));
});
//if item is not selected, delete item being previewed
if(itemsToBeReset.length == 0 && lastItemChosen) {
itemsToBeReset.push(lastItemChosen);
}
resetItemForValidation(itemsToBeReset);
toggleValidationButton();
//$('.order_row.selected').removeClass('to_be_denied');
//$('.order_row.selected').removeClass('to_be_validated');
});
$('.force_sender', $dialog.getDomElement()).bind('click', function () {
if (confirm(localeService.t('forceSendDocument'))) {
//updateValidation('validated');
let element_id = [];
element_id.push(
$(this)
.closest('.order_row')
.find('input[name=order_element_id]')
.val()
);
let order_id = $('input[name=order_id]').val();
do_send_documents(order_id, element_id, true);
}
});
$('#userInfo').hover(
function () {
let offset = $('#userInfo').position();
$('#userInfoPreview').css({
left: offset.left - $('#userInfoPreview').width() + 48,
top: offset.top + $('#userInfo').height() + 8
});
$('#userInfoPreview').show();
},
function () {
if (!userInfoIsVisible) {
$('#userInfoPreview').hide();
}
}
);
$('#userInfo').click(function () {
let offset = $('#userInfo').position();
if (!userInfoIsVisible) {
userInfoIsVisible = true;
$('#userInfoPreview').css({
left: offset.left - $('#userInfoPreview').width() + 48,
top: offset.top + $('#userInfo').height() + 8
});
$('#userInfoPreview').show();
} else {
userInfoIsVisible = false;
$('#userInfoPreview').hide();
}
});
let minimized_elements = $('.minimize');
$('.minimize').each(function () {
let t = $(this).text();
if (t.length < 60) return;
$(this).html(
t.slice(0, 60) +
'<span>... </span><a href="#" class="more">' +
window.orderItemData.translatedText.moreText +
'</a>' +
'<span style="display:none;">' +
t.slice(60, t.length) +
' <a href="#" class="less">' +
window.orderItemData.translatedText.lessText +
'</a></span>'
);
});
$('a.more', minimized_elements).click(function (event) {
event.preventDefault();
$(this).hide().prev().hide();
$(this).next().show();
});
$('a.less', minimized_elements).click(function (event) {
event.preventDefault();
$(this).parent().hide().prev().show().prev().show();
});
$('button.validate', $dialog.getDomElement()).bind('click', function (
event
) {
openValidationDialog(this, event);
return false;
});
$('.basket-btn').click(function (event) {
let titleCreate = window.orderItemData.translatedText.createTitle;
let type = $(this).attr('type');
var dialog_buttons = {};
dialog_buttons[titleCreate] = function () {
createBasket($innerDialog);
$(this).dialog('close');
};
let $innerDialog = $('#basket-window')
.dialog({
open: function (event, ui) {
$('.ui-dialog').css('z-index', 100000);
$('.ui-widget-overlay').css('z-index', 100000);
},
closeOnEscape: true,
width: 450,
height: 300,
modal: true,
draggable: false,
stack: false,
title: window.orderItemData.translatedText.dialogTitle,
overlay: {
backgroundColor: '#000',
opacity: 0.7
},
buttons: dialog_buttons
})
.dialog('open');
populateBasketDialog($innerDialog, type);
return false;
});
$('#myDropdown').on('click', function () {
if ($('#myDropdown').hasClass('open')) {
return;
}
if (
$('.order_list .selected', $dialog.getDomElement()).length > 0
) {
$('li[type="selected"]').removeClass('disabled');
} else {
//no selected item
if (!$('li[type="selected"]').hasClass('disabled')) {
$('li[type="selected"]').addClass('disabled');
}
}
});
function createBasket($innerDialog) {
let $form = $('form', $innerDialog);
let dialog = $innerDialog.closest('.ui-dialog');
let buttonPanel = dialog.find('.ui-dialog-buttonpane');
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
data: $form.serializeArray(),
dataType: 'json',
beforeSend: function () {
$(
":button:contains('" + localeService.t('create') + "')",
buttonPanel
)
.attr('disabled', true)
.addClass('ui-state-disabled');
},
success: function (data) {
let order_id = $('input[name=order_id]').val();
let success = '0';
if (data.success) {
success = '1';
}
var url =
'../prod/order/' +
order_id +
'/?success=' +
success +
'&action=basket' +
'&message=' +
encodeURIComponent(data.message);
reloadDialog(url);
appEvents.emit('workzone.refresh');
}
});
}
function populateBasketDialog($innerDialog, type) {
let lst = [];
let orderDialog = $innerDialog;
//set checkbox to true and disable it
$('input[name="lst"]', orderDialog).prop('checked', true);
$('.checkbox', orderDialog).css('visibility', 'hidden');
//set default name
let name = window.orderItemData.translatedText.defaultBasketTitle;
$('input[name="name"]', orderDialog).val(name);
let description = window.orderItemData.description;
let elements_ids = [];
switch (type) {
case 'denied':
$(
'.order_list .order_row.' + type,
$dialog.getDomElement()
).each(function (i, n) {
elements_ids.push($(n).attr('elementids'));
});
break;
case 'validated':
$(
'.order_list .order_row.' + type,
$dialog.getDomElement()
).each(function (i, n) {
elements_ids.push($(n).attr('elementids'));
});
break;
default:
//selected elements;
$(
'.order_list .order_row.' + type,
$dialog.getDomElement()
).each(function (i, n) {
elements_ids.push($(n).attr('elementids'));
});
}
$('textarea[name="description"]', orderDialog).val(description);
$('input[name="lst"]', orderDialog).val(elements_ids.join('; '));
}
function openValidationDialog(el, event) {
let submitTitle = window.orderItemData.translatedText.submit;
let resetTitle = window.orderItemData.translatedText.reset;
var dialog_buttons = {};
dialog_buttons[submitTitle] = function () {
//submit documents
submitDocuments($(this));
};
dialog_buttons[resetTitle] = function () {
if (confirm(window.orderItemData.translatedText.message)) {
resetAllItemForValidation();
toggleValidationButton();
$(this).dialog('close');
}
};
$('#validation-window')
.dialog({
open: function (event, ui) {
$('.ui-dialog').css('z-index', 100000);
$('.ui-widget-overlay').css('z-index', 100000);
},
closeOnEscape: true,
resizable: false,
width: 450,
height: 500,
modal: true,
draggable: false,
stack: false,
title: window.orderItemData.translatedText.validation,
buttons: dialog_buttons,
overlay: {
backgroundColor: '#000',
opacity: 0.7
}
})
.dialog('open');
createValidationTable();
}
function submitDocuments(dialogElem) {
let order_id = $('input[name=order_id]').val();
let validatedArrayNoForceIds = _.filter(
elementsForValidation,
function (elem) {
return (
elem.newState === ELEMENT_TYPE.VALIDATED &&
elem.oldState !== ELEMENT_TYPE.DENIED
);
}
).map(function (elem) {
return elem.elementId;
});
let validatedArrayWithForceIds = _.filter(
elementsForValidation,
function (elem) {
return (
elem.newState === ELEMENT_TYPE.VALIDATED &&
elem.oldState === ELEMENT_TYPE.DENIED
);
}
).map(function (elem) {
return elem.elementId;
});
let deniedArrayIds = _.filter(elementsForValidation, function (
elem
) {
return elem.newState === ELEMENT_TYPE.DENIED;
}).map(function (elem) {
return elem.elementId;
});
if (validatedArrayNoForceIds.length > 0) {
do_send_documents(order_id, validatedArrayNoForceIds, false);
}
if (validatedArrayWithForceIds.length > 0) {
do_send_documents(order_id, validatedArrayWithForceIds, true);
}
if (deniedArrayIds.length > 0) {
do_deny_documents(order_id, deniedArrayIds);
}
dialogElem.dialog('close');
}
function createValidationTable() {
$('.validation-content').empty();
let validatedArray = _.filter(elementsForValidation, function (
elem
) {
return elem.newState === ELEMENT_TYPE.VALIDATED;
});
let deniedArray = _.filter(elementsForValidation, function (elem) {
return elem.newState === ELEMENT_TYPE.DENIED;
});
if (validatedArray.length > 0) {
let html = '';
html +=
'<h5>' +
window.orderItemData.translatedText.youHaveValidated +
' ' +
validatedArray.length +
' ' +
window.orderItemData.translatedText.item +
(validatedArray.length === 1 ? '' : 's') +
'</h5>';
html += '<table class="validation-table">';
_.each(validatedArray, function (elem) {
html += '<tr>';
html +=
'<td width="25%" align="center">' +
elem.elementPreview[0].outerHTML +
'</td>';
html +=
'<td width="75%">' +
elem.elementTitle[0].outerHTML +
'</td>';
html += '</tr>';
});
html += '</table>';
$('.validation-content').append(html);
}
if (deniedArray.length > 0) {
let html = '';
html +=
'<h5>' +
window.orderItemData.translatedText.youHaveDenied +
' ' +
deniedArray.length +
' ' +
window.orderItemData.translatedText.item +
(deniedArray.length === 1 ? '' : 's') +
'</h5>';
html += '<table class="validation-table">';
_.each(deniedArray, function (elem) {
html += '<tr>';
html +=
'<td width="25%" align="center">' +
elem.elementPreview[0].outerHTML +
'</td>';
html +=
'<td width="75%">' +
elem.elementTitle[0].outerHTML +
'</td>';
html += '</tr>';
});
html += '</table>';
$('.validation-content').append(html);
}
}
function removeItemFromArray(item) {
var elementId = item.find('input[name=order_element_id]').val();
var found = _.where(elementsForValidation, {elementId: elementId});
if(found.length > 0) {
item.removeClass(ELEMENT_TYPE.WAITINGFORVALIDATION);
//replace content or row with original content
item[0].innerHTML = found[0].element[0].innerHTML;
//remove from array
elementsForValidation = _.without(elementsForValidation, found[0]);
}
}
function resetItemForValidation(itemsToBeReset) {
var elementArrayType = [];
itemsToBeReset.forEach(function(item){
removeItemFromArray(item);
updateButtonStatus(item.attr('class').split(/\s+/));
elementArrayType.push(item.attr('class').split(/\s+/));
});
if(elementsForValidation.length == 0) {
readyForValidation = false;
}
updateButtonStatusMultiple(elementArrayType);
toggleValidationButton();
//disable select all checkbox if selected
if($('input[name="select-all"]').is(':checked')){
$('input[name="select-all"]').prop('checked', false);
}
}
function resetAllItemForValidation() {
//var dialog = p4.Dialog.get(1);
$('.order_list .order_row', $dialog.getDomElement()).each(function(i,n){
removeItemFromArray($(n));
updateButtonStatus($(n).attr('class').split(/\s+/));
});
readyForValidation = false;
renderOrderDetailView(0);
}
function updateValidation(newState) {
let count = 0;
$('.order_list .order_row', $dialog.getDomElement()).each(function (
i,
n
) {
if (
$(n).hasClass(ELEMENT_TYPE.SELECTED) &&
!$(n).hasClass(ELEMENT_TYPE.VALIDATED) &&
!$(n).hasClass(ELEMENT_TYPE.DENIED) &&
!$(n).hasClass(ELEMENT_TYPE.WAITINGFORVALIDATION)
) {
createItemForValidation(
$(n),
ELEMENT_TYPE.SELECTABLE,
newState
);
count++;
} else if (
$(n).hasClass(ELEMENT_TYPE.SELECTED) &&
!$(n).hasClass(ELEMENT_TYPE.VALIDATED) &&
!$(n).hasClass(ELEMENT_TYPE.WAITINGFORVALIDATION)
) {
createItemForValidation(
$(n),
ELEMENT_TYPE.DENIED,
newState
);
count++;
}
$(n).removeClass(ELEMENT_TYPE.SELECTED);
});
//if item is not selected, delete item being previewed
if(count == 0 && lastItemChosen) {
createItemForValidation(lastItemChosen, ELEMENT_TYPE.SELECTABLE, newState);
count++;
}
readyForValidation = true;
toggleValidationButton();
//disable select all checkbox if selected
if ($('input[name="select-all"]').is(':checked')) {
$('input[name="select-all"]').prop('checked', false);
}
//multiple items selected
if (count > 1) {
$('#wrapper-padding').hide();
$('.external-order-action').hide();
$('#wrapper-multiple').hide();
$('#wrapper-no-item').show();
}
}
function createItemForValidation(element, oldState, newState) {
let order = {};
order.elementTitle = element.find('span');
order.elementPreview = element.find('.order_wrapper');
order.elementId = element
.find('input[name=order_element_id]')
.val();
order.element = element.clone(true);
order.oldState = oldState;
order.newState = newState;
elementsForValidation.push(order);
//element.removeClass('to_be_denied');
//element.removeClass('to_be_validated');
element.toggleClass(ELEMENT_TYPE.WAITINGFORVALIDATION);
//element.addClass('to_be_'+order.newState);
element.find('td:first-child').empty();
element
.find('td:first-child')
.append('<img style="cursor:help;" src="/assets/common/images/icons/to_be_'+order.newState+'.svg" title="">');
updateButtonStatus(element.attr('class').split(/\s+/));
}
function toggleValidationButton() {
if (readyForValidation) {
$('button.validate').prop('disabled', false);
$('button.validate').css('color', '#7CD21C');
} else {
$('button.validate').prop('disabled', true);
$('button.validate').css('color', '#737373');
}
}
function do_send_documents(order_id, elements_ids, force) {
let cont = $dialog.getDomElement();
$('button.deny, button.send', cont).prop('disabled', true);
$('.activity_indicator', cont).show();
$.ajax({
type: 'POST',
url: '../prod/order/' + order_id + '/send/',
dataType: 'json',
data: {
'elements[]': elements_ids,
force: force ? 1 : 0
},
success: function (data) {
let success = '0';
if (data.success) {
success = '1';
}
var url =
'../prod/order/' +
order_id +
'/?success=' +
success +
'&action=send';
reloadDialog(url);
},
error: function () {
$('button.deny, button.send', cont).prop('disabled', false);
$('.activity_indicator', cont).hide();
},
timeout: function () {
$('button.deny, button.send', cont).prop('disabled', false);
$('.activity_indicator', cont).hide();
}
});
}
function do_deny_documents(order_id, elements_ids) {
let cont = $dialog.getDomElement();
$('button.deny, button.send', cont).prop('disabled', true);
$('.activity_indicator', cont).show();
$.ajax({
type: 'POST',
url: '../prod/order/' + order_id + '/deny/',
dataType: 'json',
data: {
'elements[]': elements_ids
},
success: function (data) {
let success = '0';
if (data.success) {
success = '1';
}
var url =
'../prod/order/' +
order_id +
'/?success=' +
success +
'&action=deny';
reloadDialog(url);
},
error: function () {
$('button.deny, button.send', cont).prop('disabled', false);
$('.activity_indicator', cont).hide();
},
timeout: function () {
$('button.deny, button.send', cont).prop('disabled', false);
$('.activity_indicator', cont).hide();
}
});
}
function renderOrderDetailView(countSelected) {
if (countSelected > 1) {
$('#wrapper-padding').hide();
$('.external-order-action').hide();
$('#wrapper-multiple').show();
$('#wrapper-no-item').hide();
let elementArrayType = [];
$(
'.order_list .selectable.selected',
$dialog.getDomElement()
).each(function (i, n) {
//elementArrayType = _.union(elementArrayType, $(n).attr('class').split(/\s+/));
elementArrayType.push($(n).attr('class').split(/\s+/));
});
updateButtonStatusMultiple(elementArrayType);
//updateButtonStatus(elementArrayType);
} else if (countSelected === 1) {
$('#wrapper-padding').show();
$('.external-order-action').show();
$('#wrapper-multiple').hide();
$('#wrapper-no-item').hide();
} else {
$('#wrapper-padding').hide();
$('.external-order-action').hide();
$('#wrapper-multiple').hide();
$('#wrapper-no-item').show();
}
$('#preview-layout-multiple .title').html(countSelected);
}
function updateButtonStatusMultiple(elementArrayType) {
$('#order-action button.deny, #order-action button.send').hide();
let countObj = elementArrayType.reduce(
function (m, v) {
for (let k in m) {
if (~v.indexOf(k)) m[k]++;
}
return m;
},
{ validated: 0, selectable: 0, waitingForValidation: 0 }
);
let html = '';
if (countObj.validated > 0) {
html +=
'<p>' +
window.orderItemData.translatedText.itemsAlreadySent +
': ' +
countObj.validated +
'</p>';
}
if (countObj.waitingForValidation > 0) {
html +=
'<p>' +
window.orderItemData.translatedText.itemsWaitingValidation +
': ' +
countObj.waitingForValidation +
'</p>';
}
//for the remaining items
let remaining =
countObj.selectable -
(countObj.validated + countObj.waitingForValidation);
if (remaining > 0) {
html +=
'<p>' +
window.orderItemData.translatedText.nonSentItems +
': ' +
remaining +
'</p>';
$('#order-action button.deny, #order-action button.send').prop(
'disabled',
false
);
$(
'#order-action button.deny, #order-action button.send'
).show();
}
$('#wrapper-multiple #text-content').empty();
$('#wrapper-multiple #text-content').append(html);
}
/* *
* function to update status of send and deny button
* params - array of type for each button selected
*/
function updateButtonStatus(elementArrayType) {
if (_.contains(elementArrayType, ELEMENT_TYPE.VALIDATED)) {
$('#order-action button.deny, #order-action button.send, #order-action button.reset').hide();
$('#order-action span.action-text').html(
window.orderItemData.translatedText.alreadyValidated +
'<i class="fa fa-check" aria-hidden="true"></i>'
);
$('#order-action span.action-text').show();
} else if (
_.contains(elementArrayType, ELEMENT_TYPE.WAITINGFORVALIDATION)
) {
$('#order-action button.deny, #order-action button.send, #order-action span.action-text').hide();
$('#order-action button.reset').show();
//$('#order-action button.send').show();
//$('#order-action button.send').prop('disabled', true);
} else if (_.contains(elementArrayType, ELEMENT_TYPE.DENIED)) {
$('#order-action button.deny, #order-action button.reset').hide();
$('#order-action span.action-text').html('window.orderItemData.translatedText.refusedPreviously');
//$('#order-action button.send').prop('disabled', false);
$('#order-action button.send, #order-action span.action-text').show();
} else {
// $('#order-action button.send, #order-action button.deny').prop('disabled', false);
$('#order-action button.send, #order-action button.deny').show();
$('#order-action span.action-text, #order-action button.reset').hide();
}
}
function loadPreviewAndCaption(elem) {
$('#preview-layout').empty();
$('#caption-layout').empty();
updateButtonStatus(elem.attr('class').split(/\s+/));
let elementids = elem.attr('elementids').split('_');
let sbasId = elementids[0];
let recordId = elementids[1];
let prevAjax = $.ajax({
type: 'GET',
url: '../prod/records/record/' + sbasId + '/' + recordId + '/',
dataType: 'json',
success: function (data) {
if (data.error) {
return;
}
$('#preview-layout').append(data.html_preview);
$('#caption-layout').append(data.desc);
}
});
}
function reloadDialog(url) {
const baseUrl = configService.get('baseUrl');
$.ajax({
type: 'GET',
url: `${baseUrl}${url}`,
success: function (data) {
if (data.error) {
return;
}
$dialog.setContent(data);
_onOrderItemReady($dialog);
}
});
}
};
return {
openModal
};
};
export default orderItem;

View File

@@ -0,0 +1,416 @@
import $ from 'jquery';
import * as appCommons from './../../phraseanet-common';
let highlight = require('imports-loader?$=jquery!../utils/jquery-plugins/highlight');
let colorpicker = require('imports-loader?$=jquery!../utils/jquery-plugins/colorpicker/colorpicker');
const preferences = services => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const initialize = (options = {}) => {
const { $container } = options;
render();
$container.on('change', '#ADVSRCH_FILTER_FACET', event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref('facet', $el.prop('checked'));
appEvents.emit('search.updateFacetData');
appEvents.emit('search.doRefreshState');
});
$container.on('click', '.open-preferences', event => {
event.preventDefault();
openModal(event);
});
$container.on('click', '.preferences-options-submit', event => {
event.preventDefault();
submitState();
});
$container.on('change', '.preferences-options-start-page', event => {
event.preventDefault();
setInitialStateOptions();
});
$container.on('change', '.preferences-options-search-reload', event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref(
'advanced_search_reload',
$el.prop('checked') ? '1' : '0'
);
});
$container.on('change', '.preferences-options-use-truncation', event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref(
'use_truncation',
$el.prop('checked') ? '1' : '0'
);
});
$container.on(
'change',
'.preferences-options-presentation-thumbnail',
event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref('view', $el.val());
appEvents.emit('search.doRefreshState');
}
);
$container.on(
'change',
'.preferences-options-presentation-list',
event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref('view', $el.val());
appEvents.emit('search.doRefreshState');
}
);
$container.on(
'change',
'.preferences-options-rollover-caption',
event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref('rollover_thumbnail', $el.val());
appEvents.emit('search.doRefreshState');
}
);
$container.on(
'change',
'.preferences-options-rollover-preview',
event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref('rollover_thumbnail', $el.val());
appEvents.emit('search.doRefreshState');
}
);
$container.on(
'change',
'.preferences-options-technical-display',
event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref('technical_display', $el.val());
appEvents.emit('search.doRefreshState');
}
);
$container.on(
'change',
'.preferences-options-rollover-preview',
event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref('technical_display', $el.val());
appEvents.emit('search.doRefreshState');
}
);
$container.on(
'change',
'.preferences-options-rollover-preview',
event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref('technical_display', $el.val());
appEvents.emit('search.doRefreshState');
}
);
$container.on(
'change',
'.preferences-options-doctype-display',
event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref(
'doctype_display',
$el.prop('checked') ? '1' : '0'
);
appEvents.emit('search.doRefreshState');
}
);
$container.on('change', '.preferences-options-basket-status', event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref(
'basket_status_display',
$el.prop('checked') ? '1' : '0'
);
});
$container.on(
'change',
'.preferences-options-basket-caption',
event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref(
'basket_caption_display',
$el.prop('checked') ? '1' : '0'
);
}
);
$container.on('change', '.preferences-options-basket-title', event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref(
'basket_title_display',
$el.prop('checked') ? '1' : '0'
);
});
$container.on('change', '.preferences-options-basket-type', event => {
let $el = $(event.currentTarget);
event.preventDefault();
appCommons.userModule.setPref(
'basket_type_display',
$el.prop('checked') ? '1' : '0'
);
});
$container.on('click', '.preference-change-theme-action', event => {
let $el = $(event.currentTarget);
let color = $el.data('theme');
let minified = configService.get('debug') ? '' : '.min';
// setCss()
$('#skinCss').attr(
'href',
`/assets/production/skin-${color}${minified}.css`
);
/* $.post(`${configService.get('baseUrl')}/user/preferences/`, {
prop: 'css',
value: color,
t: Math.random()
});*/
var skin = '';
$.ajax({
type: 'POST',
url: `${url}user/preferences/`,
data: {
prop: 'css',
value: color,
t: Math.random()
},
success: function (data) {
$('body').removeClass().addClass('PNB ' + color);
/* console.log('saved:' + color);*/
return;
}
});
});
$container.on('change', '.preferences-options-collection-order', event => {
let el = $('#look_box_settings select[name=orderByName]');
event.preventDefault();
appCommons.userModule.setPref(
'order_collection_by',
el.val()
);
});
$('.preferences-facet-order').change( function (event) {
let el = $('.look_box_settings select[name=orderFacet]');
event.preventDefault();
appCommons.userModule.setPref(
'order_facet',
el.val()
);
appEvents.emit('search.updateFacetData');
});
$('.preferences-facet-values-order').change( function (event) {
let el = $('.look_box_settings select[name=facetValuesOrder]');
event.preventDefault();
appCommons.userModule.setPref(
'facet_values_order',
el.val()
);
appEvents.emit('search.updateFacetData');
});
$container.on('change', '.upload-options-collection', event => {
let el = $('.settings-box select[name=base_id]');
event.preventDefault();
appCommons.userModule.setPref(
'upload_last_used_collection',
el.val()
);
});
$('#nperpage_slider').slider({
value: parseInt($('#nperpage_value').val(), 10),
min: 10,
max: 100,
step: 10,
slide: function (event, ui) {
$('#nperpage_value').val(ui.value);
},
stop: function (event, ui) {
appCommons.userModule.setPref(
'images_per_page',
$('#nperpage_value').val()
);
}
});
$('#sizeAns_slider').slider({
value: parseInt($('#sizeAns_value').val(), 10),
min: 90,
max: 270,
step: 10,
slide: function (event, ui) {
$('#sizeAns_value').val(ui.value);
},
stop: function (event, ui) {
appCommons.userModule.setPref(
'images_size',
$('#sizeAns_value').val()
);
}
});
$('#backcolorpickerHolder').ColorPicker({
flat: true,
color: '404040',
livePreview: false,
eventName: 'mouseover',
onSubmit: function (hsb, hex, rgb, el) {
var back_hex = '';
var unactive = '';
var sim_b;
if (hsb.b >= 50) {
back_hex = '000000';
sim_b = 0.1 * hsb.b;
} else {
back_hex = 'FFFFFF';
sim_b = 100 - 0.1 * (100 - hsb.b);
}
sim_b = 0.1 * hsb.b;
var sim_rgb = appCommons.utilsModule.hsl2rgb(
hsb.h,
hsb.s,
sim_b
);
var sim_hex = appCommons.utilsModule.RGBtoHex(
sim_rgb.r,
sim_rgb.g,
sim_rgb.b
);
appCommons.userModule.setPref('background-selection', hex);
appCommons.userModule.setPref(
'background-selection-disabled',
sim_hex
);
appCommons.userModule.setPref('fontcolor-selection', back_hex);
$('style[title=color_selection]').empty();
var datas =
'.diapo.selected,#reorder_box .diapo.selected, #EDIT_ALL .diapo.selected, .list.selected, .list.selected .diapo' +
'{' +
' COLOR: #' +
back_hex +
';' +
' BACKGROUND-COLOR: #' +
hex +
';' +
'}';
$('style[title=color_selection]').empty().text(datas);
}
});
$('#backcolorpickerHolder')
.find('.colorpicker_submit')
.append($('#backcolorpickerHolder .submiter'))
.bind('click', function () {
$(this).highlight('#CCCCCC');
});
$('#look_box .tabs').tabs();
};
const render = () => {
let availableThemes = configService.get('availableThemes');
let themeTpl = '';
for (let t in availableThemes) {
let curTheme = availableThemes[t];
themeTpl += `<div class="colorpicker_box preference-change-theme-action" data-theme="${curTheme.name}" style="width:16px;height:16px;background-color:#${curTheme.name};">&nbsp;</div>`;
}
// generates themes
$('#theme-container').empty().append(themeTpl);
};
// look_box
function setInitialStateOptions() {
var el = $('#look_box_settings select[name=start_page]');
switch (el.val()) {
case 'LAST_QUERY':
case 'PUBLI':
case 'HELP':
$('#look_box_settings input[name=start_page_value]').hide();
break;
case 'QUERY':
$('#look_box_settings input[name=start_page_value]').show();
break;
default:
}
}
function submitState() {
var el = $('#look_box_settings select[name=start_page]');
var val = el.val();
var start_page_query = $(
'#look_box_settings input[name=start_page_value]'
).val();
if (val === 'QUERY') {
appCommons.userModule.setPref('start_page_query', start_page_query);
}
appCommons.userModule.setPref('start_page', val);
}
function openModal(event) {
$('#look_box')
.dialog({
closeOnEscape: true,
resizable: false,
width: 450,
height: 500,
modal: true,
draggable: false,
overlay: {
backgroundColor: '#000',
opacity: 0.7
}
})
.dialog('open');
}
return {
initialize,
openModal
};
};
export default preferences;

View File

@@ -0,0 +1,454 @@
import $ from 'jquery';
let lazyload = require('jquery-lazyload');
import dialog from './../../phraseanet-common/components/dialog';
const publication = (services) => {
let ajaxState = {
query: null,
isRunning: false
};
let $answers;
let curPage;
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const initialize = () => {
$answers = $('#answers');
// refresh current view
$answers.on('click', '.feed_reload', function (event) {
event.preventDefault();
fetchPublications(curPage);
});
// navigate to a specific feed
$answers.on('click', '.ajax_answers', function (event) {
event.preventDefault();
var $this = $(this);
var append = $this.hasClass('append');
var noScroll = $this.hasClass('no_scroll');
_fetchRemote($(event.currentTarget).attr('href'), {})
.then(function (data) {
if (!append) {
$answers.empty();
if (!noScroll) {
$answers.scrollTop(0);
}
$answers.append(data);
$answers.find('img.lazyload').lazyload({
container: $answers
});
} else {
$('.see_more.loading', $answers).remove();
$answers.append(data);
$answers.find('img.lazyload').lazyload({
container: $answers
});
if (!noScroll) {
$answers.animate({
scrollTop: ($answers.scrollTop() + $answers.innerHeight() - 80)
});
}
}
appEvents.emit('search.doAfterSearch');
});
});
// subscribe_rss
$answers.on('click', '.subscribe_rss', function (event) {
event.preventDefault();
let $this = $(this);
let renew = false;
/*if (typeof (renew) === 'undefined') {
renew = 'false';
} else {
renew = renew ? 'true' : 'false';
}*/
var buttons = {};
buttons[localeService.t('renewRss')] = function () {
$this.trigger({
type: 'click',
renew: true
});
};
buttons[localeService.t('fermer')] = function () {
$('#DIALOG').empty().dialog('destroy');
};
event.stopPropagation();
$.ajax({
type: 'GET',
url: $this.attr('href') + (event.renew === true ? '?renew=true' : ''),
dataType: 'json',
success: function (data) {
if (data.texte !== false && data.titre !== false) {
if ($('#DIALOG').data('ui-dialog')) {
$('#DIALOG').dialog('destroy');
}
$('#DIALOG').attr('title', data.titre)
.empty()
.append(data.texte)
.dialog({
autoOpen: false,
closeOnEscape: true,
resizable: false,
draggable: false,
modal: true,
buttons: buttons,
width: 650,
height: 250,
overlay: {
backgroundColor: '#000',
opacity: 0.7
},
open: function() {
$('#copy-feed').on('click', function (event) {
event.preventDefault();
var copyText = document.getElementById('input-select-copy');
/* Select the text field */
copyText.select();
copyText.setSelectionRange(0, 99999); /*For mobile devices*/
document.execCommand('copy');
});
},
}).dialog('open');
}
}
});
});
// edit a feed
$answers.on('click', '.feed .entry a.feed_edit', function () {
var $this = $(this);
$.ajax({
type: 'GET',
url: $this.attr('href'),
dataType: 'html',
success: function (data) {
return openModal(data);
}
});
return false;
});
// remove a feed
$answers.on('click', '.feed .entry a.feed_delete', function () {
if (!confirm('etes vous sur de vouloir supprimer cette entree ?')) {
return false;
}
var $this = $(this);
$.ajax({
type: 'POST',
url: $this.attr('href'),
dataType: 'json',
success: function (data) {
if (data.error === false) {
var $entry = $this.closest('.entry');
$entry.animate({
height: 0,
opacity: 0
}, function () {
$entry.remove();
});
} else {
alert(data.message);
}
}
});
return false;
});
$answers.on('mouseover', '.feed .entry', function () {
$(this).addClass('hover');
});
$answers.on('mouseout', '.feed .entry', function () {
$(this).removeClass('hover');
});
$answers.on('click', '.see_more a', function (event) {
const $see_more = $(this).closest('.see_more');
$see_more.addClass('loading');
});
};
const _fetchRemote = function (url, data) {
let page = 0;
if (data.page === undefined) {
page = data.page;
}
ajaxState.query = $.ajax({
type: 'GET',
url: url,
dataType: 'html',
data: data,
beforeSend: function () {
if (ajaxState.isRunning && ajaxState.query.abort) {
ajaxState.query.abort();
}
if (page === 0) {
appEvents.emit('search.doClearSearch');
}
ajaxState.isRunning = true;
$answers.addClass('loading');
},
error: function () {
ajaxState.isRunning = false;
$answers.removeClass('loading');
},
timeout: function () {
ajaxState.isRunning = false;
$answers.removeClass('loading');
},
success: function (data) {
ajaxState.isRunning = false;
}
});
return ajaxState.query;
};
function checkFeedVFieldError() {
if ($('.feed_warning').hasClass('alert-error')) {
$('.ui-dialog-buttons').find('button').eq(1).prop('disabled', true);
} else {
$('.ui-dialog-buttons').find('button').eq(1).prop('disabled', false);
}
}
function feedFieldValidator (field, feedWarning , length) {
field.on('change keyup',function () {
if ( $(this).val().length > length){
feedWarning.addClass('alert alert-error');
}else {
feedWarning.removeClass('alert alert-error');
}
checkFeedVFieldError();
});
}
var openModal = function (data) {
let buttons = {};
let modal = dialog.create(services, {
size: 'Full',
closeOnEscape: true,
closeButton: true,
title: localeService.t('Publication')
});
//Add custom class to dialog wrapper
$('.dialog-Full').closest('.ui-dialog').addClass('black-dialog-wrap publish-dialog');
modal.setContent(data);
buttons[localeService.t('valider')] = onSubmitPublication;
modal.setOption('buttons', buttons);
let $feeds_item = $('.feeds .feed', modal.getDomElement());
let $form = $('form.main_form', modal.getDomElement());
let $feed_title_field = $('#feed_add_title', modal.getDomElement());
let $feed_title_warning = $('.feed_title_warning', modal.getDomElement());
let $feed_subtitle_field = $('#feed_add_subtitle', modal.getDomElement());
let $feed_subtitle_warning = $('.feed_subtitle_warning', modal.getDomElement());
feedFieldValidator($feed_title_field,$feed_title_warning, 128);
feedFieldValidator($feed_subtitle_field,$feed_subtitle_warning, 1024);
$feeds_item.bind('click', function () {
$feeds_item.removeClass('selected');
$(this).addClass('selected');
$('input[name="feed_id"]', $form).val($('input', this).val());
}).hover(function () {
$(this).addClass('hover');
}, function () {
$(this).removeClass('hover');
});
$form.bind('submit', function () {
return false;
});
let formMode = 'create';
// is edit mode?
if ($('input[name="item_id"]').length > 0) {
formMode = 'edit';
}
$('#modal_feed .record_list').sortable({
placeholder: 'ui-state-highlight',
stop: function (event, ui) {
var lst = [];
$('#modal_feed .record_list .sortable form').each(function (i, el) {
if (formMode === 'create') {
lst.push($('input[name="sbas_id"]', el).val() + '_' + $('input[name="record_id"]', el).val());
} else {
lst.push($('input[name="item_id"]', el).val());
}
});
$('#modal_feed form.main_form input[name="lst"]').val(lst.join(';'));
}
});
return;
};
const onSubmitPublication = () => {
var $dialog = dialog.get(1);
var error = false;
var $form = $('form.main_form', $dialog.getDomElement());
$('.required_text', $form).each(function (i, el) {
if ($.trim($(el).val()) === '') {
$(el).addClass('error');
error = true;
}
});
if (error) {
alert(localeService.t('feed_require_fields'));
}
if ($('input[name="feed_id"]', $form).val() === '') {
alert(localeService.t('feed_require_feed'));
error = true;
}
if (error) {
return false;
}
$.ajax({
type: 'POST',
url: $form.attr('action'),
data: $form.serializeArray(),
dataType: 'json',
beforeSend: function () {
$('button', $dialog.getDomElement()).prop('disabled', true);
},
error: function () {
$('button', $dialog.getDomElement()).prop('disabled', false);
},
timeout: function () {
$('button', $dialog.getDomElement()).prop('disabled', false);
},
success: function (data) {
$('.state-navigation').trigger('click');
$('button', $dialog.getDomElement()).prop('disabled', false);
if (data.error === true) {
alert(data.message);
return;
}
if ($('form.main_form', $dialog.getDomElement()).hasClass('entry_update')) {
var id = $('form input[name="entry_id"]', $dialog.getDomElement()).val();
var container = $('#entry_' + id);
container.replaceWith(data.datas);
container.hide().fadeIn();
// @TODO: something was happening here
$answers.find('img.lazyload').lazyload({
container: $answers
});
}
$dialog.close(1);
}
});
}
var fetchPublications = function (page) {
if (page === undefined && $answers !== undefined) {
// @TODO $answers can be undefined
$answers.empty();
}
if ($answers !== undefined) {
curPage = page;
return _fetchRemote(`${url}prod/feeds/`, {
page: page
})
.then(function (data) {
$('.next_publi_link', $answers).remove();
$answers.append(data);
$answers.find('img.lazyload').lazyload({
container: $answers
});
appEvents.emit('search.doAfterSearch');
if (page > 0) {
$answers.stop().animate({
scrollTop: $answers.scrollTop() + $answers.height()
}, 700);
}
return;
});
}
};
var publishRecords = function (type, value) {
var options = {
lst: '',
ssel: '',
act: ''
};
switch (type) {
case 'IMGT':
case 'CHIM':
options.lst = value;
break;
case 'STORY':
options.story = value;
break;
case 'SSTT':
options.ssel = value;
break;
default:
}
$.post(`${url}prod/feeds/requestavailable/`
, options
, function (data) {
return openModal(data);
});
return;
};
const activatePublicationState = () => {
appEvents.emit('publication.fetch');
}
appEvents.listenAll({
'publication.activeState': activatePublicationState,
'publication.fetch': fetchPublications
});
return {
initialize,
fetchPublications,
publishRecords,
openModal
};
};
export default publication;

View File

@@ -0,0 +1,22 @@
import $ from 'jquery';
const addToBasket = (services) => {
const { configService, localeService, appEvents } = services;
let $container = null;
const initialize = () => {
$container = $('body');
$container.on('click', '.record-add-to-basket-action', (event) => {
event.preventDefault();
let $el = $(event.currentTarget);
let dbId = $el.data('db-id');
let recordId = $el.data('record-id');
appEvents.emit('workzone.doAddToBasket', {
dbId, recordId, event: event.currentTarget
});
});
};
return { initialize };
};
export default addToBasket;

View File

@@ -0,0 +1,31 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
import recordBridge from './recordBridge/index';
const bridgeRecord = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const openModal = (datas) => {
const $dialog = dialog.create(services, {
size: 'Full',
title: 'Bridge',
loading: false
});
return $.post(`${url}prod/bridge/manager/`, datas, function (data) {
$dialog.setContent(data);
_onDialogReady();
return;
});
};
const _onDialogReady = () => {
recordBridge(services).initialize();
};
return { openModal };
};
export default bridgeRecord;

View File

@@ -0,0 +1,185 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
const deleteRecord = (services) => {
const {configService, localeService, appEvents} = services;
const url = configService.get('baseUrl');
let workzoneSelection = [];
let searchSelection = [];
const openModal = (datas) => {
let $dialog = dialog.create(services, {
size: '480x160',
title: localeService.t('warning')
});
$.ajax({
type: 'POST',
url: `${url}prod/records/delete/what/`,
dataType: 'html',
data: datas,
success: function (data) {
$dialog.setOption('height', 'auto');
$dialog.setContent(data);
//reset top position of dialog
$dialog.getDomElement().offsetParent().css('top', ($(window).height() - $dialog.getDomElement()[0].clientHeight) / 2);
_onDialogReady();
}
});
return false;
};
const _onDialogReady = () => {
var $dialog = dialog.get(1);
var $dialogBox = $dialog.getDomElement();
var $closeButton = $('button.ui-dialog-titlebar-close', $dialogBox.parent());
var $cancelButton = $('button.cancel', $dialogBox);
var $delChildren = $("input[name='del_children']", $dialogBox);
var titleBox = $(".ui-dialog-title", $dialogBox.parent());
titleBox.prepend('<i class="fa fa-exclamation-triangle" style="margin-right: 10px"></i>');
/**
* the checkbox "delete stories children too" changes
**/
$delChildren.bind("change", function () {
fSetDelChildren($(this).is(':checked'));
});
$cancelButton.bind('click', function () {
$dialog.close();
});
/**
* set the dlg content according the "delete children" ckbox
* the counts (records will be deleted, records rejected...) will update
*/
var fSetDelChildren = function (delChildren) {
if (delChildren) {
$("#delete_records_parent_only").hide();
$("#delete_records_with_children").show();
} else {
$("#delete_records_with_children").hide();
$("#delete_records_parent_only").show();
}
};
/**
* click ok : run delete tasks
*/
$('button.submiter', $dialogBox).bind('click', function () {
let CHUNKSIZE = 3,
MAXTASKS = 5;
let $this = $(this);
let $form = $(this).closest("form"),
$counter = $form.find(".to_delete_count"),
$trash_counter = $form.find(".to_trash_count"),
$loader = $form.find(".form-action-loader");
let lst = $("input[name='lst']", $form).val().split(';');
/**
* same parameters for every delete call, except the list of (CHUNKSIZE) records
* nb: do NOT ask to delete children since they're included in lst
*/
let ajaxParms = {
type: $form.attr("method"),
url: $form.attr("action"),
data: {
'lst': "" // set in f
},
dataType: "json"
};
let runningTasks = 0, // number of running tasks
canceling = false;
/**
* cancel or close dlg will ask tasks to stop
*/
let fCancel = function () {
$closeButton.hide();
$cancelButton.hide();
$loader.show();
canceling = true;
};
/**
* task fct : will loop itself while there is job to do
*
* @param iTask (int) The task number 0...MAXTASKS-1, usefull only to debug
*/
let fTask = function (iTask) {
if (canceling) {
return;
}
// pop & truncate
ajaxParms.data.lst = lst.splice(0, CHUNKSIZE).join(';');
$.ajax(ajaxParms)
.success(function (data) { // prod feedback only if result ok
$.each(data, function (i, n) {
let imgt = $('#IMGT_' + n),
chim = $('.CHIM_' + n),
stories = $('.STORY_' + n);
$('.doc_infos', imgt).remove();
try {
$imgt.draggable("destroy");
} catch (e) {
// no-op
}
imgt.unbind("click")
.removeAttr("ondblclick")
.removeClass("selected")
.removeClass("IMGT")
.find("img")
.unbind();
imgt.find(".thumb img")
.attr("src", "/assets/common/images/icons/deleted.png")
.css({
width: '100%',
height: 'auto',
margin: '0 10px',
top: '0'
});
chim.parent().slideUp().remove();
imgt.find(".status,.title,.bottom").empty();
appEvents.emit('search.selection.remove', {records: n});
if (stories.length > 0) {
appEvents.emit('workzone.refresh');
} else {
appEvents.emit('workzone.selection.remove', {records: n});
}
});
})
.then(function () { // go on even in case of error
// countdown
$counter.html(lst.length);
$trash_counter.html(lst.length);
if (lst.length === 0 || canceling) {
// end of a task
if (--runningTasks === 0) {
$dialog.close();
$('#nbrecsel').empty().append(lst.length);
}
} else {
// don't recurse, give a delay to running fct to end
window.setTimeout(fTask, 10, iTask);
}
});
};
// cancel or close the dlg is the same : wait
$dialog.setOption('closeOnEscape', false);
$closeButton.unbind("click").bind("click", fCancel);
$cancelButton.unbind("click").bind("click", fCancel);
// run a bunch of tasks in //
for (runningTasks = 0; runningTasks < MAXTASKS && lst.length > 0; runningTasks++) {
fTask(runningTasks); // pass the task his index to get nice console logs
}
});
fSetDelChildren(false);
};
return {openModal};
}
export default deleteRecord;

View File

@@ -0,0 +1,160 @@
import $ from 'jquery';
import recordEditorService from './recordEditor/index';
import * as appCommons from './../../phraseanet-common';
const editRecord = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
let $container = null;
let recordEditor = recordEditorService(services);
appEvents.listenAll({
'record.doEdit': _doEdit
});
const initialize = () => {
$container = $('body');
$container.on('click', '.edit-record-action', function (event) {
event.preventDefault();
let $el = $(event.currentTarget);
let type = '';
let kind = $el.data('kind');
let idContent = $el.data('id');
switch (kind) {
case 'basket':
type = 'SSTT';
break;
case 'record':
type = 'IMGT';
break;
default:
}
_doEdit({type: type, value: idContent});
});
};
const openModal = (datas) => {
$('#EDITWINDOW').empty().addClass('loading');
//commonModule.showOverlay(2);
$('#EDITWINDOW').show();
$.ajax({
url: `${url}prod/records/edit/`,
type: 'POST',
dataType: 'html',
data: datas,
success: (data) => {
$('#EDITWINDOW').removeClass('loading').empty().html(data);
// let recordEditor = recordEditorService(services);
recordEditor.initialize({
$container: $('#EDITWINDOW'),
recordConfig: window.recordEditorConfig
});
$('#tooltip').hide();
return;
},
error: function (XHR, textStatus, errorThrown) {
if (XHR.status === 0) {
return false;
}
}
});
return true;
};
// open Modal
function _doEdit(options) {
let {type, value} = options;
var datas = {
lst: '',
ssel: '',
act: ''
};
switch (type) {
case 'IMGT':
datas.lst = value;
break;
case 'SSTT':
datas.ssel = value;
break;
case 'STORY':
datas.story = value;
break;
default:
}
return openModal(datas);
}
const onGlobalKeydown = (event, specialKeyState) => {
if (specialKeyState === undefined) {
let specialKeyState = {
isCancelKey: false,
isShortcutKey: false
};
}
switch (event.keyCode) {
case 9: // tab ou shift-tab
fieldNavigate(
event,
appCommons.utilsModule.is_shift_key(event) ? -1 : 1
);
specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
break;
case 27:
cancelChanges({ event });
specialKeyState.isShortcutKey = true;
break;
case 33: // pg up
if (
!options.textareaIsDirty ||
validateFieldChanges(event, 'ask_ok')
) {
skipImage(event, 1);
}
specialKeyState.isCancelKey = true;
break;
case 34: // pg dn
if (
!options.textareaIsDirty ||
validateFieldChanges(event, 'ask_ok')
) {
skipImage(event, -1);
}
specialKeyState.isCancelKey = true;
break;
default:
}
return specialKeyState;
};
function fieldNavigate(evt, dir) {
let current_field = $('#divS .edit_field.active');
if (current_field.length === 0) {
current_field = $('#divS .edit_field:first');
current_field.trigger('click');
} else {
if (dir >= 0) {
current_field.next().trigger('click');
} else {
current_field.prev().trigger('click');
}
}
}
return { initialize, openModal, onGlobalKeydown };
};
export default editRecord;

View File

@@ -0,0 +1,464 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
const humane = require('humane-js');
const exportRecord = services => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
let $container = null;
const initialize = () => {
$container = $('body');
$container.on('click', '.record-export-action', function (event) {
event.preventDefault();
let $el = $(event.currentTarget);
let key = '';
let kind = $el.data('kind');
let idContent = $el.data('id');
switch (kind) {
case 'basket':
key = 'ssel';
break;
case 'record':
key = 'lst';
break;
default:
}
doExport(`${key}=${idContent}`);
});
};
const openModal = datas => doExport(datas);
function doExport(datas) {
var $dialog = dialog.create(services, {
size: 'Medium',
title: localeService.t('export')
});
$.ajax({
method: 'POST',
url: `${url}prod/export/multi-export/`,
data: datas,
success: function (data) {
$dialog.setContent(data);
if (window.exportConfig.isGuest) {
dialog.get(1).close();
let guestModal = dialog.create(
{
size: '500x100',
closeOnEscape: true,
closeButton: false,
title: window.exportConfig.msg.modalTile
},
2
);
guestModal.setContent(window.exportConfig.msg.modalContent);
} else {
_onExportReady($dialog, window.exportConfig);
}
}
});
return true;
}
const _onExportReady = ($dialog, dataConfig) => {
$('.tabs', $dialog.getDomElement()).tabs();
$('.close_button', $dialog.getDomElement()).bind('click', function () {
$dialog.close();
});
var tabs = $('.tabs', $dialog.getDomElement());
if (dataConfig.haveFtp === true) {
$('#ftp_form_selector')
.bind('change', function () {
$('#ftp .ftp_form').hide();
$('#ftp .ftp_form_' + $(this).val()).show();
$('.ftp_folder_check', dialog.get(1).getDomElement())
.unbind('change')
.bind('change', function () {
if ($(this).prop('checked')) {
$(this).next().prop('disabled', false);
} else {
$(this).next().prop('disabled', true);
}
});
})
.trigger('change');
}
$('a.TOUview').bind('click', function (event) {
event.preventDefault();
let $el = $(event.currentTarget);
var options = {
size: 'Medium',
closeButton: true,
title: dataConfig.msg.termOfUseTitle
};
let termOfuseDialog = dialog.create(services, options, 2);
$.get($el.attr('href'), function (content) {
termOfuseDialog.setContent(content);
});
});
$('.close_button').bind('click', function () {
$dialog.close();
});
$('#download .download_button').bind('click', function () {
if (!check_subdefs($('#download'), dataConfig)) {
return false;
}
if (!check_TOU($('#download'), dataConfig)) {
return false;
}
var total = 0;
var count = 0;
$('input[name="obj[]"]', $('#download')).each(function () {
var total_el = $(
'#download input[name=download_' + $(this).val() + ']'
);
var count_el = $(
'#download input[name=count_' + $(this).val() + ']'
);
if ($(this).prop('checked')) {
total += parseInt($(total_el).val(), 10);
count += parseInt($(count_el).val(), 10);
}
});
if (count > 1 && total / 1024 / 1024 > dataConfig.maxDownload) {
if (
confirm(
`${dataConfig.msg.fileTooLarge} \n ${dataConfig.msg
.fileTooLargeAlt}`
)
) {
$(
'input[name="obj[]"]:checked',
$('#download')
).each(function (i, n) {
$(
'input[name="obj[]"][value="' + $(n).val() + '"]',
$('#sendmail')
).prop('checked', true);
});
$(document).find('input[name="taglistdestmail"]').tagsinput('add', dataConfig.user.email);
var tabs = $('.tabs', $dialog.getDomElement());
tabs.tabs('option', 'active', 1);
}
return false;
}
$('#download form').submit();
$dialog.close();
});
$('#order .order_button').bind('click', function () {
let title = '';
if (!check_TOU($('#order'), dataConfig)) {
return false;
}
$('#order .order_button_loader').css('visibility', 'visible');
var options = $('#order form').serialize();
var $this = $(this);
$this.prop('disabled', true).addClass('disabled');
$.post(
`${url}prod/order/`,
options,
function (data) {
$this.prop('disabled', false).removeClass('disabled');
$('#order .order_button_loader').css(
'visibility',
'hidden'
);
if (!data.error) {
title = dataConfig.msg.success;
} else {
title = dataConfig.msg.warning;
}
var options = {
size: 'Alert',
closeButton: true,
title: title
};
dialog.create(services, options, 2).setContent(data.msg);
if (!data.error) {
humane.info(data.msg);
$dialog.close();
} else {
humane.error(data.msg);
}
return;
},
'json'
);
});
$('#ftp .ftp_button').bind('click', function () {
if (!check_subdefs($('#ftp'), dataConfig)) {
return false;
}
if (!check_TOU($('#ftp'), dataConfig)) {
return false;
}
$('#ftp .ftp_button_loader').show();
$('#ftp .ftp_form:hidden').remove();
var $this = $(this);
var options_addr = $('#ftp_form_stock form:visible').serialize();
var options_join = $('#ftp_joined').serialize();
$this.prop('disabled', true);
$.post(
`${url}prod/export/ftp/`,
options_addr + '&' + options_join,
function (data) {
$this.prop('disabled', false);
$('#ftp .ftp_button_loader').hide();
if (data.success) {
humane.info(data.message);
$dialog.close();
} else {
var alert = dialog.create(
services,
{
size: 'Alert',
closeOnEscape: true,
closeButton: true,
title: dataConfig.msg.warning
},
2
);
alert.setContent(data.message);
}
return;
},
'json'
);
});
$('#ftp .tryftp_button').bind('click', function () {
$('#ftp .tryftp_button_loader').css('visibility', 'visible');
var $this = $(this);
$this.prop('disabled', true);
var options_addr = $('#ftp_form_stock form:visible').serialize();
$.post(
`${url}prod/export/ftp/test/`,
// no need to include 'ftp_joined' checkboxes to test ftp
options_addr,
function (data) {
$('#ftp .tryftp_button_loader').css('visibility', 'hidden');
var options = {
size: 'Alert',
closeButton: true,
title: data.success
? dataConfig.msg.success
: dataConfig.msg.warning
};
dialog
.create(services, options, 3)
.setContent(data.message);
$this.prop('disabled', false);
return;
}
);
});
$('#sendmail .sendmail_button').bind('click', function () {
if(!validEmail($('input[name="taglistdestmail"]', $('#sendmail')).val(), dataConfig)) {
return false;
}
if (!check_subdefs($('#sendmail'), dataConfig)) {
return false;
}
if (!check_TOU($('#sendmail'), dataConfig)) {
return false;
}
if ($('iframe[name=""]').length === 0) {
$('body').append(
'<iframe style="display:none;" name="sendmail_target"></iframe>'
);
}
$('#sendmail form').submit();
humane.infoLarge($('#export-send-mail-notif').val());
$dialog.close();
});
$('.datepicker', $dialog.getDomElement()).datepicker({
changeYear: true,
changeMonth: true,
dateFormat: 'yy-mm-dd'
});
$(
'a.undisposable_link',
$dialog.getDomElement()
).bind('click', function () {
$(this).parent().parent().find('.undisposable').slideToggle();
return false;
});
$(
'input[name="obj[]"]',
$('#download, #sendmail, #ftp')
).bind('change', function () {
var $form = $(this).closest('form');
if ($('input.caption[name="obj[]"]:checked', $form).length > 0) {
$('div.businessfields', $form).show();
} else {
$('div.businessfields', $form).hide();
}
});
};
function validateEmail(email) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
function validEmail(emailList, dataConfig) {
//split emailList by ; , or whitespace and filter empty element
let emails = emailList.split(/[ ,;]+/).filter(Boolean);
let alert;
for(let i=0; i < emails.length; i++) {
if (!validateEmail(emails[i])) {
alert = dialog.create(
services,
{
size: 'Alert',
closeOnEscape: true,
closeButton: true,
title: dataConfig.msg.warning
},
2
);
alert.setContent(dataConfig.msg.invalidEmail);
return false;
}
}
return true;
}
function check_TOU(container, dataConfig) {
let checkbox = $('input[name="TOU_accept"]', $(container));
let go = checkbox.length === 0 || checkbox.prop('checked');
let alert;
if (!go) {
alert = dialog.create(
services,
{
size: 'Small',
closeOnEscape: true,
closeButton: true,
title: dataConfig.msg.warning
},
2
);
alert.setContent(dataConfig.msg.termOfUseAgree);
return false;
}
return true;
}
function check_subdefs(container, dataConfig) {
let go = false;
let required = false;
let alert;
$('input[name="obj[]"]', $(container)).each(function () {
if ($(this).prop('checked')) {
go = true;
}
});
$('input.required, textarea.required', container).each(function (i, n) {
if ($.trim($(n).val()) === '') {
required = true;
$(n).addClass('error');
} else {
$(n).removeClass('error');
}
});
if (required) {
alert = dialog.create(
services,
{
size: 'Alert',
closeOnEscape: true,
closeButton: true,
title: dataConfig.msg.warning
},
2
);
alert.setContent(dataConfig.msg.requiredFields);
return false;
}
if (!go) {
alert = dialog.create(
services,
{
size: 'Alert',
closeOnEscape: true,
closeButton: true,
title: dataConfig.msg.warning
},
2
);
alert.setContent(dataConfig.msg.missingSubdef);
return false;
}
return true;
}
return { initialize, openModal };
};
export default exportRecord;

View File

@@ -0,0 +1,44 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
import pushRecord from './recordPush/index';
const recordFeedbackModal = (services, datas) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const openModal = (datas) => {
/* disable push closeonescape as an over dialog may exist (add user) */
let $dialog = dialog.create(services, {
size: 'Full',
title: localeService.t('feedback')
});
$dialog.getDomElement().closest('.ui-dialog').addClass('feedback_dialog_container');
$.post(`${url}prod/push/validateform/`, datas, function (data) {
// data content's javascript can't be fully refactored
$dialog.setContent(data);
_onDialogReady();
return;
});
return true;
};
const _onDialogReady = () => {
pushRecord(services).initialize({
feedback: {
containerId: '#PushBox',
context: 'Feedback'
},
listManager: {
containerId: '#ListManager'
}
});
};
return { openModal };
};
export default recordFeedbackModal;

View File

@@ -0,0 +1,40 @@
import {Observable} from 'rx';
// import {ajax} from 'jquery';
import $ from 'jquery';
let recordService = (services) => {
const {configService} = services;
const url = configService.get('baseUrl');
const notificationEndPoint = 'session/notifications/';
let initialize = () => {
};
let getNotification = (data) => {
let notificationPromise = $.Deferred();
$.ajax({
type: 'POST',
url: `${url}${notificationEndPoint}`,
data: data,
dataType: 'json'
}).done((data) => {
data.status = data.status || false;
if (data.status === 'ok') {
notificationPromise.resolve(data);
} else {
notificationPromise.reject(data);
}
})
.fail((data) => {
notificationPromise.reject(data);
});
return notificationPromise.promise();
};
let stream = Observable.fromPromise(getNotification);
return {
initialize,
getNotification,
stream
};
};
export default recordService;

View File

@@ -0,0 +1,449 @@
import $ from 'jquery';
function checkVocabId(VocabularyId) {
if (typeof VocabularyId === 'undefined') {
VocabularyId = null;
}
if (VocabularyId === '') {
VocabularyId = null;
}
return VocabularyId;
}
var recordFieldValue = function (meta_id, value, VocabularyId) {
VocabularyId = checkVocabId(VocabularyId);
this.datas = {
meta_id: meta_id,
value: value,
VocabularyId: VocabularyId
};
var $this = this;
};
recordFieldValue.prototype = {
getValue: function () {
return this.datas.value;
},
getMetaId: function () {
return this.datas.meta_id;
},
getVocabularyId: function () {
return this.datas.VocabularyId;
},
setValue: function (value, VocabularyId) {
this.datas.value = value;
this.datas.VocabularyId = checkVocabId(VocabularyId);
return this;
},
remove: function () {
this.datas.value = '';
this.datas.VocabularyId = null;
return this;
}
};
var databoxField = function (name, label, meta_struct_id, options) {
var defaults = {
multi: false,
required: false,
readonly: false,
maxLength: null,
minLength: null,
type: 'string',
separator: null,
vocabularyControl: null,
vocabularyRestricted: false
};
options = (typeof options === 'object') ? options : {};
if (isNaN(meta_struct_id)) {
throw 'meta_struct_id should be a number';
}
this.name = name;
this.label = label;
this.meta_struct_id = meta_struct_id;
this.options = $.extend(defaults, options);
if (this.options.multi === true && this.options.separator === null) {
this.options.separator = ';';
}
};
databoxField.prototype = {
getMetaStructId: function () {
return this.meta_struct_id;
},
getName: function () {
return this.name;
},
getLabel: function () {
return this.label;
},
isMulti: function () {
return this.options.multi;
},
isRequired: function () {
return this.options.required;
},
isReadonly: function () {
return this.options.readonly;
},
getMaxLength: function () {
return this.options.maxLength;
},
getMinLength: function () {
return this.options.minLength;
},
getType: function () {
return this.options.type;
},
getSeparator: function () {
return this.options.separator;
}
};
var recordField = function (databoxField, arrayValues) {
this.databoxField = databoxField;
this.options = {
dirty: false
};
this.datas = [];
if (arrayValues instanceof Array) {
if (arrayValues.length > 1 && !databoxField.isMulti()) {
throw 'You can not add multiple values to a non multi field ' + databoxField.getName();
}
var first = true;
for (let v in arrayValues) {
if (typeof arrayValues[v] !== 'object') {
if (window.console) {
console.error('Trying to add a non-recordFieldValue to the field...');
}
continue;
}
if (isNaN(arrayValues[v].getMetaId())) {
if (window.console) {
console.error('Trying to add a recordFieldValue without metaId...');
}
continue;
}
if (!first && this.options.multi === false) {
if (window.console) {
console.error('Trying to add multi values in a non-multi field');
}
}
/*if (window.console) {
console.log('adding a value : ', arrayValues[v]);
}*/
this.datas.push(arrayValues[v]);
first = false;
}
}
var $this = this;
};
recordField.prototype = {
getName: function () {
return this.databoxField.getName();
},
getMetaStructId: function () {
return this.databoxField.getMetaStructId();
},
isMulti: function () {
return this.databoxField.isMulti();
},
isRequired: function () {
return this.databoxField.isRequired();
},
isDirty: function () {
return this.options.dirty;
},
addValue: function (value, merge, VocabularyId) {
VocabularyId = checkVocabId(VocabularyId);
merge = !!merge;
/* if (this.databoxField.isReadonly()) {
if (window.console) {
console.error('Unable to set a value to a readonly field');
}
return this;
}*/
if (window.console) {
console.log('adding value ', value, ' vocId : ', VocabularyId, ' ; merge is ', merge);
}
if (this.isMulti()) {
if (!this.hasValue(value, VocabularyId)) {
if (window.console) {
console.log('adding new multi value ', value);
}
this.datas.push(new recordFieldValue(null, value, VocabularyId));
this.options.dirty = true;
} else {
if (window.console) {
console.log('already have ', value);
}
}
} else {
if (merge === true && this.isEmpty() === false && VocabularyId === null) {
if (window.console) {
console.log('Merging value ', value);
}
this.datas[0].setValue(this.datas[0].getValue() + ' ' + value, VocabularyId);
this.options.dirty = true;
} else {
if (merge === true && this.isEmpty() === false && VocabularyId !== null) {
if (window.console) {
console.error('Cannot merge vocabularies');
}
this.datas[0].setValue(value, VocabularyId);
} else {
if (!this.hasValue(value, VocabularyId)) {
if (this.datas.length === 0) {
/*if (window.console) {
console.log('Adding new value ', value);
}*/
this.datas.push(new recordFieldValue(null, value, VocabularyId));
} else {
if (window.console) {
console.log('Updating value ', value);
}
this.datas[0].setValue(value, VocabularyId);
}
this.options.dirty = true;
}
}
}
}
return this;
},
hasValue: function (value, VocabularyId) {
if (typeof value === 'undefined') {
if (window.console) {
console.error('Trying to check the presence of an undefined value');
}
}
VocabularyId = checkVocabId(VocabularyId);
for (let d in this.datas) {
if (VocabularyId !== null) {
if (this.datas[d].getVocabularyId() === VocabularyId) {
if (window.console) {
console.log('already got the vocab ID');
}
return true;
}
} else if (this.datas[d].getVocabularyId() === null && this.datas[d].getValue() === value) {
if (window.console) {
console.log('already got this value');
}
return true;
}
}
return false;
},
removeValue: function (value, vocabularyId) {
if (this.databoxField.isReadonly()) {
if (window.console) {
console.error('Unable to set a value to a readonly field');
}
return this;
}
vocabularyId = checkVocabId(vocabularyId);
if (window.console) {
console.log('Try to remove value ', value, vocabularyId, this.datas);
}
for (let d in this.datas) {
if (window.console) {
console.log('loopin... ', this.datas[d].getValue());
}
if (this.datas[d].getVocabularyId() !== null) {
if (this.datas[d].getVocabularyId() === vocabularyId) {
if (window.console) {
console.log('Found within the vocab ! removing... ');
}
this.datas[d].remove();
this.options.dirty = true;
}
} else if (this.datas[d].getValue() === value) {
if (window.console) {
console.log('Found ! removing... ');
}
this.datas[d].remove();
this.options.dirty = true;
}
}
return this;
},
isEmpty: function () {
var empty = true;
for (let d in this.datas) {
if (this.datas[d].getValue() !== '') {
empty = false;
}
}
return empty;
},
empty: function () {
if (this.databoxField.isReadonly()) {
if (window.console) {
console.error('Unable to set a value to a readonly field');
}
return this;
}
for (let d in this.datas) {
this.datas[d].remove();
this.options.dirty = true;
}
return this;
},
getValue: function () {
if (this.isMulti()) {
throw 'This field is multi, I can not give you a single value';
}
if (this.isEmpty()) {
return null;
}
return this.datas[0];
},
getValues: function () {
if (!this.isMulti()) {
throw 'This field is not multi, I can not give you multiple values';
}
if (this.isEmpty()) {
return [];
}
var arrayValues = [];
for (let d in this.datas) {
if (this.datas[d].getValue() === '') {
continue;
}
arrayValues.push(this.datas[d]);
}
return arrayValues;
},
sort: function (algo) {
this.datas.sort(algo);
return this;
},
getSerializedValues: function () {
var arrayValues = [];
var values = this.getValues();
for (let v in values) {
arrayValues.push(values[v].getValue());
}
return arrayValues.join(' ; ');
},
replaceValue: function (search, replace) {
if (this.databoxField.isReadonly()) {
if (window.console) {
console.error('Unable to set a value to a readonly field');
}
return 0;
}
var n = 0;
for (let d in this.datas) {
if (this.datas[d].getVocabularyId() !== null) {
continue;
}
var value = this.datas[d].getValue();
var replacedValue = value.replace(search, replace);
if (value === replacedValue) {
continue;
}
n++;
this.removeValue(value);
if (!this.hasValue(replacedValue)) {
this.addValue(replacedValue);
}
this.options.dirty = true;
}
return n;
},
exportDatas: function () {
var returnValue = [];
for (let d in this.datas) {
var temp = {
meta_id: this.datas[d].getMetaId() ? this.datas[d].getMetaId() : '',
meta_struct_id: this.getMetaStructId(),
value: this.datas[d].getValue()
};
if (this.datas[d].getVocabularyId()) {
temp.vocabularyId = this.datas[d].getVocabularyId();
}
returnValue.push(temp);
}
return returnValue;
}
};
export {
databoxField, recordFieldValue, recordField
};

View File

@@ -0,0 +1,104 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
const humane = require('humane-js');
let $dialog = null;
const moveRecord = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const openModal = (datas) => {
$dialog = dialog.create(services, {
size: 'Small phrasea-black-dialog',
title: localeService.t('move'),
closeButton: true,
});
//Add custom class to dialog wrapper
$('.phrasea-black-dialog').closest('.ui-dialog').addClass('black-dialog-wrap move-dialog');
return _getMovableRecords(datas)
.then((data) => {
if (data.success !== undefined) {
if (data.success === true) {
$dialog.setContent(data.template);
_bindFormEvents();
} else {
if (data.message !== undefined) {
$dialog.setContent(data.message);
}
}
}
}, (data) => {
if (data.message !== undefined) {
$dialog.setContent(data.message);
}
});
};
const _bindFormEvents = () => {
$dialog = dialog.get(1);
var $form = $dialog.getDomElement();
var buttons = {};
buttons[localeService.t('valider')] = function () {
var coll_son = $('input[name="chg_coll_son"]:checked', $form).length > 0 ? '1' : '0';
var datas = {
lst: $('input[name="lst"]', $form).val(),
base_id: $('select[name="base_id"]', $form).val(),
chg_coll_son: coll_son
};
var buttonPanel = $dialog.getDomElement()
.closest('.ui-dialog')
.find('.ui-dialog-buttonpane');
$(":button:contains('" + localeService.t('valider') + "')", buttonPanel)
.attr('disabled', true).addClass('ui-state-disabled');
_postMovableRecords(datas).then(
(data) => {
$dialog.close();
if (data.success) {
humane.info(data.message);
} else {
humane.error(data.message);
}
$(":button:contains('" + localeService.t('valider') + "')", buttonPanel)
.attr('disabled', false).removeClass('ui-state-disabled');
},
() => {
}
);
return false;
};
$dialog.setOption('buttons', buttons);
};
const _getMovableRecords = (datas) => {
return $.ajax({
type: 'POST',
url: `${url}prod/records/movecollection/`,
data: datas
});
};
const _postMovableRecords = (datas) => {
return $.ajax({
type: 'POST',
url: `${url}prod/records/movecollection/apply/`,
dataType: 'json',
data: datas
});
};
return { openModal };
};
export default moveRecord;

View File

@@ -0,0 +1,77 @@
import $ from 'jquery';
const printRecord = (services) => {
const {configService, localeService, appEvents} = services;
const url = configService.get('baseUrl');
let $container = null;
appEvents.listenAll({
'record.doPrint': doPrint
});
const initialize = () => {
$container = $('body');
$container.on('click', '.record-print-action', function (event) {
event.preventDefault();
let $el = $(event.currentTarget);
let key = '';
let kind = $el.data('kind');
let idContent = $el.data('id');
switch (kind) {
case 'basket':
key = 'ssel';
break;
case 'record':
key = 'lst';
break;
default:
}
doPrint(`${key}=${idContent}`);
});
};
const openModal = (datas) => {
return doPrint($.param(datas))
}
function doPrint(value) {
if ($('#DIALOG').data('ui-dialog')) {
$('#DIALOG').dialog('destroy');
}
$('#DIALOG').attr('title', localeService.t('print'))
.empty().addClass('loading')
.dialog({
resizable: false,
closeOnEscape: true,
modal: true,
width: '800',
height: '500',
open: function (event, ui) {
$(this).dialog('widget').css('z-index', '1999');
},
close: function (event, ui) {
$(this).dialog('widget').css('z-index', 'auto');
}
})
.dialog('open');
$.ajax({
type: 'POST',
url: `${url}prod/printer/?${value}`,
dataType: 'html',
beforeSend: function () {
},
success: function (data) {
$('#DIALOG').removeClass('loading').empty()
.append(data);
return;
}
});
}
return {initialize, openModal};
};
export default printRecord;

View File

@@ -0,0 +1,137 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
const propertyRecord = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const openModal = (datas) => {
return doProperty(datas);
};
const doProperty = (datas) => {
var $dialog = dialog.create(services, {
size: 'Medium',
title: $('#property-title').val()
});
$.ajax({
type: 'GET',
data: datas,
url: `${url}prod/records/property/`,
success: function (data) {
$dialog.setContent(data);
_onPropertyReady($dialog);
}
});
return true;
};
const _onPropertyReady = ($dialog) => {
$('#tabs-records-property').tabs({
beforeLoad: function (event, ui) {
ui.ajaxSettings.data = {
lst: $('input[name=original_selection]', $(this)).val(),
};
// load template only once
if (ui.tab.data('loaded')) {
event.preventDefault();
return;
}
ui.jqXHR.success(function () {
ui.tab.data('loaded', true);
ui.tab.find('span').html('');
typeTabContent($dialog, '#' + ui.tab.attr('aria-controls'));
});
ui.tab.find('span').html('<i>' + localeService.t('loading') + '</i>');
},
load: function (event, ui) {
ui.tab.find('span').empty();
}
});
propertyTabContent($dialog);
};
/**
* Property Tab
* @param $dialogBox
*/
const propertyTabContent = ($dialog) => {
const $propertyContainer = $('#property-status');
$propertyContainer.on('click', 'button.cancel', function () {
$dialog.close();
});
$propertyContainer.on('click', 'button.submiter', function () {
var $this = $(this);
var form = $(this).closest('form');
var loader = form.find('form-action-loader');
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serializeArray(),
dataType: 'json',
beforeSend: function () {
$this.attr('disabled', true);
loader.show();
},
success: function (data) {
$dialog.close();
},
complete: function () {
$this.attr('disabled', false);
loader.hide();
}
});
});
};
/**
* Type Tab
* @param $dialog
* @param typeContainerId
*/
const typeTabContent = ($dialog, typeContainerId) => {
const $typeContainer = $(typeContainerId);
$typeContainer.on('click', 'button.cancel', function () {
$dialog.close();
});
$typeContainer.on('click', 'button.submiter', function () {
var $this = $(this);
var form = $(this).closest('form');
var loader = form.find('form-action-loader');
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serializeArray(),
dataType: 'json',
beforeSend: function () {
$this.attr('disabled', true);
loader.show();
},
success: function (data) {
$dialog.close();
},
complete: function () {
$this.attr('disabled', false);
loader.hide();
}
});
});
};
return {openModal};
};
export default propertyRecord;

View File

@@ -0,0 +1,24 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
import publication from '../publication';
const recordPublishModal = (services, datas) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
const openModal = (datas) => {
$.post(`${url}prod/feeds/requestavailable/`
, datas
, function (data) {
return publication(services).openModal(data);
});
return true;
};
return { openModal };
};
export default recordPublishModal;

View File

@@ -0,0 +1,44 @@
import $ from 'jquery';
import dialog from './../../phraseanet-common/components/dialog';
import pushRecordWindow from './recordPush/index';
const pushRecord = (services, datas) => {
const {configService, localeService, appEvents} = services;
const url = configService.get('baseUrl');
const openModal = (datas) => {
let $dialog = dialog.create(services, {
size: 'Full',
title: localeService.t('push')
});
$dialog.getDomElement().closest('.ui-dialog').addClass('push_dialog_container');
$.post(`${url}prod/push/sendform/`, datas, function (data) {
$dialog.setContent(data);
_onDialogReady();
return;
});
return true;
};
const _onDialogReady = () => {
pushRecordWindow(services).initialize({
feedback: {
containerId: '#PushBox',
context: 'Push'
},
listManager: {
containerId: '#ListManager'
}
});
};
return {openModal};
};
export default pushRecord;

View File

@@ -0,0 +1,331 @@
import $ from 'jquery';
import dialog from './../../../phraseanet-common/components/dialog';
const recordBridge = (services) => {
const { configService, localeService, appEvents } = services;
const url = configService.get('baseUrl');
let pub_tabs = $('#pub_tabs');
let container = $('#dialog_publicator');
let managerUrl = container.data('url');
let $panel;
const initialize = () => {
pub_tabs.tabs({
beforeLoad: function (event, ui) {
ui.tab.html_tab = ui.tab.find('span').html();
ui.tab.find('span').html('<i>' + localeService.t('Loading') + '...</i>');
},
load: function (event, ui) {
ui.tab.find('span').empty().append(ui.tab.html_tab);
$panel = $(ui.panel);
$('.container-bridge', $panel).removeClass('loading');
$panel.addClass('PNB');
$panel.wrapInner("<div class='PNB10 container-bridge' />");
panel_load($panel);
},
beforeActivate: function (event, ui) {
if ($(ui.tab).hasClass('account')) {
var container = $('.container-bridge', ui.panel);
container.empty();
$('.container', ui.panel).addClass('loading');
}
}
}).addClass('ui-tabs-vertical ui-helper-clearfix');
$('.ui-tabs-nav', pub_tabs).removeClass('ui-corner-all');
$('.new_bridge_button', pub_tabs).bind('click', function () {
var url = $(this).parent('form').find('input[name="url"]').val();
popme(url);
return false;
});
$('ul li a.account', pub_tabs).bind('click', function () {
$('#dialog_publicator form[name="current_datas"] input[name="account_id"]').val($('input[name="account_id"]', this).val());
});
$('ul li.ui-tabs-selected a.account', pub_tabs).trigger('click');
$('#publicator_selection .PNB10:first').selectable();
$('#publicator_selection button.act_upload').bind('click', function () {
var $this = $(this);
var $form = $this.closest('form');
$('input[name=lst]', $form).val(
$.makeArray(
$('#publicator_selection .diapo.ui-selected').map(function (i, el) {
return $(el).attr('id').split('_').slice(2, 4).join('_');
})
).join(';')
);
var account_id = $('form[name="current_datas"] input[name="account_id"]').val();
$('input[name="account_id"]', $form).val(account_id);
var $panel = $('#pub_tabs .ui-tabs-panel:visible');
$.ajax({
type: 'GET',
url: `${url}prod/bridge/upload/`,
data: $form.serializeArray(),
beforeSend: function () {
$panel.empty().addClass('loading');
},
success: function (datas) {
$panel.removeClass('loading').append(datas);
panel_load($panel);
},
error: function () {
$panel.removeClass('loading');
},
timeout: function () {
$panel.removeClass('loading');
}
});
return false;
});
$('li', pub_tabs).removeClass('ui-corner-top').addClass('ui-corner-left');
$('#api_connexion').click(function () {
if (container.data('ui-dialog')) {
container.dialog('close');
}
});
};
function popme(url) {
var newwindow = window.open(url, 'logger', 'height=500,width=800');
if (window.focus) {
newwindow.focus();
}
return false;
}
function panel_load($panel) {
$('.new_bridge_button', $panel).bind('click', function () {
var url = $(this).parent('form').find('input[name="url"]').val();
popme(url);
return false;
});
$('.error_box, .notice_box', $panel).delay(10000).fadeOut();
$('.back_link', $panel).bind('click', function () {
if ($('#pub_tabs').data('ui-tabs')) {
$('#pub_tabs').tabs('load', $('#pub_tabs').tabs('option', 'active'));
}
return false;
});
$('.bridge_action', $panel).bind('click', function () {
var $this = $(this);
$.ajax({
type: 'GET',
url: $(this).attr('href'),
beforeSend: function () {
var container = $('.container-bridge', $panel);
container.empty();
if (!$this.hasClass('bridge_logout')) {
container.addClass('loading');
}
},
success: function (datas) {
$('.container-bridge', $panel).removeClass('loading').append(datas);
panel_load($panel);
},
error: function () {
$panel.removeClass('loading');
},
timeout: function () {
$panel.removeClass('loading');
}
});
return false;
});
$('.delete-account', $panel).bind('click', function () {
let account_id = $(this).val();
let buttons = {};
buttons[localeService.t('valider')] = function () {
$.ajax({
type: 'POST',
dataType: 'json',
url: `${url}prod/bridge/adapter/${account_id}/delete/`,
data: {},
success: function (datas) {
if (datas.success) {
confirmBox.close();
appEvents.emit('push.reload', managerUrl);
// pushModule.reloadBridge(managerUrl);
} else {
confirmBox.close();
var alertBox = dialog.create(services, {
size: 'Alert',
closeOnEscape: true,
closeButton: true
}, 2);
alertBox.setContent(datas.message);
}
}
});
};
var confirmBox = dialog.create(services, {
size: 'Alert',
closeOnEscape: true,
closeButton: true,
cancelButton: true,
buttons: buttons
}, 2);
confirmBox.setContent(localeService.t('You are about to delete this account. Would you like to continue ?'));
});
$('.form_submitter', $panel).bind('click', function () {
var $form = $(this).closest('form');
var method = $form.attr('method');
method = $.inArray(method.toLowerCase(), ['post', 'get']) ? method : 'POST';
$.ajax({
type: method,
url: $form.attr('action'),
data: $form.serializeArray(),
beforeSend: function () {
$panel.empty().addClass('loading');
},
success: function (datas) {
$panel.removeClass('loading').append(datas);
panel_load($panel);
},
error: function () {
$panel.removeClass('loading');
},
timeout: function () {
$panel.removeClass('loading');
}
});
return false;
});
$('.bridge_all_selector', $panel).bind('click', function () {
var checkboxes = $('.bridge_element_selector', $panel);
var $this = $(this);
checkboxes.each(function (i, checkbox) {
if ($(checkbox).is(':checked') !== $this.is(':checked')) {
var event = $.Event('click');
event.selector_all = true;
$(checkbox).trigger(event);
}
});
});
$('.bridge_element_selector', $panel)
.bind('click', function (event) {
var $this = $(this);
if (event.selector_all) {
$this.prop('checked', $('.bridge_all_selector', $panel).is(':checked'));
}
$('form[name="bridge_selection"] input[name="elements_list"]', $panel).val(
$.makeArray($('.bridge_element_selector:checked', $panel).map(function (i, el) {
return ($(el).val());
})).join(';')
);
if ($this.is(':checked')) {
$this.closest('.element').addClass('selected');
} else {
$this.closest('.element').removeClass('selected');
}
if (!event.selector_all) {
var bool = !($('.bridge_element_selector:checked', $panel).length !== $('.bridge_element_selector', $panel).length);
$('.bridge_all_selector', $panel).prop('checked', bool);
} else {
if (event.stopPropagation) {
event.stopPropagation();
}
return false;
}
});
$('a.form_multiple_submitter', $panel).bind('click', function () {
var $form = $(this).closest('form');
var elements = $('form[name="bridge_selection"] input[name="elements_list"]', $panel).val();
var n_elements = 0;
if ($.trim(elements) !== '') {
n_elements = elements.split(';').length;
}
if (n_elements === 0 && $form.hasClass('action_works_standalone') === false) {
alert('No records selected');
return false;
}
if (n_elements === 1 && $form.hasClass('action_works_single_element') === false) {
alert('This action works only with a single records');
return false;
}
if (n_elements > 1 && $form.hasClass('action_works_many_element') === false) {
alert('This action works only with many records');
return false;
}
$('input[name="elements_list"]', $form).val(elements);
$.ajax({
type: 'GET',
url: $form.attr('action'),
data: $form.serializeArray(),
beforeSend: function () {
$panel.empty().addClass('loading');
},
success: function (datas) {
$panel.removeClass('loading').append(datas);
panel_load($panel);
},
error: function () {
$panel.removeClass('loading');
},
timeout: function () {
$panel.removeClass('loading');
}
});
return false;
});
}
return {
initialize
};
};
export default recordBridge;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,176 @@
import $ from 'jquery';
import * as appCommons from './../../../phraseanet-common';
const recordEditorLayout = services => {
const { configService, localeService, recordEditorEvents } = services;
let $container = null;
let parentOptions = {};
const initialize = options => {
let initWith = ({ $container, parentOptions } = options);
$(window).bind('resize', function () {
recordEditorEvents.emit('recordEditor.uiResize');
_setSizeLimits();
});
_hsplit1();
_vsplit2();
_vsplit1();
$('#EDIT_TOP', parentOptions.$container).resizable({
handles: 's',
minHeight: 100,
resize: function () {
_hsplit1();
recordEditorEvents.emit('recordEditor.uiResize');
},
stop: function () {
_hsplit1();
appCommons.userModule.setPref(
'editing_top_box',
Math.floor(
$('#EDIT_TOP').height() * 100 / $('#EDIT_ALL').height()
)
);
_setSizeLimits();
}
});
$('#divS_wrapper', parentOptions.$container).resizable({
handles: 'e',
minWidth: 200,
resize: function () {
_vsplit1();
recordEditorEvents.emit('recordEditor.uiResize');
},
stop: function () {
appCommons.userModule.setPref(
'editing_right_box',
Math.floor(
$('#divS').width() * 100 / $('#EDIT_MID_L').width()
)
);
_vsplit1();
_setSizeLimits();
}
});
$('#EDIT_MID_R')
.css(
'left',
$('#EDIT_MID_L').position().left + $('#EDIT_MID_L').width() + 15
)
.resizable({
handles: 'w',
minWidth: 200,
resize: function () {
_vsplit2();
recordEditorEvents.emit('recordEditor.uiResize');
},
stop: function () {
appCommons.userModule.setPref(
'editing_left_box',
Math.floor(
$('#EDIT_MID_R').width() *
100 /
$('#EDIT_MID').width()
)
);
_vsplit2();
_setSizeLimits();
}
});
$('#EDIT_ZOOMSLIDER', parentOptions.$container).slider({
min: 60,
max: 300,
value: parentOptions.recordConfig.diapoSize,
slide: function (event, ui) {
var v = $(ui.value)[0];
$('#EDIT_FILM2 .diapo', parentOptions.$container)
.width(v)
.height(v);
},
change: function (event, ui) {
parentOptions.recordConfig.diapoSize = $(ui.value)[0];
appCommons.userModule.setPref(
'editing_images_size',
parentOptions.recordConfig.diapoSize
);
}
});
_setSizeLimits();
};
function _setSizeLimits() {
if (!$('#EDITWINDOW').is(':visible')) {
return;
}
if ($('#EDIT_TOP').data('ui-resizable')) {
$('#EDIT_TOP').resizable(
'option',
'maxHeight',
$('#EDIT_ALL').height() -
$('#buttonEditing').height() -
10 -
160
);
}
if ($('#divS_wrapper').data('ui-resizable')) {
$('#divS_wrapper').resizable(
'option',
'maxWidth',
$('#EDIT_MID_L').width() - 270
);
}
if ($('#EDIT_MID_R').data('ui-resizable')) {
$('#EDIT_MID_R').resizable(
'option',
'maxWidth',
$('#EDIT_MID_R').width() + $('#idEditZone').width() - 240
);
}
}
function _hsplit1() {
let el = $('#EDIT_TOP');
if (el.length === 0) {
return;
}
let h = $(el).outerHeight();
$(el).height(h);
let t = $(el).offset().top + h;
$('#EDIT_MID', parentOptions.$container).css('top', t + 'px');
}
function _vsplit1() {
$('#divS_wrapper').height('auto');
let el = $('#divS_wrapper');
if (el.length === 0) {
return;
}
let a = $(el).width();
el.width(a);
$('#idEditZone', parentOptions.$container).css('left', a + 20);
}
function _vsplit2() {
let el = $('#EDIT_MID_R');
if (el.length === 0) {
return;
}
let a = $(el).width();
el.width(a);
let v = $('#EDIT_ALL').width() - a - 35;
$('#EDIT_MID_L', parentOptions.$container).width(v);
}
return { initialize };
};
export default recordEditorLayout;

View File

@@ -0,0 +1,81 @@
import merge from 'lodash.merge';
class FieldCollection {
fields;
constructor(fieldsList) {
this.fields = fieldsList;
}
getFields() {
return this.fields;
}
getFieldOptionsById(meta_struct_id) {
/*var name = this.fields[meta_struct_id].name;
var label = this.fields[meta_struct_id].label;
var multi = ;
var required = this.fields[meta_struct_id].required;
var readonly = this.fields[meta_struct_id].readonly;
var maxLength = this.fields[meta_struct_id].maxLength;
var minLength = this.fields[meta_struct_id].minLength;
var type = this.fields[meta_struct_id].type;
var separator = this.fields[meta_struct_id].separator;
var vocabularyControl = this.fields[meta_struct_id].vocabularyControl || null;
var vocabularyRestricted = this.fields[meta_struct_id].vocabularyRestricted || null;*/
return {
multi: this.fields[meta_struct_id].multi,
required: this.fields[meta_struct_id].required,
readonly: this.fields[meta_struct_id].readonly,
maxLength: this.fields[meta_struct_id].maxLength,
minLength: this.fields[meta_struct_id].minLength,
type: this.fields[meta_struct_id].type,
separator: this.fields[meta_struct_id].separator,
vocabularyControl: this.fields[meta_struct_id].vocabularyControl || null,
vocabularyRestricted: this.fields[meta_struct_id].vocabularyRestricted || null
};
}
setActiveField(metaStructId) {
this.metaStructId = metaStructId;
}
getActiveFieldIndex() {
return this.metaStructId === undefined ? '?' : this.metaStructId;
}
getActiveField() {
return this.fields[this.getActiveFieldIndex()]
}
getFieldByIndex(id = false) {
if (this.fields[id] !== undefined) {
return this.fields[id];
}
return false;
}
getFieldByName(fieldName) {
let foundField = false;
for (let field in this.fields) {
if (this.fields[field].name === fieldName) {
foundField = this.fields[field];
}
}
return foundField;
}
getFieldStatus(id = false) {
}
updateField(id, data) {
if (this.fields[id] !== undefined) {
this.fields[id] = merge(this.fields[id], data);
return this.fields[id];
}
}
}
export default FieldCollection;

View File

@@ -0,0 +1,193 @@
import FieldCollection from './fieldCollection';
import * as recordModel from '../../../record/model';
class RecordCollection {
records;
fieldCollection;
statbitCollection;
constructor(recordsList, fieldsColl, statusbitList, predefinedValues) {
this.records = recordsList;
this.statusbits = statusbitList;
this.fieldCollection = fieldsColl;
this.predefinedValues = predefinedValues;
// set each models
this.initializeRecordModels();
}
getRecords() {
return this.records;
}
getRecordByIndex(id = false) {
if (this.records[id] !== undefined) {
return this.records[id];
}
return false;
}
initializeRecordModels() {
for (let recordIndex in this.records) {
// let fields = this.setRecordFields(recordIndex);
this.records[recordIndex].fields = this.setRecordFields(recordIndex);
//options.fields = fields;
}
}
setRecordFields(recordIndex) {
let fields = {};
for (let fieldIndex in this.records[recordIndex].fields) {
var meta_struct_id = this.records[recordIndex].fields[fieldIndex].meta_struct_id;
let currentField = this.fieldCollection.getFieldByIndex(meta_struct_id);
var fieldOptions = this.fieldCollection.getFieldOptionsById(meta_struct_id);
var databoxField = new recordModel.databoxField(currentField.name, currentField.label, meta_struct_id, fieldOptions);
var values = [];
for (let v in this.records[recordIndex].fields[fieldIndex].values) {
var meta_id = this.records[recordIndex].fields[fieldIndex].values[v].meta_id;
var value = this.records[recordIndex].fields[fieldIndex].values[v].value;
var vocabularyId = this.records[recordIndex].fields[fieldIndex].values[v].vocabularyId;
values.push(new recordModel.recordFieldValue(meta_id, value, vocabularyId));
}
fields[fieldIndex] = new recordModel.recordField(databoxField, values);
}
return fields;
}
/**
* Merge all suggestions for 1 or n records
* @returns {{}}
*/
getFieldSuggestedValues() {
var suggestedValuesCollection = {};
var t_selcol = {};
var ncolsel = 0;
var nrecsel = 0;
for (let recordIndex in this.records) {
if (!this.records[recordIndex]._selected) {
continue;
}
nrecsel++;
var bid = 'b' + this.records[recordIndex].bid;
if (t_selcol[bid]) {
continue;
}
t_selcol[bid] = 1;
ncolsel++;
for (let f in this.predefinedValues[bid]) {
if (!suggestedValuesCollection[f]) {
suggestedValuesCollection[f] = {};
}
for (let ivs in this.predefinedValues[bid][f]) {
let vs = this.predefinedValues[bid][f][ivs];
if (!suggestedValuesCollection[f][vs]) {
suggestedValuesCollection[f][vs] = 0;
}
suggestedValuesCollection[f][vs]++;
}
}
}
return suggestedValuesCollection;
}
setStatus(bit, val) {
for (let id in this.records) {
// toutes les fiches selectionnees
if (this.records[id]._selected) {
if (this.records[id].editableStatus === true) {
this.records[id].statbits[bit].value = val;
this.records[id].statbits[bit].dirty = true;
}
}
}
}
isDirty() {
let dirty = false;
for (let recordIndex in this.records) {
for (let fieldIndex in this.records[recordIndex].fields) {
if ((dirty |= this.records[recordIndex].fields[fieldIndex].isDirty())) {
break;
}
}
for (let bitIndex in this.records[recordIndex].statbits) {
if ((dirty |= this.records[recordIndex].statbits[bitIndex].dirty)) {
break;
}
}
}
return dirty;
}
gatherUpdatedRecords() {
let t = [];
for (let recordIndex in this.records) {
let record_datas = {
record_id: this.records[recordIndex].rid,
metadatas: [],
edit: 0,
status: null
};
let editDirty = false;
for (let f in this.records[recordIndex].fields) {
if (!this.records[recordIndex].fields[f].isDirty()) {
continue;
}
editDirty = true;
record_datas.edit = 1;
record_datas.metadatas = record_datas.metadatas.concat(
this.records[recordIndex].fields[f].exportDatas()
);
}
// les statbits
let tsb = [];
for (let n = 0; n < 64; n++) {
tsb[n] = 'x';
}
let sb_dirty = false;
for (let n in this.records[recordIndex].statbits) {
if (this.records[recordIndex].statbits[n].dirty) {
tsb[63 - n] = this.records[recordIndex].statbits[n].value;
sb_dirty = true;
}
}
if (sb_dirty || editDirty) {
if (sb_dirty === true) {
record_datas.status = tsb.join('');
}
t.push(record_datas);
}
}
return t;
}
removeRecordFieldValue(recordIndex, fieldIndex, params) {
let {value, vocabularyId} = params;
this.records[recordIndex].fields[fieldIndex].removeValue(value, vocabularyId);
}
addRecordFieldValue(recordIndex, fieldIndex, params) {
let {value, merge, vocabularyId} = params;
this.records[recordIndex].fields[fieldIndex].addValue(value, merge, vocabularyId);
}
/* options.recordCollection.removeRecordFieldValue(r, currentFieldId, {
value, vocabularyId
})*/
// currentRecord.fields[currentFieldId].removeValue(value, VocabularyId);
}
export default RecordCollection;

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