mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-23 09:53:15 +00:00
Merge branch 'master' into PHRAS-2680-webhook-privacy-and-security
This commit is contained in:
@@ -123,8 +123,8 @@ workflows:
|
||||
dockerfile: Dockerfile
|
||||
extra-build-args: "--target phraseanet-fpm"
|
||||
region: AWS_DEFAULT_REGION
|
||||
repo: "${AWS_RESOURCE_NAME_PREFIX}/phraseanet"
|
||||
tag: "alpha-0.1"
|
||||
repo: "phraseanet-fpm"
|
||||
tag: "${CIRCLE_BRANCH}"
|
||||
- aws-ecr/build_and_push_image:
|
||||
account-url: AWS_ACCOUNT_URL
|
||||
aws-access-key-id: AWS_ACCESS_KEY_ID
|
||||
@@ -134,8 +134,8 @@ workflows:
|
||||
dockerfile: Dockerfile
|
||||
extra-build-args: "--target phraseanet-nginx"
|
||||
region: AWS_DEFAULT_REGION
|
||||
repo: "${AWS_RESOURCE_NAME_PREFIX}/phraseanet-nginx"
|
||||
tag: "alpha-0.1"
|
||||
repo: "phraseanet-nginx"
|
||||
tag: "${CIRCLE_BRANCH}"
|
||||
- aws-ecr/build_and_push_image:
|
||||
account-url: AWS_ACCOUNT_URL
|
||||
aws-access-key-id: AWS_ACCESS_KEY_ID
|
||||
@@ -145,5 +145,5 @@ workflows:
|
||||
dockerfile: Dockerfile
|
||||
extra-build-args: "--target phraseanet-worker"
|
||||
region: AWS_DEFAULT_REGION
|
||||
repo: "${AWS_RESOURCE_NAME_PREFIX}/phraseanet"
|
||||
tag: "alpha-0.1"
|
||||
repo: "phraseanet-worker"
|
||||
tag: "${CIRCLE_BRANCH}"
|
||||
|
41
Dockerfile
41
Dockerfile
@@ -86,6 +86,18 @@ COPY grammar /var/alchemy/grammar
|
||||
COPY templates-profiler /var/alchemy/templates-profiler
|
||||
COPY templates /var/alchemy/templates
|
||||
COPY tests /var/alchemy/tests
|
||||
RUN mkdir -p /var/alchemy/Phraseanet/logs \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/logs \
|
||||
&& mkdir -p /var/alchemy/Phraseanet/cache \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/cache \
|
||||
&& mkdir -p /var/alchemy/Phraseanet/datas \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/datas \
|
||||
&& mkdir -p /var/alchemy/Phraseanet/tmp \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/tmp \
|
||||
&& mkdir -p /var/alchemy/Phraseanet/www/custom \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/www/custom \
|
||||
&& mkdir -p /var/alchemy/Phraseanet/config \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/config
|
||||
|
||||
# Phraseanet
|
||||
FROM php:7.0-fpm-stretch as phraseanet-fpm
|
||||
@@ -129,6 +141,23 @@ RUN apt-get update \
|
||||
&& docker-php-source delete \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
|
||||
&& php -r "if (hash_file('sha384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
|
||||
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
|
||||
&& php -r "unlink('composer-setup.php');"
|
||||
|
||||
# Node Installation (node + yarn)
|
||||
# Reference :
|
||||
# https://linuxize.com/post/how-to-install-node-js-on-ubuntu-18.04/
|
||||
# https://yarnpkg.com/lang/en/docs/install/#debian-stable
|
||||
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
&& apt install -y nodejs \
|
||||
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
|
||||
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
|
||||
&& apt-get update && apt-get install -y --no-install-recommends yarn \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/
|
||||
|
||||
RUN mkdir /entrypoint /var/alchemy \
|
||||
&& useradd -u 1000 app \
|
||||
&& mkdir -p /home/app/.composer \
|
||||
@@ -136,18 +165,6 @@ RUN mkdir /entrypoint /var/alchemy \
|
||||
|
||||
COPY --from=builder --chown=app /var/alchemy /var/alchemy/Phraseanet
|
||||
ADD ./docker/phraseanet/ /
|
||||
RUN mkdir -p /var/alchemy/Phraseanet/logs \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/logs \
|
||||
&& mkdir -p /var/alchemy/Phraseanet/cache \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/cache \
|
||||
&& mkdir -p /var/alchemy/Phraseanet/datas \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/datas \
|
||||
&& mkdir -p /var/alchemy/Phraseanet/tmp \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/tmp \
|
||||
&& mkdir -p /var/alchemy/Phraseanet/www/custom \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/www/custom \
|
||||
&& mkdir -p /var/alchemy/Phraseanet/config \
|
||||
&& chmod -R 777 /var/alchemy/Phraseanet/config
|
||||
WORKDIR /var/alchemy/Phraseanet
|
||||
ENTRYPOINT ["/phraseanet-entrypoint.sh"]
|
||||
CMD ["/boot.sh"]
|
||||
|
16
README.md
16
README.md
@@ -63,14 +63,16 @@ The docker distribution come with 3 differents containers :
|
||||
|
||||
## How to build
|
||||
|
||||
The three images can be built respectively with these commands :
|
||||
You can build all the images with the following command at the root directory, choosing an arbirary TAG name :
|
||||
|
||||
# nginx server
|
||||
docker build --target phraseanet-nginx -t local/phraseanet-nginx .
|
||||
./build.sh <TAG>
|
||||
|
||||
# php-fpm application
|
||||
docker build --target phraseanet-fpm -t local/phraseanet-fpm .
|
||||
It will build and tag the following images :
|
||||
|
||||
# worker
|
||||
docker build --target phraseanet-worker -t local/phraseanet-worker .
|
||||
local/phraseanet-worker:<TAG>
|
||||
local/phraseanet-fpm:<TAG>
|
||||
local/phraseanet-nginx:<TAG>
|
||||
|
||||
# Deploy the application
|
||||
|
||||
Once the images are built, you can deploy the entire phraseanet stack using the repository : https://github.com/alchemy-fr/phraseanet-docker and follow the instruction inside its `README.md` file.
|
||||
|
11
build.sh
Executable file
11
build.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# nginx server
|
||||
docker build --target phraseanet-nginx -t local/phraseanet-nginx:$1 .
|
||||
|
||||
# php-fpm application
|
||||
docker build --target phraseanet-fpm -t local/phraseanet-fpm:$1 .
|
||||
|
||||
# worker
|
||||
docker build --target phraseanet-worker -t local/phraseanet-worker:$1 .
|
||||
|
0
cache/.gitkeep
vendored
Normal file
0
cache/.gitkeep
vendored
Normal file
@@ -1,4 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
cat nginx.conf.sample | sed "s/\$MAX_BODY_SIZE/$MAX_BODY_SIZE/g" > /etc/nginx/nginx.conf
|
||||
set -xe
|
||||
|
||||
cat nginx.conf.sample | sed "s/\$MAX_BODY_SIZE/$MAX_BODY_SIZE/g" > /etc/nginx/conf.d/default.conf
|
||||
nginx -g "daemon off;"
|
||||
|
31
docker/nginx/etc/nginx/nginx.conf
Executable file
31
docker/nginx/etc/nginx/nginx.conf
Executable file
@@ -0,0 +1,31 @@
|
||||
|
||||
user app;
|
||||
worker_processes 1;
|
||||
|
||||
error_log /var/log/ngnix_error.log info;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
#gzip on;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
|
||||
}
|
@@ -1,54 +1,9 @@
|
||||
user app;
|
||||
worker_processes auto;
|
||||
|
||||
#error_log /var/log/ngnix_error.log info;
|
||||
error_log /dev/stdout info;
|
||||
|
||||
pid /var/run/nginx.pid;
|
||||
#daemon off;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
multi_accept on;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
server_tokens off;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /dev/stdout main;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
#gzip on;
|
||||
|
||||
reset_timedout_connection on;
|
||||
|
||||
proxy_connect_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
fastcgi_send_timeout 300s;
|
||||
fastcgi_read_timeout 300;
|
||||
|
||||
resolver 127.0.0.11;
|
||||
|
||||
upstream backend {
|
||||
server phraseanet:9000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
error_log on;
|
||||
access_log on;
|
||||
root /var/alchemy/Phraseanet/www;
|
||||
|
||||
index index.php;
|
||||
@@ -82,4 +37,3 @@ http {
|
||||
fastcgi_pass backend;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,16 @@
|
||||
|
||||
set -xe
|
||||
|
||||
if [ $INSTALL_ACCOUNT_EMAIL = ""]; then
|
||||
echo "INSTALL_ACCOUNT_EMAIL var is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $INSTALL_ACCOUNT_PASSWORD = ""]; then
|
||||
echo "INSTALL_ACCOUNT_PASSWORD var is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
/var/alchemy/Phraseanet/bin/setup system:install \
|
||||
--email=$INSTALL_ACCOUNT_EMAIL \
|
||||
--password=$INSTALL_ACCOUNT_PASSWORD \
|
||||
|
@@ -1,5 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -xe
|
||||
|
||||
chown -R app:app /var/alchemy/Phraseanet/config
|
||||
chown -R app:app /var/alchemy/Phraseanet/datas
|
||||
chown -R app:app /var/alchemy/Phraseanet/tmp
|
||||
chown -R app:app /var/alchemy/Phraseanet/www/thumbnails
|
||||
FILE=/var/alchemy/Phraseanet/config/configuration.yml
|
||||
if [ -f "$FILE" ]; then
|
||||
echo "$FILE exist, skip setup."
|
||||
|
@@ -5,4 +5,4 @@ set -e
|
||||
envsubst < /php.ini.sample > /usr/local/etc/php/php.ini
|
||||
envsubst < /php-fpm.conf.sample > /usr/local/etc/php-fpm.conf
|
||||
|
||||
docker-php-entrypoint $@
|
||||
bash -e docker-php-entrypoint $@
|
||||
|
@@ -1,3 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
mkdir /var/alchemy/Phraseanet/tmp/locks && chown -R app:app /var/alchemy/Phraseanet/tmp
|
||||
runuser app -c 'php /var/alchemy/Phraseanet/bin/console task-manager:scheduler:run'
|
||||
|
@@ -128,7 +128,7 @@ key:
|
||||
| quoted_string()
|
||||
|
||||
group:
|
||||
::space::? ::parenthese_:: primary() ::_parenthese:: ::space::?
|
||||
::space::? ::parenthese_:: ::space::? primary() ::space::? ::_parenthese:: ::space::?
|
||||
|
||||
|
||||
// Thesaurus terms
|
||||
|
@@ -73,7 +73,7 @@ class RedisCache extends CacheProvider implements Cache
|
||||
*/
|
||||
protected function doDelete($id)
|
||||
{
|
||||
return $this->_redis->delete($id);
|
||||
return $this->_redis->del($id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\Command\Setup;
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Alchemy\Phrasea\Core\Configuration\StructureTemplate;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchOptions;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Symfony\Component\Console\Helper\DialogHelper;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
@@ -51,7 +52,9 @@ class Install extends Command
|
||||
->addOption('db-template', null, InputOption::VALUE_OPTIONAL, 'Databox template (' . $this->structureTemplate->toString() . ')', null)
|
||||
->addOption('data-path', null, InputOption::VALUE_OPTIONAL, 'Path to data repository', realpath(__DIR__ . '/../../../../../datas'))
|
||||
->addOption('server-name', null, InputOption::VALUE_OPTIONAL, 'Server name')
|
||||
->addOption('indexer', null, InputOption::VALUE_OPTIONAL, 'Path to Phraseanet Indexer', 'auto')
|
||||
->addOption('es-host', null, InputOption::VALUE_OPTIONAL, 'ElasticSearch server HTTP host', 'localhost')
|
||||
->addOption('es-port', null, InputOption::VALUE_OPTIONAL, 'ElasticSearch server HTTP port', 9200)
|
||||
->addOption('es-index', null, InputOption::VALUE_OPTIONAL, 'ElasticSearch index name', null)
|
||||
->addOption('yes', 'y', InputOption::VALUE_NONE, 'Answer yes to all questions');
|
||||
|
||||
return $this;
|
||||
@@ -121,6 +124,21 @@ class Install extends Command
|
||||
list($email, $password) = $this->getCredentials($input, $output, $dialog);
|
||||
$dataPath = $this->getDataPath($input, $output, $dialog);
|
||||
|
||||
if (! $input->getOption('yes')) {
|
||||
$output->writeln("<info>--- ElasticSearch connection settings ---</info>");
|
||||
}
|
||||
|
||||
list($esHost, $esPort) = $this->getESHost($input, $output, $dialog);
|
||||
$esIndexName = $this->getESIndexName($input, $output, $dialog);
|
||||
|
||||
$esOptions = ElasticsearchOptions::fromArray([
|
||||
'host' => $esHost,
|
||||
'port' => $esPort,
|
||||
'index' => $esIndexName
|
||||
]);
|
||||
|
||||
$output->writeln('');
|
||||
|
||||
if (!$input->getOption('yes')) {
|
||||
$continue = $dialog->askConfirmation($output, "<question>Phraseanet is going to be installed, continue ? (N/y)</question>", false);
|
||||
|
||||
@@ -132,6 +150,7 @@ class Install extends Command
|
||||
}
|
||||
|
||||
$this->container['phraseanet.installer']->install($email, $password, $abConn, $serverName, $dataPath, $dbConn, $templateName, $this->detectBinaries());
|
||||
$this->container['conf']->set(['main', 'search-engine', 'options'], $esOptions->toArray());
|
||||
|
||||
if (null !== $this->getApplication()) {
|
||||
$command = $this->getApplication()->find('crossdomain:generate');
|
||||
@@ -339,6 +358,35 @@ class Install extends Command
|
||||
return $serverName;
|
||||
}
|
||||
|
||||
private function getESHost(InputInterface $input, OutputInterface $output, DialogHelper $dialog)
|
||||
{
|
||||
$host = $input->getOption('es-host');
|
||||
$port = (int) $input->getOption('es-port');
|
||||
|
||||
if (! $input->getOption('yes')) {
|
||||
while (! $host) {
|
||||
$host = $dialog->ask($output, 'ElasticSearch server host : ', null);
|
||||
};
|
||||
|
||||
while ($port <= 0 || $port >= 65535) {
|
||||
$port = (int) $dialog->ask($output, 'ElasticSearch server port : ', null);
|
||||
};
|
||||
}
|
||||
|
||||
return [ $host, $port ];
|
||||
}
|
||||
|
||||
private function getESIndexName(InputInterface $input, OutputInterface $output, DialogHelper $dialog)
|
||||
{
|
||||
$index = $input->getOption('es-index');
|
||||
|
||||
if (! $input->getOption('yes')) {
|
||||
$index = $dialog->ask($output, 'ElasticSearch server index name (blank to autogenerate) : ', null);
|
||||
}
|
||||
|
||||
return $index;
|
||||
}
|
||||
|
||||
private function detectBinaries()
|
||||
{
|
||||
return [
|
||||
|
@@ -316,6 +316,7 @@ class FieldsController extends Controller
|
||||
->set_tbranch($data['tbranch'])
|
||||
->set_generate_cterms($data['generate_cterms'])
|
||||
->set_gui_editable($data['gui_editable'])
|
||||
->set_gui_visible($data['gui_visible'])
|
||||
->set_report($data['report'])
|
||||
->setVocabularyControl(null)
|
||||
->setVocabularyRestricted(false);
|
||||
@@ -351,7 +352,7 @@ class FieldsController extends Controller
|
||||
{
|
||||
return [
|
||||
'name', 'multi', 'thumbtitle', 'tag', 'business', 'indexable', 'aggregable',
|
||||
'required', 'separator', 'readonly', 'gui_editable', 'type', 'tbranch', 'generate_cterms', 'report',
|
||||
'required', 'separator', 'readonly', 'gui_editable', 'gui_visible' , 'type', 'tbranch', 'generate_cterms', 'report',
|
||||
'vocabulary-type', 'vocabulary-restricted', 'dces-element', 'labels'
|
||||
];
|
||||
}
|
||||
|
@@ -596,6 +596,7 @@ class V1Controller extends Controller
|
||||
'thesaurus_branch' => $databox_field->get_tbranch(),
|
||||
'generate_cterms' => $databox_field->get_generate_cterms(),
|
||||
'gui_editable' => $databox_field->get_gui_editable(),
|
||||
'gui_visible' => $databox_field->get_gui_visible(),
|
||||
'type' => $databox_field->get_type(),
|
||||
'indexable' => $databox_field->is_indexable(),
|
||||
'multivalue' => $databox_field->is_multi(),
|
||||
|
@@ -77,6 +77,7 @@ class EditController extends Controller
|
||||
'tbranch' => $meta->get_tbranch(),
|
||||
'generate_cterms' => $meta->get_generate_cterms(),
|
||||
'gui_editable' => $meta->get_gui_editable(),
|
||||
'gui_visible' => $meta->get_gui_visible(),
|
||||
'maxLength' => $meta->get_tag()
|
||||
->getMaxLength(),
|
||||
'minLength' => $meta->get_tag()
|
||||
|
@@ -126,6 +126,16 @@ class LazaretController extends Controller
|
||||
|
||||
$ret = $lazaretManipulator->add($file_id, $keepAttributes, $attributesToKeep);
|
||||
|
||||
try{
|
||||
// get the new record
|
||||
$record = \Collection::getByBaseId($this->app, $request->request->get('bas_id'))->get_databox()->get_record($ret['result']['record_id']);
|
||||
$postStatus = (array) $request->request->get('status');
|
||||
// update status
|
||||
$this->updateRecordStatus($record, $postStatus);
|
||||
}catch(\Exception $e){
|
||||
$ret['message'] = $this->app->trans('An error occured when wanting to change status!');
|
||||
}
|
||||
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
|
||||
@@ -216,6 +226,7 @@ class LazaretController extends Controller
|
||||
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
$postStatus = (array) $request->request->get('status');
|
||||
|
||||
$path = $this->app['tmp.lazaret.path'] . '/';
|
||||
$lazaretFileName = $path .$lazaretFile->getFilename();
|
||||
@@ -233,6 +244,9 @@ class LazaretController extends Controller
|
||||
''
|
||||
);
|
||||
|
||||
// update status
|
||||
$this->updateRecordStatus($record, $postStatus);
|
||||
|
||||
//Delete lazaret file
|
||||
$manager = $this->getEntityManager();
|
||||
$manager->remove($lazaretFile);
|
||||
@@ -278,6 +292,35 @@ class LazaretController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param $databox_id
|
||||
* @param $record_id
|
||||
* @return \Symfony\Component\HttpFoundation\JsonResponse
|
||||
*/
|
||||
public function getDestinationStatus(Request $request, $databox_id, $record_id)
|
||||
{
|
||||
if (!$request->isXmlHttpRequest()) {
|
||||
$this->app->abort(400);
|
||||
}
|
||||
$record = new \record_adapter($this->app, (int) $databox_id, (int) $record_id);
|
||||
$databox = $this->findDataboxById($databox_id);
|
||||
$statusStructure = $databox->getStatusStructure();
|
||||
$recordsStatuses = [];
|
||||
foreach ($statusStructure as $status) {
|
||||
// make the key as a string for the json usage in javascript
|
||||
$bit = "'".$status['bit']."'";
|
||||
if (!isset($recordsStatuses[$bit])) {
|
||||
$recordsStatuses[$bit] = $status;
|
||||
}
|
||||
$statusSet = \databox_status::bitIsSet($record->getStatusBitField(), $status['bit']);
|
||||
if (!isset($recordsStatuses[$bit]['flag'])) {
|
||||
$recordsStatuses[$bit]['flag'] = (int) $statusSet;
|
||||
}
|
||||
}
|
||||
return $this->app->json(['status' => $recordsStatuses]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LazaretFileRepository
|
||||
*/
|
||||
@@ -293,4 +336,32 @@ class LazaretController extends Controller
|
||||
{
|
||||
return $this->app['border-manager'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new status to selected record
|
||||
*
|
||||
* @param \record_adapter $record
|
||||
* @param array $postStatus
|
||||
* @return array|null
|
||||
*/
|
||||
private function updateRecordStatus(\record_adapter $record, array $postStatus)
|
||||
{
|
||||
$sbasId = $record->getDataboxId();
|
||||
if (isset($postStatus[$sbasId]) && is_array($postStatus[$sbasId])) {
|
||||
$postStatus = $postStatus[$sbasId];
|
||||
$currentStatus = strrev($record->getStatus());
|
||||
$newStatus = '';
|
||||
foreach (range(0, 31) as $i) {
|
||||
$newStatus .= isset($postStatus[$i]) ? ($postStatus[$i] ? '1' : '0') : $currentStatus[$i];
|
||||
}
|
||||
$record->setStatus(strrev($newStatus));
|
||||
$this->getDataboxLogger($record->getDatabox())
|
||||
->log($record, \Session_Logger::EVENT_STATUS, '', '');
|
||||
return [
|
||||
'current_status' => $currentStatus,
|
||||
'new_status' => $newStatus,
|
||||
];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -341,10 +341,20 @@ class QueryController extends Controller
|
||||
|
||||
if ($result->getTotal() === 0) {
|
||||
$template = 'prod/results/help.html.twig';
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$template = 'prod/results/records.html.twig';
|
||||
}
|
||||
$json['results'] = $this->render($template, ['results'=> $result]);
|
||||
|
||||
/** @var \Closure $filter */
|
||||
$filter = $this->app['plugin.filter_by_authorization'];
|
||||
|
||||
$plugins = [
|
||||
'workzone' => $filter('workzone'),
|
||||
'actionbar' => $filter('actionbar'),
|
||||
];
|
||||
|
||||
$json['results'] = $this->render($template, ['results'=> $result, 'plugins'=>$plugins]);
|
||||
|
||||
|
||||
// add technical fields
|
||||
@@ -382,7 +392,6 @@ class QueryController extends Controller
|
||||
'labels' => $field->get_labels(),
|
||||
'type' => $field->get_type(),
|
||||
'field' => $field->get_name(),
|
||||
'query' => "field." . $field->get_name() . ":%s",
|
||||
'trans_label' => $field->get_label($this->app['locale']),
|
||||
];
|
||||
$field->get_label($this->app['locale']);
|
||||
|
@@ -82,6 +82,11 @@ class Lazaret implements ControllerProviderInterface, ServiceProviderInterface
|
||||
->assert('file_id', '\d+')
|
||||
->bind('lazaret_thumbnail');
|
||||
|
||||
$controllers->get('/{databox_id}/{record_id}/status', 'controller.prod.lazaret:getDestinationStatus')
|
||||
->assert('databox_id', '\d+')
|
||||
->assert('record_id', '\d+')
|
||||
->bind('lazaret_destination_status');
|
||||
|
||||
return $controllers;
|
||||
}
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ final class DbalDataboxFieldRepository implements DataboxFieldRepository
|
||||
'label_nl',
|
||||
'generate_cterms',
|
||||
'gui_editable',
|
||||
'gui_visible',
|
||||
];
|
||||
|
||||
/** @var DataboxFieldFactory */
|
||||
|
@@ -12,6 +12,7 @@
|
||||
namespace Alchemy\Phrasea\Model\Entities;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Border\Attribute\AttributeInterface;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Gedmo\Mapping\Annotation as Gedmo;
|
||||
use \record_adapter;
|
||||
@@ -474,4 +475,32 @@ class LazaretFile
|
||||
return $merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Application $app
|
||||
* @return array|null
|
||||
*/
|
||||
public function getStatus(Application $app)
|
||||
{
|
||||
/**@var LazaretAttribute $atribute*/
|
||||
foreach ($this->attributes as $atribute) {
|
||||
if ($atribute->getName() == AttributeInterface::NAME_STATUS) {
|
||||
$databox = $this->getCollection($app)->get_databox();
|
||||
$statusStructure = $databox->getStatusStructure();
|
||||
$recordsStatuses = [];
|
||||
foreach ($statusStructure as $status) {
|
||||
$bit = $status['bit'];
|
||||
if (!isset($recordsStatuses[$bit])) {
|
||||
$recordsStatuses[$bit] = $status;
|
||||
}
|
||||
$statusSet = \databox_status::bitIsSet(bindec($atribute->getValue()), $bit);
|
||||
if (!isset($recordsStatuses[$bit]['flag'])) {
|
||||
$recordsStatuses[$bit]['flag'] = (int) $statusSet;
|
||||
}
|
||||
}
|
||||
return $recordsStatuses;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -226,6 +226,8 @@ class LazaretManipulator
|
||||
$this->entityManager->remove($lazaretFile);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$ret['result']['record_id'] = $record->getRecordId();
|
||||
|
||||
$ret['success'] = true;
|
||||
} catch (\Exception $e) {
|
||||
$ret['message'] = $this->app->trans('An error occured');
|
||||
|
@@ -45,6 +45,9 @@ class TextNode extends AbstractTermNode implements ContextAbleInterface
|
||||
foreach ($context->localizeField($field) as $f) {
|
||||
$index_fields[] = $f;
|
||||
}
|
||||
foreach ($context->truncationField($field) as $f) {
|
||||
$index_fields[] = $f;
|
||||
}
|
||||
}
|
||||
if (!$index_fields) {
|
||||
return null;
|
||||
|
@@ -323,7 +323,7 @@ class ElasticsearchOptions
|
||||
"aggregated (2 values: fired = 0 or 1)" => -1,
|
||||
],
|
||||
'output_formatter' => function($value) {
|
||||
static $map = ['0'=>"No flash", '1'=>"Flash"];
|
||||
static $map = ["false"=>"No flash", "true"=>"Flash", '0'=>"No flash", '1'=>"Flash"];
|
||||
return array_key_exists($value, $map) ? $map[$value] : $value;
|
||||
},
|
||||
],
|
||||
|
@@ -90,6 +90,16 @@ class Index
|
||||
// TODO Maybe replace nfkc_normalizer + asciifolding with icu_folding
|
||||
'filter' => ['nfkc_normalizer', 'asciifolding']
|
||||
],
|
||||
'truncation_analyzer' => [
|
||||
'type' => 'custom',
|
||||
'tokenizer' => 'truncation_tokenizer',
|
||||
'filter' => ['lowercase', 'stop', 'kstem']
|
||||
],
|
||||
'truncation_analyzer#search' => [
|
||||
'type' => 'custom',
|
||||
'tokenizer' => 'truncation_tokenizer',
|
||||
'filter' => ['lowercase', 'stop', 'kstem']
|
||||
],
|
||||
// Lang specific
|
||||
'fr_full' => [
|
||||
'type' => 'custom',
|
||||
@@ -145,6 +155,12 @@ class Index
|
||||
]
|
||||
],
|
||||
'tokenizer' => [
|
||||
'truncation_tokenizer' => [
|
||||
"type" => "edgeNGram",
|
||||
"min_gram" => "2",
|
||||
"max_gram" => "15",
|
||||
"token_chars" => [ "letter", "digit", "punctuation", "symbol" ]
|
||||
],
|
||||
'thesaurus_path' => [
|
||||
'type' => 'path_hierarchy'
|
||||
]
|
||||
|
@@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic\Indexer\Record\Hydrator;
|
||||
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\Exception;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\GlobalStructure;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Thesaurus;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Thesaurus\CandidateTerms;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Thesaurus\Concept;
|
||||
@@ -27,7 +28,7 @@ class ThesaurusHydrator implements HydratorInterface
|
||||
private $thesaurus;
|
||||
private $candidate_terms;
|
||||
|
||||
public function __construct(Structure $structure, Thesaurus $thesaurus, CandidateTerms $candidate_terms)
|
||||
public function __construct(GlobalStructure $structure, Thesaurus $thesaurus, CandidateTerms $candidate_terms)
|
||||
{
|
||||
$this->structure = $structure;
|
||||
$this->thesaurus = $thesaurus;
|
||||
@@ -67,7 +68,13 @@ class ThesaurusHydrator implements HydratorInterface
|
||||
$terms = array();
|
||||
$filters = array();
|
||||
$field_names = array();
|
||||
/** @var Field[] $dbFields */
|
||||
$dbFields = $this->structure->getAllFieldsByDatabox($record['databox_id']);
|
||||
foreach ($fields as $name => $field) {
|
||||
if(!array_key_exists($name, $dbFields) || !$dbFields[$name]->get_generate_cterms()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$root_concepts = $field->getThesaurusRoots();
|
||||
// Loop through all values to prepare bulk query
|
||||
$field_values = \igorw\get_in($record, explode('.', $index_fields[$name]));
|
||||
@@ -98,11 +105,8 @@ class ThesaurusHydrator implements HydratorInterface
|
||||
}
|
||||
}
|
||||
else {
|
||||
$field = $fields[$name];
|
||||
if($field->get_generate_cterms()) {
|
||||
$this->candidate_terms->insert($field_names[$offset], $values[$offset]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -55,8 +55,13 @@ class StringFieldMapping extends ComplexFieldMapping
|
||||
{
|
||||
$child = new StringFieldMapping('light');
|
||||
$child->setAnalyzer('general_light');
|
||||
|
||||
$this->addChild($child);
|
||||
|
||||
$child = new StringFieldMapping('truncated');
|
||||
$child->setAnalyzer('truncation_analyzer', 'indexing');
|
||||
$child->setAnalyzer('truncation_analyzer#search', 'searching');
|
||||
$this->addChild($child);
|
||||
|
||||
$this->addLocalizedChildren($locales);
|
||||
|
||||
return $this;
|
||||
|
@@ -4,6 +4,11 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
||||
|
||||
class Escaper
|
||||
{
|
||||
public function quoteWord($value)
|
||||
{
|
||||
return '"' . $this->escapeRaw($value) . '"';
|
||||
}
|
||||
|
||||
public function escapeWord($value)
|
||||
{
|
||||
// Strip double quotes from values to prevent broken queries
|
||||
|
@@ -46,22 +46,23 @@ class FacetsResponse
|
||||
if (!isset($bucket['key']) || !isset($bucket['doc_count'])) {
|
||||
$this->throwAggregationResponseError();
|
||||
}
|
||||
$key = array_key_exists('key_as_string', $bucket) ? $bucket['key_as_string'] : $bucket['key'];
|
||||
if($tf) {
|
||||
// the field is one of the hardcoded tech fields
|
||||
$value = [
|
||||
'value' => $valueFormatter($bucket['key']),
|
||||
'raw_value' => $bucket['key'],
|
||||
'value' => $valueFormatter($key),
|
||||
'raw_value' => $key,
|
||||
'count' => $bucket['doc_count'],
|
||||
'query' => sprintf($tf['query'], $this->escaper->escapeWord($bucket['key']))
|
||||
'query' => sprintf($tf['query'], $this->escaper->escapeWord($key))
|
||||
];
|
||||
}
|
||||
else {
|
||||
// the field is a normal field
|
||||
$value = [
|
||||
'value' => $bucket['key'],
|
||||
'raw_value' => $bucket['key'],
|
||||
'value' => $key,
|
||||
'raw_value' => $key,
|
||||
'count' => $bucket['doc_count'],
|
||||
'query' => sprintf('field.%s:%s', $this->escaper->escapeWord($name), $this->escaper->escapeWord($bucket['key']))
|
||||
'query' => sprintf('field.%s=%s', $this->escaper->escapeWord($name), $this->escaper->quoteWord($key))
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -9,6 +9,7 @@ use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Field;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST\Field as ASTField;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST\Flag;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure;
|
||||
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
|
||||
|
||||
/**
|
||||
* @todo Check for private fields and only search on them if allowed
|
||||
@@ -23,13 +24,23 @@ class QueryContext
|
||||
private $queryLocale;
|
||||
/** @var array */
|
||||
private $fields;
|
||||
/** @var SearchEngineOptions */
|
||||
private $options;
|
||||
|
||||
public function __construct(Structure $structure, array $locales, $queryLocale, array $fields = null)
|
||||
/**
|
||||
* @param SearchEngineOptions|null $options
|
||||
* @param Structure $structure
|
||||
* @param array $locales
|
||||
* @param $queryLocale
|
||||
* @param array $fields
|
||||
*/
|
||||
public function __construct($options, Structure $structure, array $locales, $queryLocale, array $fields = null)
|
||||
{
|
||||
$this->structure = $structure;
|
||||
$this->locales = $locales;
|
||||
$this->queryLocale = $queryLocale;
|
||||
$this->fields = $fields;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
public function narrowToFields(array $fields)
|
||||
@@ -43,7 +54,7 @@ class QueryContext
|
||||
}
|
||||
}
|
||||
|
||||
return new static($this->structure, $this->locales, $this->queryLocale, $fields);
|
||||
return new static($this->options, $this->structure, $this->locales, $this->queryLocale, $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,6 +142,16 @@ class QueryContext
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function truncationField(Field $field)
|
||||
{
|
||||
if($this->options && $this->options->useTruncation()) {
|
||||
return [sprintf('%s.truncated', $field->getIndexField())];
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private function localizeFieldName($field)
|
||||
{
|
||||
$fields = array();
|
||||
|
@@ -23,7 +23,7 @@ class QueryContextFactory
|
||||
? $this->getLimitedStructure($options)
|
||||
: $this->structure;
|
||||
|
||||
$context = new QueryContext($structure, $this->locales, $this->current_locale);
|
||||
$context = new QueryContext($options, $structure, $this->locales, $this->current_locale);
|
||||
|
||||
if ($options) {
|
||||
$fields = $this->getSearchedFields($options);
|
||||
|
@@ -63,4 +63,26 @@ class StringUtils
|
||||
|
||||
return self::$transliterator->transliterate($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* replace bad chars (ascii 0...31 except 9,10,13)
|
||||
*
|
||||
* @param $s
|
||||
* @param string $replace
|
||||
* @return mixed
|
||||
*/
|
||||
public static function substituteCtrlCharacters($s, $replace = '_')
|
||||
{
|
||||
static $bad_chars = null;
|
||||
if($bad_chars === null) {
|
||||
$bad_chars = [];
|
||||
for($i=0; $i<32; $i++) {
|
||||
if($i != 9 && $i != 10 && $i != 13) {
|
||||
$bad_chars[] = chr($i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str_replace($bad_chars, $replace, $s);
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,11 @@ class Field implements Typed
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $databox_id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -73,6 +78,7 @@ class Field implements Typed
|
||||
}
|
||||
|
||||
return new self($field->get_name(), $type, [
|
||||
'databox_id' => $databox->get_sbas_id(),
|
||||
'searchable' => $field->is_indexable(),
|
||||
'private' => $field->isBusiness(),
|
||||
'facet' => $facet,
|
||||
@@ -102,6 +108,7 @@ class Field implements Typed
|
||||
{
|
||||
$this->name = (string) $name;
|
||||
$this->type = $type;
|
||||
$this->databox_id = \igorw\get_in($options, ['databox_id'], 0);
|
||||
$this->is_searchable = \igorw\get_in($options, ['searchable'], true);
|
||||
$this->is_private = \igorw\get_in($options, ['private'], false);
|
||||
$this->facet = \igorw\get_in($options, ['facet']);
|
||||
@@ -126,6 +133,7 @@ class Field implements Typed
|
||||
public function withOptions(array $options)
|
||||
{
|
||||
return new self($this->name, $this->type, $options + [
|
||||
'databox_id' => $this->databox_id,
|
||||
'searchable' => $this->is_searchable,
|
||||
'private' => $this->is_private,
|
||||
'facet' => $this->facet,
|
||||
@@ -155,6 +163,11 @@ class Field implements Typed
|
||||
return sprintf('concept_path.%s', $this->name);
|
||||
}
|
||||
|
||||
public function get_databox_id()
|
||||
{
|
||||
return $this->databox_id;
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
|
@@ -14,6 +14,12 @@ final class GlobalStructure implements Structure
|
||||
*/
|
||||
private $fields = array();
|
||||
|
||||
|
||||
/**
|
||||
* @var Field[][]
|
||||
*/
|
||||
private $fieldsByDatabox = [];
|
||||
|
||||
/**
|
||||
* @var Field[]
|
||||
* */
|
||||
@@ -119,6 +125,10 @@ final class GlobalStructure implements Structure
|
||||
|
||||
public function add(Field $field)
|
||||
{
|
||||
// store info for each field, not still merged by databox
|
||||
$this->fieldsByDatabox[$field->get_databox_id()][$field->getName()] = $field;
|
||||
|
||||
// store merged infos (same field name)
|
||||
$name = $field->getName();
|
||||
|
||||
if (isset($this->fields[$name])) {
|
||||
@@ -152,6 +162,11 @@ final class GlobalStructure implements Structure
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
public function getAllFieldsByDatabox($databox_id)
|
||||
{
|
||||
return $this->fieldsByDatabox[$databox_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Field[]
|
||||
*/
|
||||
|
@@ -32,6 +32,7 @@ class CandidateTerms
|
||||
|
||||
public function insert($field, $value)
|
||||
{
|
||||
$value = StringUtils::substituteCtrlCharacters($value, '');
|
||||
$this->ensureVisitorSetup();
|
||||
if (!$this->visitor->hasTerm($field, $value)) {
|
||||
$this->new_candidates[$value] = $field;
|
||||
|
@@ -71,6 +71,8 @@ class SearchEngineOptions
|
||||
protected $i18n;
|
||||
/** @var bool */
|
||||
protected $stemming = true;
|
||||
/** @var bool */
|
||||
protected $use_truncation = false;
|
||||
/** @var string */
|
||||
protected $sort_by;
|
||||
|
||||
@@ -105,7 +107,8 @@ class SearchEngineOptions
|
||||
'sort_ord',
|
||||
'business_fields',
|
||||
'max_results',
|
||||
'first_result'
|
||||
'first_result',
|
||||
'use_truncation',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -217,6 +220,29 @@ class SearchEngineOptions
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether to use truncation or not
|
||||
*
|
||||
* @param boolean $boolean
|
||||
* @return $this
|
||||
*/
|
||||
public function setUseTruncation($boolean)
|
||||
{
|
||||
$this->use_truncation = !!$boolean;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return wheter the use of truncation is enabled or not
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function useTruncation()
|
||||
{
|
||||
return $this->use_truncation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return wheter the use of stemming is enabled or not
|
||||
*
|
||||
@@ -542,6 +568,8 @@ class SearchEngineOptions
|
||||
$options->setFields($databoxFields);
|
||||
$options->setDateFields($databoxDateFields);
|
||||
|
||||
$options->setUseTruncation((Boolean) $request->get('truncation'));
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
@@ -628,6 +656,7 @@ class SearchEngineOptions
|
||||
}
|
||||
},
|
||||
'stemming' => $optionSetter('setStemming'),
|
||||
'use_truncation' => $optionSetter('setUseTruncation'),
|
||||
'date_fields' => function ($value, SearchEngineOptions $options) use ($fieldNormalizer) {
|
||||
$options->setDateFields($fieldNormalizer($value));
|
||||
},
|
||||
|
@@ -48,6 +48,7 @@ class PhraseanetExtension extends \Twig_Extension
|
||||
new \Twig_SimpleFunction('border_checker_from_fqcn', array($this, 'getCheckerFromFQCN')),
|
||||
new \Twig_SimpleFunction('caption_field', array($this, 'getCaptionField')),
|
||||
new \Twig_SimpleFunction('caption_field_label', array($this, 'getCaptionFieldLabel')),
|
||||
new \Twig_SimpleFunction('caption_field_gui_visible', array($this, 'getCaptionFieldGuiVisible')),
|
||||
new \Twig_SimpleFunction('caption_field_order', array($this, 'getCaptionFieldOrder')),
|
||||
|
||||
new \Twig_SimpleFunction('flag_slugify', array(Flag::class, 'normalizeName')),
|
||||
@@ -77,6 +78,29 @@ class PhraseanetExtension extends \Twig_Extension
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* get localized field's gui_visible
|
||||
* @param RecordInterface $record
|
||||
* @param $fieldName
|
||||
* @return string - the name gui_visible
|
||||
*/
|
||||
public function getCaptionFieldGuiVisible(RecordInterface $record, $fieldName)
|
||||
{
|
||||
if ($record) {
|
||||
/** @var \appbox $appbox */
|
||||
$appbox = $this->app['phraseanet.appbox'];
|
||||
$databox = $appbox->get_databox($record->getDataboxId());
|
||||
foreach ($databox->get_meta_structure() as $meta) {
|
||||
/** @var \databox_field $meta */
|
||||
if ($meta->get_name() === $fieldName) {
|
||||
return $meta->get_gui_visible($this->app['locale']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getCaptionField(RecordInterface $record, $field, $value)
|
||||
{
|
||||
if ($record instanceof ElasticsearchRecord) {
|
||||
|
@@ -80,7 +80,7 @@ class RedisSessionHandler implements \SessionHandlerInterface
|
||||
*/
|
||||
public function destroy($sessionId)
|
||||
{
|
||||
return 1 === $this->redis->delete($this->prefix.$sessionId);
|
||||
return 1 === $this->redis->del($this->prefix.$sessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -463,7 +463,8 @@ class databox extends base implements ThumbnailedElement
|
||||
->set_type($type)
|
||||
->set_tbranch(isset($field['tbranch']) ? (string) $field['tbranch'] : '')
|
||||
->set_generate_cterms((isset($field['generate_cterms']) && (string) $field['generate_cterms'] == 1))
|
||||
->set_gui_editable((isset($field['gui_editable']) && (string) $field['gui_editable'] == 1))
|
||||
->set_gui_editable((!isset($field['gui_editable']) || (isset($field['gui_editable']) && (string) $field['gui_editable'] == 1)))
|
||||
->set_gui_visible((!isset($field['gui_visible']) || (isset($field['gui_visible']) && (string) $field['gui_visible'] == 1)))
|
||||
->set_thumbtitle(isset($field['thumbtitle']) ? (string) $field['thumbtitle'] : (isset($field['thumbTitle']) ? $field['thumbTitle'] : '0'))
|
||||
->set_report(isset($field['report']) ? (string) $field['report'] : '1')
|
||||
->save();
|
||||
|
@@ -45,6 +45,7 @@ class databox_field implements cache_cacheableInterface
|
||||
protected $tbranch;
|
||||
protected $generate_cterms;
|
||||
protected $gui_editable;
|
||||
protected $gui_visible;
|
||||
protected $separator;
|
||||
protected $thumbtitle;
|
||||
|
||||
@@ -170,6 +171,7 @@ class databox_field implements cache_cacheableInterface
|
||||
$this->tbranch = $row['tbranch'];
|
||||
$this->generate_cterms = (bool)$row['generate_cterms'];
|
||||
$this->gui_editable = (bool)$row['gui_editable'];
|
||||
$this->gui_visible = (bool)$row['gui_visible'];
|
||||
$this->VocabularyType = $row['VocabularyControlType'];
|
||||
$this->VocabularyRestriction = (bool)$row['RestrictToVocabularyControl'];
|
||||
|
||||
@@ -312,6 +314,7 @@ class databox_field implements cache_cacheableInterface
|
||||
`tbranch` = :tbranch,
|
||||
`generate_cterms` = :generate_cterms,
|
||||
`gui_editable` = :gui_editable,
|
||||
`gui_visible` = :gui_visible,
|
||||
`sorter` = :position,
|
||||
`thumbtitle` = :thumbtitle,
|
||||
`VocabularyControlType` = :VocabularyControlType,
|
||||
@@ -337,6 +340,7 @@ class databox_field implements cache_cacheableInterface
|
||||
':tbranch' => $this->tbranch,
|
||||
':generate_cterms' => $this->generate_cterms ? '1' : '0',
|
||||
':gui_editable' => $this->gui_editable ? '1' : '0',
|
||||
':gui_visible' => $this->gui_visible ? '1' : '0',
|
||||
':position' => $this->position,
|
||||
':thumbtitle' => $this->thumbtitle,
|
||||
':VocabularyControlType' => $this->getVocabularyControl() ? $this->getVocabularyControl()->getType() : null,
|
||||
@@ -390,6 +394,7 @@ class databox_field implements cache_cacheableInterface
|
||||
$meta->setAttribute('tbranch', $this->tbranch);
|
||||
$meta->setAttribute('generate_cterms', $this->generate_cterms ? '1' : '0');
|
||||
$meta->setAttribute('gui_editable', $this->gui_editable ? '1' : '0');
|
||||
$meta->setAttribute('gui_visible', $this->gui_visible ? '1' : '0');
|
||||
if ($this->multi) {
|
||||
$meta->setAttribute('separator', $this->separator);
|
||||
}
|
||||
@@ -743,6 +748,17 @@ class databox_field implements cache_cacheableInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $gui_visible
|
||||
* @return databox_field
|
||||
*/
|
||||
public function set_gui_visible($gui_visible)
|
||||
{
|
||||
$this->gui_visible = $gui_visible;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $separator
|
||||
@@ -845,6 +861,15 @@ class databox_field implements cache_cacheableInterface
|
||||
return $this->gui_editable;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function get_gui_visible()
|
||||
{
|
||||
return $this->gui_visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Boolean $all If set to false, returns a one-char separator to use for serialiation
|
||||
*
|
||||
@@ -957,6 +982,7 @@ class databox_field implements cache_cacheableInterface
|
||||
'tbranch' => $this->tbranch,
|
||||
'generate_cterms' => $this->generate_cterms,
|
||||
'gui_editable' => $this->gui_editable,
|
||||
'gui_visible' => $this->gui_visible,
|
||||
'separator' => $this->separator,
|
||||
'required' => $this->required,
|
||||
'report' => $this->report,
|
||||
@@ -995,10 +1021,10 @@ class databox_field implements cache_cacheableInterface
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO metadatas_structure
|
||||
(`id`, `name`, `src`, `readonly`, `gui_editable`, `required`, `indexable`, `type`, `tbranch`, `generate_cterms`,
|
||||
(`id`, `name`, `src`, `readonly`, `gui_editable`,`gui_visible`, `required`, `indexable`, `type`, `tbranch`, `generate_cterms`,
|
||||
`thumbtitle`, `multi`, `business`, `aggregable`,
|
||||
`report`, `sorter`, `separator`)
|
||||
VALUES (null, :name, '', 0, 1, 0, 1, 'string', '', 1,
|
||||
VALUES (null, :name, '', 0, 1, 1, 0, 1, 'string', '', 1,
|
||||
null, 0, 0, 0,
|
||||
1, :sorter, '')";
|
||||
|
||||
|
@@ -2049,6 +2049,14 @@
|
||||
<default>1</default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>gui_visible</name>
|
||||
<type>int(1) unsigned</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default>1</default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
</fields>
|
||||
<indexes>
|
||||
<index>
|
||||
|
@@ -79,7 +79,7 @@
|
||||
<size>748</size>
|
||||
<mediatype>video</mediatype>
|
||||
<writeDatas>yes</writeDatas>
|
||||
<acodec>libfaac</acodec>
|
||||
<acodec>libmp3lame</acodec>
|
||||
<vcodec>libx264</vcodec>
|
||||
<devices>screen</devices>
|
||||
<bitrate>1000</bitrate>
|
||||
|
@@ -79,7 +79,7 @@
|
||||
<size>748</size>
|
||||
<mediatype>video</mediatype>
|
||||
<writeDatas>yes</writeDatas>
|
||||
<acodec>libfaac</acodec>
|
||||
<acodec>libmp3lame</acodec>
|
||||
<vcodec>libx264</vcodec>
|
||||
<devices>screen</devices>
|
||||
<bitrate>1000</bitrate>
|
||||
|
@@ -79,7 +79,7 @@
|
||||
<size>748</size>
|
||||
<mediatype>video</mediatype>
|
||||
<writeDatas>yes</writeDatas>
|
||||
<acodec>libfaac</acodec>
|
||||
<acodec>libmp3lame</acodec>
|
||||
<vcodec>libx264</vcodec>
|
||||
<devices>screen</devices>
|
||||
<bitrate>1000</bitrate>
|
||||
|
@@ -65,7 +65,7 @@
|
||||
"normalize-css": "^2.1.0",
|
||||
"npm": "^6.0.0",
|
||||
"npm-modernizr": "^2.8.3",
|
||||
"phraseanet-production-client": "0.34.72-d",
|
||||
"phraseanet-production-client": "0.34.80-d",
|
||||
"requirejs": "^2.3.5",
|
||||
"tinymce": "^4.0.28",
|
||||
"underscore": "^1.8.3",
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
|
||||
<file date="2019-05-21T05:53:02Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
|
||||
<file date="2019-11-19T08:48:53Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
|
||||
<header>
|
||||
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
|
||||
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
|
||||
<file date="2019-05-21T05:54:16Z" source-language="en" target-language="en" datatype="plaintext" original="not.available">
|
||||
<file date="2019-11-19T08:49:17Z" source-language="en" target-language="en" datatype="plaintext" original="not.available">
|
||||
<header>
|
||||
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
|
||||
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
|
||||
<file date="2019-05-21T05:55:28Z" source-language="en" target-language="fr" datatype="plaintext" original="not.available">
|
||||
<file date="2019-11-15T08:03:23Z" source-language="en" target-language="fr" datatype="plaintext" original="not.available">
|
||||
<header>
|
||||
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
|
||||
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
|
||||
<file date="2019-05-21T05:56:47Z" source-language="en" target-language="nl" datatype="plaintext" original="not.available">
|
||||
<file date="2019-11-19T08:50:13Z" source-language="en" target-language="nl" datatype="plaintext" original="not.available">
|
||||
<header>
|
||||
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
|
||||
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
|
||||
|
31
resources/www/common/images/icons/icon-right-arrow.svg
Normal file
31
resources/www/common/images/icons/icon-right-arrow.svg
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 58 (101010) - https://sketch.com -->
|
||||
<title>5609DDD5-6B9C-411B-B926-EEA284949013</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<polygon id="path-1" points="0 0 22.3169609 16.2062701 0 32.4125403"></polygon>
|
||||
<filter x="-31.4%" y="-15.4%" width="162.7%" height="143.2%" filterUnits="objectBoundingBox" id="filter-3">
|
||||
<feOffset dx="0" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="Pictos" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Pictos/Arrow/Pleine">
|
||||
<g id="Colors/Black" transform="translate(5.000000, 0.000000)">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<g id="Mask" fill="black" fill-opacity="1">
|
||||
<use filter="url(#filter-3)" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<g id="Colors/Rectangular/Black" mask="url(#mask-2)" fill="#000000">
|
||||
<g transform="translate(-5.000000, 0.000000)" id="Rectangle">
|
||||
<rect x="0" y="0" width="32" height="32"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
resources/www/common/images/icons/to_be_denied.svg
Normal file
1
resources/www/common/images/icons/to_be_denied.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="times-circle" class="svg-inline--fa fa-times-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#aaa" d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm101.8-262.2L295.6 256l62.2 62.2c4.7 4.7 4.7 12.3 0 17l-22.6 22.6c-4.7 4.7-12.3 4.7-17 0L256 295.6l-62.2 62.2c-4.7 4.7-12.3 4.7-17 0l-22.6-22.6c-4.7-4.7-4.7-12.3 0-17l62.2-62.2-62.2-62.2c-4.7-4.7-4.7-12.3 0-17l22.6-22.6c4.7-4.7 12.3-4.7 17 0l62.2 62.2 62.2-62.2c4.7-4.7 12.3-4.7 17 0l22.6 22.6c4.7 4.7 4.7 12.3 0 17z"></path></svg>
|
After Width: | Height: | Size: 705 B |
1
resources/www/common/images/icons/to_be_validated.svg
Normal file
1
resources/www/common/images/icons/to_be_validated.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="check-circle" class="svg-inline--fa fa-check-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#aaa" d="M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z"></path></svg>
|
After Width: | Height: | Size: 738 B |
@@ -50,7 +50,9 @@ $mainMenuLinkBackgroundHoverColor: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[class*=" icon-"].fa, [class^=icon-].fa, .fa {
|
||||
font-family: Fontawesome!important;
|
||||
}
|
||||
[class^="icon-"], [class*=" icon-"].icomoon {
|
||||
display: inline-block;
|
||||
width: inherit;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
$iconsPath: '../../../assets/common/images/icons/';
|
||||
|
||||
ul.image_set{
|
||||
padding:0;
|
||||
margin:0;
|
||||
@@ -6,26 +7,57 @@ ul.image_set{
|
||||
width:100%;
|
||||
border:none;
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
li.image_box a img{
|
||||
position:relative;
|
||||
vertical-align:middle;
|
||||
border:none;
|
||||
width: auto!important;
|
||||
height: 100% !important;
|
||||
top: 0 !important;
|
||||
object-fit: contain;
|
||||
}
|
||||
li.image_box a{
|
||||
padding:0;
|
||||
text-shadow:0;
|
||||
margin:0;
|
||||
width: 100%;
|
||||
}
|
||||
li.image_box{
|
||||
width:80px;
|
||||
height:80px;
|
||||
width: 18%;
|
||||
position: relative;
|
||||
float:left;
|
||||
margin:0px 15px 15px 0px;
|
||||
padding:0px;
|
||||
margin: 0 2.5% 15px 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
background: #ededed;
|
||||
&:nth-child(5n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
.thumb_wrapper {
|
||||
background: #ededed;
|
||||
width: 100%!important;
|
||||
height: 160px!important;
|
||||
@media screen and (max-width: 767px) {
|
||||
height: 130px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 767px) {
|
||||
li.image_box{
|
||||
width: 32%;
|
||||
margin: 0 2% 15px 0;
|
||||
&:nth-child(5n) {
|
||||
margin-right: 2% ;
|
||||
}
|
||||
&:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a.no.active_choice{
|
||||
background-color:red;
|
||||
color: #fff;
|
||||
@@ -45,10 +77,12 @@ a.active_choice{
|
||||
}
|
||||
|
||||
.valid_choice.agree{
|
||||
background-image: url('#{$iconsPath}ok.png');
|
||||
background: #7ed321;
|
||||
border-top-left-radius: 100px;
|
||||
}
|
||||
.valid_choice.disagree{
|
||||
background-image: url('#{$iconsPath}delete.png');
|
||||
background: #d0021b;
|
||||
border-top-left-radius: 100px;
|
||||
}
|
||||
|
||||
.thumb_wrapper {
|
||||
@@ -70,3 +104,7 @@ a.active_choice{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.ui-footer .ui-title, .ui-header .ui-title {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
@@ -1,5 +1,28 @@
|
||||
@import './jquery-mobile/jquery-validator';
|
||||
|
||||
@font-face {
|
||||
font-family: 'icomoon';
|
||||
src: url("../../common/fonts/PhraseanetIcomoon/fonts/icomoon.eot?xt8hfo");
|
||||
src: url("../../common/fonts/PhraseanetIcomoon/fonts/icomoon.eot?xt8hfo#iefix") format("embedded-opentype"), url("../../common/fonts/PhraseanetIcomoon/fonts/icomoon.ttf?xt8hfo") format("truetype"), url("../../common/fonts/PhraseanetIcomoon/fonts/icomoon.woff?xt8hfo") format("woff"), url("../../common/fonts/PhraseanetIcomoon/fonts/icomoon.svg?xt8hfo#icomoon") format("svg");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
[class^="icon-"], [class*=" icon-"] {
|
||||
/* use !important to prevent issues with browser extensions that change fonts */
|
||||
font-family: 'icomoon' !important;
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.nav_button {
|
||||
width: 90%;
|
||||
margin: 0px auto;
|
||||
@@ -25,3 +48,668 @@
|
||||
#right-btn {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.report-modal, .ui-dialog .ui-dialog-content {
|
||||
background: linear-gradient(#3c3c3c, #111);
|
||||
}
|
||||
|
||||
.ui-bar-c, .ui-body-c, .ui-btn-down-c, .ui-btn-hover-c, .ui-btn-up-c, .ui-overlay-c {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
@import '../../_shared/styles/variables';
|
||||
$lightboxPath: '../images/';
|
||||
$imagesPath: '/assets/vendors/jquery-ui/images/dark-hive/';
|
||||
|
||||
$mainMenuBackgroundColor: #c7c7c7; //BFBFBF;
|
||||
$mainMenuBottomBorder: 1px solid #c7c7c7;
|
||||
$mainMenuLinkColor: #212121;
|
||||
$mainMenuLinkHoverColor: #000000;
|
||||
$mainMenuLinkActiveColor: #BFBFBF;
|
||||
$mainMenuLinkBackgroundHoverColor: transparent;
|
||||
|
||||
body {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.title15 {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.record_display_box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
table {
|
||||
vertical-align: middle;
|
||||
table-layout: fixed;
|
||||
}
|
||||
.title {
|
||||
margin: 0 10px;
|
||||
}
|
||||
.record {
|
||||
position: relative;
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
}
|
||||
.header {
|
||||
color: #BFBFBF;
|
||||
height: 30px;
|
||||
bottom: auto;
|
||||
overflow: hidden;
|
||||
.title {
|
||||
overflow: hidden;
|
||||
line-height: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
.lightbox_container {
|
||||
top: 30px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.display_id {
|
||||
top: 5px;
|
||||
margin: 0 0 0 5px;
|
||||
background: #bebebe;
|
||||
}
|
||||
}
|
||||
|
||||
#sc_wrapper {
|
||||
left: 20px;
|
||||
right: 20px;
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
#sc_container {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.basket_element_wrapper {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.basket_element {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 114px;
|
||||
height: 130px;
|
||||
border: 1px solid #212121;
|
||||
text-align: left;
|
||||
padding: 5px 8px;
|
||||
&.selected {
|
||||
background-color: #212121;
|
||||
}
|
||||
.display_id {
|
||||
top: 4px;
|
||||
left: 8px;
|
||||
}
|
||||
.agreement {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 8px;
|
||||
z-index: 99;
|
||||
}
|
||||
.image {
|
||||
position: relative;
|
||||
z-index: 90;
|
||||
}
|
||||
.previewTips {
|
||||
background-image: url('#{$iconsPath}zoom.gif');
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
cursor: help;
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 8px;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
z-index: 99;
|
||||
}
|
||||
}
|
||||
|
||||
#report .display_id {
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: 0;
|
||||
background-color: rgba(216, 216, 216, 0.7);
|
||||
font-weight: 700;
|
||||
z-index: 99;
|
||||
color: #333333;
|
||||
position: absolute;
|
||||
width: 22px;
|
||||
padding: 2px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#report .CHIM.diapo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.display_id {
|
||||
background-color: #FFFFFF;
|
||||
padding: 3px 6px;
|
||||
font-weight: bold;
|
||||
z-index: 99;
|
||||
color: #212121;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.not_decided {
|
||||
opacity: 0.30;
|
||||
filter: alpha(opacity=30);
|
||||
}
|
||||
|
||||
#sc_wrapper .not_decided {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#right_scroller {
|
||||
width: 30px;
|
||||
right: -10px;
|
||||
left: auto;
|
||||
background-image: url('#{$lightboxPath}right_arrow.png');
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#left_scroller {
|
||||
width: 30px;
|
||||
left: -10px;
|
||||
right: auto;
|
||||
background-image: url('#{$lightboxPath}left_arrow.png');
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#basket_infos {
|
||||
overflow: hidden;
|
||||
background-color: #1F1E1B;
|
||||
color: #BFBFBF;
|
||||
}
|
||||
|
||||
#basket_options {
|
||||
height: 35px;
|
||||
top: auto;
|
||||
background-color: #1F1E1B;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#basket_options .confirm_report {
|
||||
margin: 5px auto;
|
||||
}
|
||||
|
||||
#basket_infos .user_infos {
|
||||
height: 120px;
|
||||
top: auto;
|
||||
}
|
||||
|
||||
#basket_infos {
|
||||
table {
|
||||
width: 100%;
|
||||
margin: 5px 0;
|
||||
.title {
|
||||
width: 100%;
|
||||
}
|
||||
.report_wrapper {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#right_column {
|
||||
left: auto;
|
||||
right: 0;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
#right_column_validation_toggle {
|
||||
bottom: 45px;
|
||||
background-color: #1F1E1B;
|
||||
height: 30px;
|
||||
top: auto;
|
||||
text-align: center;
|
||||
display: none;
|
||||
line-height: 25px;
|
||||
color: #BFBFBF;
|
||||
}
|
||||
|
||||
#right_column .right_column_title {
|
||||
height: 30px;
|
||||
bottom: auto;
|
||||
}
|
||||
|
||||
#right_column .right_column_title img.expanded {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#right_column .right_column_title img.collapsed {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#right_column .right_column_title.expanded img.expanded {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#right_column .right_column_title.expanded img.collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#right_column .right_column_wrapper {
|
||||
top: 30px;
|
||||
bottom: 45px;
|
||||
}
|
||||
|
||||
#right_column .right_column_wrapper.caption {
|
||||
bottom: 85px;
|
||||
}
|
||||
|
||||
#record_infos {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#record_compare {
|
||||
visibility: hidden;
|
||||
top: auto;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
#record_compare .header, #record_compare .lightbox_container {
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
#record_wrapper.comparison #record_main .header, #record_wrapper.comparison #record_main .lightbox_container {
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
.agreement_selector {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.big_box.agree {
|
||||
border: 2px solid #35AC00;
|
||||
background-color: #35AC00;
|
||||
}
|
||||
|
||||
.big_box.disagree {
|
||||
border: 2px solid #DE1200;
|
||||
background-color: #DE1200;
|
||||
}
|
||||
|
||||
.big_box, .big_box.not_decided {
|
||||
width: 95px;
|
||||
margin: 0 auto;
|
||||
padding: 6px 10px;
|
||||
height: 30px;
|
||||
color: #1F1E1B;
|
||||
background-color: #353430;
|
||||
border: 2px solid #353430;
|
||||
text-align: center;
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
|
||||
.big_box span {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
li.userchoice {
|
||||
margin: 5px 0 0px 20px;
|
||||
}
|
||||
|
||||
.userchoice.disagree {
|
||||
color: #DE1200;
|
||||
}
|
||||
|
||||
.userchoice.agree {
|
||||
color: #35AC00;
|
||||
}
|
||||
|
||||
.basket_report_user {
|
||||
padding: 7px 10px;
|
||||
}
|
||||
|
||||
.basket_report_user_wrapper {
|
||||
margin: 0;
|
||||
border-bottom: 1px solid #b2b2b2;
|
||||
border-radius: 0;
|
||||
display: inline-block;
|
||||
padding: 10px 15px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background: #e5e5e5;
|
||||
text-shadow: none;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text {
|
||||
padding: 0.2em 1em 0.2em 2.1em;
|
||||
}
|
||||
|
||||
/*******
|
||||
*
|
||||
* Index
|
||||
*
|
||||
* ******/
|
||||
#main_index {
|
||||
position: relative;
|
||||
width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#main_wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#main_wrapper h1 {
|
||||
font-weight: bold;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
table th {
|
||||
text-align: right;
|
||||
vertical-align: bottom;
|
||||
height: 60px;
|
||||
border-bottom: 1px solid #8F8F8F;
|
||||
}
|
||||
|
||||
table th.title {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table th h1 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
table th i {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.ui-state-default.note_closer, .ui-state-default.note_saver {
|
||||
background-color: #353430;
|
||||
padding: 5px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.ui-state-default.note_saver {
|
||||
background-color: #1F1E1B;
|
||||
}
|
||||
|
||||
.record_display_box form .buttons {
|
||||
margin: 5px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.record_display_box form {
|
||||
margin: 15px 0;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.record_display_box form textarea {
|
||||
width: 100%;
|
||||
height: 75px;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.basket_downloader {
|
||||
background-color: #1F1E1B;
|
||||
margin: 0 10px;
|
||||
padding: 2px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #212121;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.report {
|
||||
margin: 0 10px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Overrides JqueryUI
|
||||
*
|
||||
*/
|
||||
.ui-button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ui-button-text-only .ui-button-text {
|
||||
padding: 0.15em;
|
||||
}
|
||||
|
||||
.ui-dialog {
|
||||
.ui-dialog-titlebar {
|
||||
padding: 1em 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.videoTips {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#basket_infos {
|
||||
margin-bottom: 20px;
|
||||
.mobile_aggreement_box {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-button-icon.ui-icon.ui-icon-closethick {
|
||||
background-position: -73px 0px;
|
||||
background-color: rgba(0, 0, 0, .9);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
button.confirm_report {
|
||||
background: #38c !important;
|
||||
color: #fff !important;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
padding: 6px;
|
||||
display: inline-block;
|
||||
border: 1px solid #38c;
|
||||
text-shadow: 0 1px 0 #111;
|
||||
border-radius: 16px;
|
||||
font-family: Roboto, sans-serif;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2) !important;
|
||||
}
|
||||
|
||||
.report_wrapper {
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.report_btn {
|
||||
position: absolute;
|
||||
top: -41px;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
background: #8bc34a;
|
||||
border: 1px solid #8bc34a;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 13px;
|
||||
min-width: 110px;
|
||||
border-radius: 4px;
|
||||
color: #fff !important;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
transition: all 0.3s;
|
||||
&:hover, &:focus {
|
||||
background: darken(#8bc34a, 0.2);
|
||||
border-color: darken(#8bc34a, 0.3);
|
||||
}
|
||||
&.report_list {
|
||||
background: #f44336;
|
||||
border-color: #f44336;
|
||||
&:hover, &:focus {
|
||||
background: darken(#f44336, 0.2);
|
||||
border-color: darken(#f44336, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.report_list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.report_summary_backup, .report_list_backup {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chim-wrapper-block {
|
||||
margin-bottom: 15px;
|
||||
.chim-block {
|
||||
margin: 0;
|
||||
}
|
||||
.chim-inner {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
min-width: 296px;
|
||||
}
|
||||
.chim-left {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
background: #ededed;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
.diapo {
|
||||
display: inline-block;
|
||||
div {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chim-right {
|
||||
width: 100%;
|
||||
.validate-icon {
|
||||
float: left;
|
||||
height: 25px;
|
||||
vertical-align: middle;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
padding-top: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.thumb_wrapper img.record_image {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/*header lightbox*/
|
||||
.ui-footer .ui-title, .ui-header .ui-title {
|
||||
min-height: 26px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.ui-listview.lightbox-list-view {
|
||||
& > .ui-li-static {
|
||||
padding: .7em 1em;
|
||||
text-overflow: inherit;
|
||||
white-space: inherit;
|
||||
}
|
||||
& > li {
|
||||
border-color: #b2b2b2;
|
||||
background: none;
|
||||
p {
|
||||
text-overflow: inherit;
|
||||
white-space: inherit;
|
||||
line-height: 15px;
|
||||
font-size: 13px;
|
||||
color: #141414;
|
||||
}
|
||||
}
|
||||
h3 {
|
||||
font-family: Roboto, sans-serif;;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: 0.94;
|
||||
letter-spacing: normal;
|
||||
color: #141414;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.ui-footer.ui-bar-inherit {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.center-image {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/*validate page*/
|
||||
.validate-icon {
|
||||
float: left;
|
||||
position: absolute;
|
||||
.icomoon {
|
||||
color: #fff;
|
||||
font-size: 17px;
|
||||
padding: 3px;
|
||||
border-radius: 50px;
|
||||
display: inline-block;
|
||||
}
|
||||
.icon-disagree {
|
||||
background: #cd2f2f;
|
||||
}
|
||||
.icon-agree {
|
||||
background: #8bc34a;
|
||||
}
|
||||
|
||||
}
|
||||
.validate-info {
|
||||
float: left;
|
||||
padding-left: 36px;
|
||||
}
|
||||
|
||||
|
@@ -109,3 +109,48 @@ dd {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
/*Help menu*/
|
||||
.contextMenu.helpcontextmenu {
|
||||
display: none;
|
||||
&.shown {
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 101;
|
||||
}
|
||||
}
|
||||
.help-trigger {
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
padding: 0 4px;
|
||||
border:none;
|
||||
margin-left: -12px;
|
||||
margin-right: 94px;
|
||||
.fa-caret-down:before {
|
||||
content: "\25BC";
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
.context-menu-theme-vista {
|
||||
background-image: none;
|
||||
background-color: #414141;
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
|
||||
.context-menu-item {
|
||||
transition: 500ms;
|
||||
&:hover {
|
||||
background-image: none;
|
||||
background-color: #75abff;
|
||||
border: none;
|
||||
}
|
||||
.context-menu-item-inner {
|
||||
padding: 4px 12px;
|
||||
margin-left: 0;
|
||||
font-family: Helvetica;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -50,7 +50,6 @@
|
||||
class="ui-btn-right jqm-home">{{ 'Home' | trans }}</a>
|
||||
</div>
|
||||
<div id="content" data-role="content">
|
||||
{{ thumbnail.format100percent(record.get_preview()) }}
|
||||
<div class="nav_button">
|
||||
{% if prevId != NULL %}
|
||||
<a data-ajax="false" id="left-btn"
|
||||
@@ -64,13 +63,14 @@
|
||||
{% endif %}
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
<div class="center-image">{{ thumbnail.format100percent(record.get_preview()) }}</div>
|
||||
{% if basket_element.getBasket().getValidation() %}
|
||||
{% if basket_element.getBasket().getValidation().getParticipant(app.getAuthenticatedUser()).getCanAgree() %}
|
||||
<fieldset data-role="controlgroup" data-type="horizontal" style="text-align:center;">
|
||||
<input {% if basket_element.getUserValidationDatas(app.getAuthenticatedUser()).getAgreement() == true%}checked="checked"{% endif %} type="radio" name="radio-view" id="radio-view-yes_{{basket_element.getId()}}" value="yes" />
|
||||
<input onclick="window.location.reload();" {% if basket_element.getUserValidationDatas(app.getAuthenticatedUser()).getAgreement() == true%}checked="checked"{% endif %} type="radio" name="radio-view" id="radio-view-yes_{{basket_element.getId()}}" value="yes" />
|
||||
<label class="agreement_radio" style="width:110px;text-align:center;"
|
||||
for="radio-view-yes_{{ basket_element.getId() }}">{{ 'validation:: OUI' | trans }}</label>
|
||||
<input {% if basket_element.getUserValidationDatas(app.getAuthenticatedUser()).getAgreement() == false and basket_element.getUserValidationDatas(app.getAuthenticatedUser()).getAgreement() is not null %}checked="checked"{% endif %} type="radio" name="radio-view" id="radio-view-no_{{basket_element.getId()}}" value="no" />
|
||||
<input onclick="window.location.reload();" {% if basket_element.getUserValidationDatas(app.getAuthenticatedUser()).getAgreement() == false and basket_element.getUserValidationDatas(app.getAuthenticatedUser()).getAgreement() is not null %}checked="checked"{% endif %} type="radio" name="radio-view" id="radio-view-no_{{basket_element.getId()}}" value="no" />
|
||||
<label class="agreement_radio" style="width:110px;text-align:center;"
|
||||
for="radio-view-no_{{ basket_element.getId() }}">{{ 'validation:: NON' | trans }}</label>
|
||||
</fieldset>
|
||||
@@ -81,7 +81,7 @@
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<ul data-role="listview" id="notes_{{basket_element.getId()}}">
|
||||
<ul data-role="listview" class="lightbox-list-view" id="notes_{{basket_element.getId()}}">
|
||||
{% include 'lightbox/sc_note.html.twig' %}
|
||||
</ul>
|
||||
</div>
|
||||
|
@@ -1,17 +1,21 @@
|
||||
{% for validationDatas in basket_element.getValidationDatas() %}
|
||||
{% set is_mine = validationDatas.getParticipant().getUser().getId() == app.getAuthenticatedUser().getId() %}
|
||||
{% if validationDatas.getNote() != '' or (validationDatas.getAgreement() is not null and is_mine) %}
|
||||
<li>
|
||||
<h3 style="text-align:left;">
|
||||
{% if is_mine == false and validationDatas.getAgreement() is not null %}
|
||||
<img style="vertical-align:middle;"
|
||||
src="/assets/lightbox/images/{% if validationDatas.getAgreement() == true %}agree.png{% else %}disagree.png{% endif %}" />
|
||||
<div class="validate-icon">
|
||||
{% if basket_element.getBasket().getValidation().getParticipant(app.getAuthenticatedUser()).getCanSeeOthers() or validationDatas.getParticipant().getUser() == app.getAuthenticatedUser() %}
|
||||
{% if validationDatas.getAgreement() == true %}<span class="icomoon icon-agree"></span>{% endif %}
|
||||
{% if validationDatas.getAgreement() == false and validationDatas.getAgreement() is not null %}<span class="icomoon icon-disagree"> {{ validationDatas.getAgreement() }}</span>{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="validate-info">
|
||||
<h3>
|
||||
{{ validationDatas.getParticipant().getUser().getDisplayName() }}
|
||||
</h3>
|
||||
{% if basket_element.getBasket().getValidation().getParticipant(app.getAuthenticatedUser()).getCanSeeOthers() or validationDatas.getParticipant().getUser() == app.getAuthenticatedUser() %}
|
||||
{% if validationDatas.getNote() != '' %}
|
||||
<p style="text-align:left;">{{ 'validation:: note' | trans }} : {{ validationDatas.getNote()|nl2br }} </p>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
@@ -38,22 +38,56 @@
|
||||
{% set basket_length = basket.getElements().count() %}
|
||||
{% trans with {'%basket_length%' : basket_length} %}%basket_length% documents{% endtrans %}
|
||||
</p>
|
||||
{% if basket.getValidation() %}
|
||||
<div class="report_wrapper">
|
||||
<a id="report_summary" class="report_btn report_summary" href="#" onclick="$.ajax({
|
||||
type: 'GET',
|
||||
url: '/lightbox/ajax/LOAD_REPORT/' + $('#navigation').val() + '/',
|
||||
dataType: 'html',
|
||||
success: function (data) {
|
||||
$('#report_list_backup').empty().append($('#report').html());
|
||||
$('#report').empty().append(data);
|
||||
$('#report .record_image').css('height','auto');
|
||||
return;
|
||||
}
|
||||
});
|
||||
$(this).hide();
|
||||
$('#report_list').show();">
|
||||
{{ 'lightbox::recaptitulatif' | trans }}
|
||||
</a>
|
||||
<a id="report_list" class="report_btn report_list" href="#" onclick=" $(this).hide();
|
||||
$('#report_summary').show();
|
||||
$('#report').empty().append($('#report_list_backup').html());">
|
||||
{{ 'lightbox::list' | trans }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="report_list_backup" id="report_list_backup"> </div>
|
||||
<div class="report_summary_backup " id="report_summary_backup"> </div>
|
||||
{% endif %}
|
||||
<input type="hidden" id="navigation" value="{{ basket.getId() }}">
|
||||
<div id="report" class="summary_block">
|
||||
<ul class="image_set">
|
||||
{% for basket_element in basket.getElements() %}
|
||||
|
||||
<li class="image_box" id="sselcontid_{{basket_element.getId()}}">
|
||||
<div class="display_id">
|
||||
{{basket_element.getOrd()}}
|
||||
</div>
|
||||
{% if basket_element.getBasket().getValidation() and basket_element.getBasket().getValidation().getParticipant(app.getAuthenticatedUser()).getCanAgree() %}
|
||||
<div class="valid_choice valid_choice_{{basket_element.getId()}} {% if basket_element.getUserValidationDatas(app.getAuthenticatedUser()).getAgreement() == true %}agree{% elseif basket_element.getUserValidationDatas(app.getAuthenticatedUser()).getAgreement() == false and basket_element.getUserValidationDatas(app.getAuthenticatedUser()).getAgreement() is not null %}disagree{% endif %}">
|
||||
</div>
|
||||
{% endif %}
|
||||
<a href="{{ path('lightbox_ajax_load_basketelement', { 'sselcont_id' : basket_element.getId() }) }}">
|
||||
{{thumbnail.format(basket_element.getRecord(app).get_thumbnail(), 80, 80, '', true, false)}}
|
||||
{{thumbnail.format(basket_element.getRecord(app).get_thumbnail(), 300, 300, '', true, false)}}
|
||||
</a>
|
||||
<input type="hidden" class="display_id" name="display_id" value="{{basket_element.getOrd()}}" />
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div data-role="footer">
|
||||
</div>
|
||||
|
||||
<div class="btn-container">
|
||||
{% if basket.getValidation() and basket.getValidation().getParticipant(app.getAuthenticatedUser()).getCanAgree() %}
|
||||
<button class="confirm_report" style="width:100%;" title="{{ 'validation::envoyer mon rapport' | trans }}">
|
||||
{{ 'validation::envoyer mon rapport' | trans }}
|
||||
@@ -62,6 +96,8 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
@@ -193,7 +193,15 @@
|
||||
<td>
|
||||
<label for="gui_editable" class="checkbox">
|
||||
<input id="gui_editable" type="checkbox" <%= field.gui_editable ? "checked='checked'" : "" %> />
|
||||
{% trans %}gui_editable{% endtrans %}
|
||||
{% trans %}Gui-editable{% endtrans %}
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="gui_visible" class="checkbox">
|
||||
<input id="gui_visible" type="checkbox" <%= field.gui_visible ? "checked='checked'" : "" %> />
|
||||
{% trans %}Gui-visible{% endtrans %}
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -256,7 +264,7 @@
|
||||
<td><input id="tbranch" type="text" value="<%= field.tbranch %>"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="generate_cterms" class="checkbox">{% trans %}generate_cterms{% endtrans %}</label></td>
|
||||
<td><label for="generate_cterms" class="checkbox">{% trans %}Generate-cterms{% endtrans %}</label></td>
|
||||
<td><input id="generate_cterms" type="checkbox" <%= field.generate_cterms ? "checked='checked'" : "" %> /></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@@ -1,8 +1,10 @@
|
||||
{% macro caption(record, can_see_business, display_exif, limitedWidth = false) %}
|
||||
<dl class="{% if limitedWidth %}{% else %}dl-horizontal{% endif %}">
|
||||
{% for name, value in record.getCaption(caption_field_order(record, can_see_business)) %}
|
||||
{% if caption_field_gui_visible(record, name) == 1 %}
|
||||
<dt>{{ caption_field_label(record, name) }}</dt>
|
||||
<dd>{{ caption_field(record, name, value)|e|highlight|linkify|parseColor }}</dd>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</dl>
|
||||
{% if display_exif|default(true) and app.getAuthenticator().user is not none and user_setting('technical_display') == 'group' %}
|
||||
|
@@ -302,8 +302,18 @@
|
||||
$(document).ready(function () {
|
||||
$('body').on('click', '#help-trigger', function (event) {
|
||||
$('#mainMenu .helpcontextmenu').toggleClass('shown');
|
||||
console.log('mety');
|
||||
|
||||
});
|
||||
|
||||
$(document).on('click', function (e) {
|
||||
if($('#mainMenu .helpcontextmenu').hasClass('shown')) {
|
||||
var $this = $(e.target);
|
||||
if ($this.closest('#mainMenu .helpcontextmenu.shown, .help-trigger').length == 0 && $this[0].id != "toggle") {
|
||||
$('#mainMenu .helpcontextmenu').removeClass('shown');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// var key = 'help';
|
||||
var configurationSettingLinks = {{ configuration|json_encode|raw }};
|
||||
//seperate array based on location of link
|
||||
|
@@ -4,48 +4,50 @@
|
||||
<div style="margin:0 7px;overflow:hidden;">
|
||||
{% for basket_element in basket.getElements() %}
|
||||
{% set record = basket_element.getRecord(app) %}
|
||||
<div class="chim-wrapper wrapCHIM_{{basket_element.getId()}} valid">
|
||||
<div style="margin:20px;">
|
||||
<table style="width: 100%; min-width: 330px;">
|
||||
<tr valign="top">
|
||||
<td style="width:165px;">
|
||||
<div id="CHIM_{{basket_element.getId()}}_{{record.get_serialize_key()}}"
|
||||
class="CHIM diapo">
|
||||
<div class="chim-wrapper-block chim-wrapper wrapCHIM_{{basket_element.getId()}} valid">
|
||||
<div class="chim-block">
|
||||
<div class="chim-inner">
|
||||
<div class="chim-left">
|
||||
<div id="CHIM_{{basket_element.getId()}}_{{record.get_serialize_key()}}" class="CHIM diapo">
|
||||
<div class="display_id">
|
||||
{{basket_element.getOrd()}}
|
||||
</div>
|
||||
{{thumbnail.format(record.get_thumbnail(),165, 125, '', true, false)}}
|
||||
</div>
|
||||
</td>
|
||||
<td style="width:10px;">
|
||||
</td>
|
||||
<td>
|
||||
</div>
|
||||
<div class="chim-right">
|
||||
{% for validationDatas in basket_element.getValidationDatas()%}
|
||||
<div class="basket_report_user_wrapper ui-corner-all">
|
||||
<div class="basket_report_user">
|
||||
{% if validationDatas.getAgreement() == true %}
|
||||
{% set imguser = '<img src="/assets/lightbox/images/agree.png" />' %}
|
||||
{% set imguser = '<span class="icomoon icon-agree"></span>' %}
|
||||
{% set styleuser = '' %}
|
||||
{% elseif validationDatas.getAgreement() is null %}
|
||||
{% set imguser = '' %}
|
||||
{% set imguser = ' ' %}
|
||||
{% set styleuser = 'margin-left:18px;' %}
|
||||
{% else %}
|
||||
{% set imguser = '<img src="/assets/lightbox/images/disagree.png" />' %}
|
||||
{% set imguser = '<span class="icomoon icon-disagree"></span>' %}
|
||||
{% set styleuser = '' %}
|
||||
{% endif %}
|
||||
<b style="{{styleuser}}">{{imguser|raw}} {{validationDatas.getParticipant().getUser().getDisplayName()}}</b>
|
||||
|
||||
<div class="validate-icon">
|
||||
{% if basket_element.getBasket().getValidation().getParticipant(app.getAuthenticatedUser()).getCanSeeOthers() or validationDatas.getParticipant().getUser() == app.getAuthenticatedUser() %}
|
||||
{{imguser|raw}}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="validate-info">
|
||||
<h3> {{validationDatas.getParticipant().getUser().getDisplayName()}}</h3>
|
||||
{% if validationDatas.getNote() != '' %}
|
||||
: {{validationDatas.getNote()|nl2br}}
|
||||
{% if basket_element.getBasket().getValidation().getParticipant(app.getAuthenticatedUser()).getCanSeeOthers() or validationDatas.getParticipant().getUser() == app.getAuthenticatedUser() %}
|
||||
<p> {{validationDatas.getNote()|nl2br}}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div><hr/></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
@@ -90,7 +90,7 @@
|
||||
{% endif %}
|
||||
{% for field in fields %}
|
||||
{% set i = field.get_id() %}
|
||||
{% if field.is_readonly() is empty %}
|
||||
{% if field.is_readonly() is empty and field.get_gui_editable()== 1 %}
|
||||
<div class="edit_field edit-field-action" id="EditFieldBox_{{i}}"
|
||||
data-id="{{i}}"
|
||||
data-name="{{field.get_name()}}">
|
||||
|
@@ -1,4 +1,5 @@
|
||||
{% include 'prod/results/record.html.twig' with {
|
||||
'record': record,
|
||||
'settings': settings
|
||||
'settings': settings,
|
||||
'plugins': plugins
|
||||
} %}
|
||||
|
@@ -7,7 +7,8 @@
|
||||
<td valign="top" style='width:{{ settings.images_size + 50 }}px'>
|
||||
{% include 'prod/results/record.html.twig' with {
|
||||
'record': record,
|
||||
'settings': settings
|
||||
'settings': settings,
|
||||
'plugins': plugins
|
||||
} %}
|
||||
</td>
|
||||
<td valign="middle">
|
||||
|
@@ -155,6 +155,29 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{# add plugins entries #}
|
||||
{% for plugin in plugins.actionbar|default([]) %}
|
||||
{% set menu = plugin.ActionBar['_context_']|default([]) %}
|
||||
{% for k, action in menu %}
|
||||
{% if plugin.isContextMenuOptionAvailable(k, record) %}
|
||||
<div title="" class="context-menu-item"
|
||||
onclick="{{ plugin.getContextMenuJS(k) }}('{{ k }}', '{{record.baseId}}', '{{record.recordId}}', '{{ record.id }}');">
|
||||
<div class="context-menu-item-inner">
|
||||
{% set icon = (action.icon ?? false) ? plugin_asset(plugin.PluginName, action.icon) : null %}
|
||||
{% set label = (action.label ?? false) ? (action.label|trans({}, plugin.PluginLocale)) : 'undefined label' %}
|
||||
<a title="{{ label }}" href="#">
|
||||
{% if icon %}
|
||||
<img style="cursor:pointer;" src="{{ icon }}" alt="{{ label }}">
|
||||
{% endif %}
|
||||
<span>{{ label }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@@ -31,7 +31,8 @@
|
||||
'doctype_display': doctype_display,
|
||||
'handle_dblclick' : true,
|
||||
'show_context_menu': true
|
||||
}
|
||||
},
|
||||
'plugins': plugins
|
||||
} %}
|
||||
{% endblock %}
|
||||
{% endfor %}
|
||||
|
@@ -44,270 +44,159 @@
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span class="dropdownButton">
|
||||
<div class="btn-group">
|
||||
<button id="TOOL_disktt" class="default_action TOOL_disktt_btn results_window btn btn-inverse" data-selection-source="search-result">
|
||||
<img src="/assets/common/images/icons/disktt_history.png" height="16" width="16" class="btn-image"/> {{ 'action : exporter' | trans }}
|
||||
</button>
|
||||
<button class="trigger btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="TOOL_print_btn results_window" data-selection-source="search-result">
|
||||
<img src="/assets/common/images/icons/print_history.png" height="16" width="16" class="btn-image"/>
|
||||
{{ 'action : print' | trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</span>
|
||||
{% set menus = {
|
||||
'export': [
|
||||
{
|
||||
'class':'TOOL_disktt_btn',
|
||||
'icon':'/assets/common/images/icons/disktt_history.png',
|
||||
'label':'action : exporter' | trans },
|
||||
{
|
||||
'class':'TOOL_print_btn',
|
||||
'icon':'/assets/common/images/icons/print_history.png',
|
||||
'label':'action : print' | trans }
|
||||
],
|
||||
'edit': [],
|
||||
'push': [],
|
||||
'tools': [],
|
||||
'delete': []
|
||||
} %}
|
||||
|
||||
{% set actions = {} %}
|
||||
{# menu "edit" #}
|
||||
{% set m = [] %}
|
||||
{% if acl.has_right(constant('\\ACL::CANMODIFRECORD')) %}
|
||||
{% set label %}
|
||||
{{ 'action : editer' | trans }}
|
||||
{% endset %}
|
||||
{% set actions = actions|merge( { 'edit' : {'icon': "/assets/common/images/icons/ppen_history.png", 'class':'TOOL_ppen_btn', 'label' : label} }) %}
|
||||
{% set label %}
|
||||
{{ 'prod::toolbar : video editor' | trans }}
|
||||
{% endset %}
|
||||
{% set actions = actions|merge( { 'video' : {'icon': "/assets/common/images/icons/icon-video-editor.png", 'class':'TOOL_videoeditor_btn', 'label' : label} }) %}
|
||||
{% set m = m|merge([
|
||||
{
|
||||
'class':'TOOL_ppen_btn',
|
||||
'icon':'/assets/common/images/icons/ppen_history.png',
|
||||
'label':'action : editer' | trans },
|
||||
{
|
||||
'class':'TOOL_videoeditor_btn',
|
||||
'icon':'/assets/common/images/icons/icon-video-editor.png',
|
||||
'label':'prod::toolbar : video editor' | trans }
|
||||
]) %}
|
||||
{% endif %}
|
||||
{% if acl.has_right(constant('\\ACL::CHGSTATUS')) %}
|
||||
{% set label %}
|
||||
{{ 'action : status' | trans }}
|
||||
{% endset %}
|
||||
{% set actions = actions|merge( { 'status' : {'icon': "/assets/common/images/icons/chgstatus_history.png", 'class':'TOOL_chgstatus_btn', 'label' : label} }) %}
|
||||
{% if acl.has_right(constant('\\\ACL::CHGSTATUS')) %}
|
||||
{% set m = m|merge([
|
||||
{
|
||||
'class':'TOOL_chgstatus_btn',
|
||||
'icon':'/assets/common/images/icons/chgstatus_history.png',
|
||||
'label':'action : status' | trans }
|
||||
]) %}
|
||||
{% endif %}
|
||||
{% if acl.has_right(constant('\\ACL::CANDELETERECORD')) and acl.has_right(constant('\\ACL::CANADDRECORD')) %}
|
||||
{% set label %}
|
||||
{{ 'action : collection' | trans }}
|
||||
{% endset %}
|
||||
{% set actions = actions|merge( { 'move' : {'icon': "/assets/common/images/icons/chgcoll_history.png", 'class':'TOOL_chgcoll_btn', 'label' : label} }) %}
|
||||
{% set m = m|merge([
|
||||
{
|
||||
'class':'TOOL_chgcoll_btn',
|
||||
'icon':'/assets/common/images/icons/chgcoll_history.png',
|
||||
'label':'action : collection' | trans }
|
||||
]) %}
|
||||
{% endif %}
|
||||
{% set menus = menus|merge({'edit' : m}) %}
|
||||
|
||||
{% set n_actions = actions|length %}
|
||||
{% if n_actions > 1 %}
|
||||
<span class="dropdownButton">
|
||||
<div class="btn-group">
|
||||
{% for action in actions %}
|
||||
{% if loop.first %}
|
||||
<button class="default_action {{ action.class }} results_window btn btn-inverse" data-selection-source="search-result">
|
||||
<img src="{{ action.icon }}" height="16" width="16" class="btn-image"/> {{ action.label }}
|
||||
</button>
|
||||
{# menu "push" #}
|
||||
{% set m = [] %}
|
||||
{% if acl.has_right(constant('\\ACL::CANPUSH')) %}
|
||||
{% set m = m|merge([
|
||||
{
|
||||
'class':'TOOL_pushdoc_btn',
|
||||
'icon':'/assets/common/images/icons/push16.png',
|
||||
'label':'action : push' | trans },
|
||||
{
|
||||
'class':'TOOL_feedback_btn',
|
||||
'icon':'/assets/common/images/icons/feedback16.png',
|
||||
'label':'Feedback' | trans }
|
||||
]) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<button class="trigger btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span
|
||||
class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
{% for action in actions %}
|
||||
{% if not loop.first %}
|
||||
<li>
|
||||
<a class="{{ action.class }} results_window" data-selection-source="search-result">
|
||||
<img src="{{ action.icon }}" height="16" width="16" class="btn-image"/>
|
||||
{{ action.label }}
|
||||
</a>
|
||||
</li>
|
||||
{% if not loop.last %}
|
||||
<li class="divider"></li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</span>
|
||||
{% elseif n_actions == 1 %}
|
||||
<span class="classicButton">
|
||||
<div class="btn-group">
|
||||
{% for action in actions %}
|
||||
<button class="{{ action.class }} results_window btn btn-inverse" data-selection-source="search-result">
|
||||
<img src="{{ action.icon }}" height="16" width="16" class="btn-image"/> {{ action.label }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{% if acl.has_right(constant('\\ACL::CANPUSH')) and acl.has_right(constant('\\ACL::BAS_CHUPUB')) %}
|
||||
<span class="dropdownButton">
|
||||
<div class="btn-group">
|
||||
<button class="TOOL_pushdoc_btn default_action results_window btn btn-inverse" data-selection-source="search-result">
|
||||
<img src="/assets/common/images/icons/push16.png" height="16" width="16" class="btn-image"/> {{ 'action : push' | trans }}
|
||||
</button>
|
||||
<button class="trigger btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span
|
||||
class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="TOOL_feedback_btn results_window" data-selection-source="search-result">
|
||||
<img src="/assets/common/images/icons/feedback16.png" height="16" width="16" class="btn-image"/>
|
||||
{{ 'Feedback' | trans }}
|
||||
</a>
|
||||
</li>
|
||||
{#<li class="divider"></li>#}
|
||||
{#<li>#}
|
||||
{#<a class="TOOL_bridge_btn results_window" href="{{ path("prod_bridge_manager") }}" data-selection-source="search-result">#}
|
||||
{#<img src="/assets/common/images/icons/door.png" height="16" width="16" class="btn-image"/>#}
|
||||
{#{{ 'action : bridge' | trans }}#}
|
||||
{#</a>#}
|
||||
{#</li>#}
|
||||
<li class="divider"></li>
|
||||
<li>
|
||||
<a class="TOOL_publish_btn results_window" data-selection-source="search-result">
|
||||
<img src="/assets/common/images/icons/rss16.png" height="16" width="16" class="btn-image"/>
|
||||
{{ 'action : publier' | trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% if plugins.actionbar is not empty %}
|
||||
{% for plugin in plugins.actionbar %}
|
||||
<li class="divider"></li>
|
||||
{% for key, action in plugin.getActionBar().push|default([]) %}
|
||||
<li>
|
||||
<a class="results_window {{ action.classes|default('') }}" data-selection-source="search-result">
|
||||
{% if action.icon %}
|
||||
<img src="{{ plugin_asset(plugin.PluginName, action.icon) }}" height="16" width="16" class="btn-image"/>
|
||||
{% endif %}
|
||||
{{ action.label|trans({}, plugin.PluginLocale) }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</span>
|
||||
{% elseif acl.has_right(constant('\\ACL::CANPUSH')) %}
|
||||
<span class="dropdownButton">
|
||||
<div class="btn-group">
|
||||
<button class="TOOL_pushdoc_btn default_action results_window btn btn-inverse" data-selection-source="search-result">
|
||||
<img src="/assets/common/images/icons/push16.png" height="16" width="16" class="btn-image"/> {{ 'action : push' | trans }}
|
||||
</button>
|
||||
<button class="trigger btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span
|
||||
class="caret"></span></button>
|
||||
<ul class="submenu dropdown-menu">
|
||||
<li>
|
||||
<a class="TOOL_feedback_btn results_window" data-selection-source="search-result">
|
||||
<img src="/assets/common/images/icons/feedback16.png" height="16" width="16" class="btn-image"/>
|
||||
{{ 'Feedback' | trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% if plugins.actionbar is not empty %}
|
||||
{% for plugin in plugins.actionbar %}
|
||||
<li class="divider"></li>
|
||||
{% for key, action in plugin.getActionBar().push|default([]) %}
|
||||
<li>
|
||||
<a class="results_window {{ action.classes|default('') }}" data-selection-source="search-result">
|
||||
{% if action.icon %}
|
||||
<img src="{{ plugin_asset(plugin.PluginName, action.icon) }}" height="16" width="16" class="btn-image"/>
|
||||
{% endif %}
|
||||
{{ action.label|trans({}, plugin.PluginLocale) }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</span>
|
||||
{% elseif acl.has_right(constant('\\ACL::BAS_CHUPUB')) %}
|
||||
<span class="dropdownButton">
|
||||
<div class="btn-group">
|
||||
{#<button class="TOOL_pushdoc_btn default_action results_window btn btn-inverse" data-selection-source="search-result">#}
|
||||
{#<img src="/assets/common/images/icons/door.png" height="16" width="16" class="btn-image"/> {{ 'action : bridge' | trans }}#}
|
||||
{#</button>#}
|
||||
<button class="TOOL_publish_btn results_window btn btn-inverse">
|
||||
<img src="/assets/common/images/icons/rss16.png" height="16" width="16" class="btn-image"/>
|
||||
{{ 'action : publier' | trans }}
|
||||
</button>
|
||||
<button class="trigger btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span
|
||||
class="caret"></span></button>
|
||||
{% if plugins.actionbar is not empty %}
|
||||
<button class="trigger btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span
|
||||
class="caret"></span></button>
|
||||
<ul class="submenu dropdown-menu">
|
||||
{% for plugin in plugins.actionbar %}
|
||||
<li class="divider"></li>
|
||||
{% for key, action in plugin.getActionBar().push|default([]) %}
|
||||
<li>
|
||||
<a class="results_window {{ action.classes|default('') }}">
|
||||
{% if action.icon %}
|
||||
<img src="{{ plugin_asset(plugin.PluginName, action.icon) }}"
|
||||
height="16" width="16" class="btn-image"/>
|
||||
{% endif %}
|
||||
{{ action.label|trans({}, plugin.PluginLocale) }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
</span>
|
||||
{% elseif plugins.actionbar is not empty %}
|
||||
<span class="dropdownButton">
|
||||
<div class="btn-group">
|
||||
{% set firstButton = true %}
|
||||
{% for plugin in plugins.actionbar %}
|
||||
{% for key, action in plugin.getActionBar().push|default([]) %}
|
||||
{% if firstButton %}
|
||||
<button class="default_action results_window btn btn-inverse" data-selection-source="search-result">
|
||||
<a class="results_window {{ action.classes|default('') }}" data-selection-source="search-result">
|
||||
{% if action.icon %}
|
||||
<img src="{{ plugin_asset(plugin.PluginName, action.icon) }}" height="16" width="16"/>
|
||||
{% endif %}
|
||||
{{ action.label|trans({}, plugin.PluginLocale) }}
|
||||
</a>
|
||||
</button>
|
||||
{% if not (loop.last and loop.parent.loop.last) %}
|
||||
<button class="trigger btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
|
||||
<ul class="submenu dropdown-menu">
|
||||
{% endif %}
|
||||
{% if not loop.first %}<li class="divider"></li>{% endif %}
|
||||
{% if not firstButton %}
|
||||
<li>
|
||||
<a class="results_window {{ action.classes|default('') }}" data-selection-source="search-result">
|
||||
{% if action.icon %}
|
||||
<img src="{{ plugin_asset(plugin.PluginName, action.icon) }}" height="16" width="16" class="btn-image"/>
|
||||
{% endif %}
|
||||
{{ action.label|trans({}, plugin.PluginLocale) }}
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
{% set firstButton = false %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% if not firstButton %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
</span>
|
||||
{% if acl.has_right(constant('\\ACL::BAS_CHUPUB')) %}
|
||||
{% set m = m|merge([
|
||||
{
|
||||
'class':'TOOL_publish_btn',
|
||||
'icon':'/assets/common/images/icons/rss16.png',
|
||||
'label':'action : publier' | trans }
|
||||
]) %}
|
||||
{% endif %}
|
||||
{% set menus = menus|merge({'push' : m}) %}
|
||||
|
||||
{# menu "tools" #}
|
||||
{% if acl.has_right(constant('\\ACL::IMGTOOLS')) %}
|
||||
<span class="classicButton">
|
||||
<div class="btn-group">
|
||||
<button class="TOOL_imgtools_btn results_window btn btn-inverse" data-selection-source="search-result">
|
||||
<img src="/assets/common/images/icons/imgtools_history.png" height="16" width="16" class="btn-image"/> {{ 'action : outils' | trans }}
|
||||
</button>
|
||||
</div>
|
||||
</span>
|
||||
{% set menus = menus|merge({'tools' : [
|
||||
{
|
||||
'class':'TOOL_imgtools_btn',
|
||||
'icon':'/assets/common/images/icons/imgtools_history.png',
|
||||
'label':'action : outils' | trans }
|
||||
]}) %}
|
||||
{% endif %}
|
||||
|
||||
{# menu "delete" #}
|
||||
{% if acl.has_right(constant('\\ACL::CANDELETERECORD')) %}
|
||||
<span class="classicButton">
|
||||
{% set menus = menus|merge({'delete' : [
|
||||
{
|
||||
'class':'TOOL_trash_btn',
|
||||
'icon':'/assets/common/images/icons/delete.png',
|
||||
'label':'action : supprimer' | trans }
|
||||
]}) %}
|
||||
{% endif %}
|
||||
|
||||
{# add plugins entries #}
|
||||
{% if plugins.actionbar is not empty %}
|
||||
{% for plugin in plugins.actionbar %}
|
||||
{% for k, menu in plugin.getActionBar() %}
|
||||
{% if k != '_context_' %}
|
||||
{% set m = menus[k]|default([]) %}
|
||||
{% for action in menu %}
|
||||
{% set m = m|merge([{
|
||||
'class':action.classes|default(''),
|
||||
'icon':plugin_asset(plugin.PluginName, action.icon),
|
||||
'label':action.label|trans({}, plugin.PluginLocale) }])
|
||||
%}
|
||||
{% endfor %}
|
||||
{% set menus = menus|merge({(k) : m}) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{# print #}
|
||||
{% for menu_entries in menus %}
|
||||
{% if menu_entries|length > 0 %}
|
||||
<span class="dropdownButton">
|
||||
<div class="btn-group">
|
||||
<button class="TOOL_trash_btn results_window btn btn-inverse" data-selection-source="search-result">
|
||||
<img src="/assets/common/images/icons/delete.png" height="16" width="16" class="btn-image"/> {{ 'action : supprimer' | trans }}
|
||||
{% set menu_entry = menu_entries[0] %}
|
||||
<button class="results_window btn btn-inverse {{ menu_entry.class }}" data-selection-source="search-result">
|
||||
<img src="{{ menu_entry.icon }}" class="btn-image"/>
|
||||
{{ menu_entry.label }}
|
||||
</button>
|
||||
{% set menu_entries = menu_entries|slice(1) %}
|
||||
{% if menu_entries|length > 0 %}
|
||||
<button class="trigger btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span
|
||||
class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
{% for menu_entry in menu_entries %}
|
||||
<li>
|
||||
<a class="results_window {{ menu_entry.class }}" data-selection-source="search-result">
|
||||
<img src="{{ menu_entry.icon }}" class="btn-image"/>
|
||||
{{ menu_entry.label }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block toolbarJS %}
|
||||
{% if plugins.actionbar is not empty %}
|
||||
{% for plugin in plugins.actionbar %}
|
||||
{{ (plugin.JS|default(''))|raw }}
|
||||
{% for pluginId, plugin in plugins.actionbar %}
|
||||
{% if plugin.getActionBarTemplate is defined %}
|
||||
{% set template = plugin.getActionBarTemplate() %}
|
||||
{% if template %}
|
||||
{% include template with {'app': app, 'plugin_id': pluginId, 'plugin': plugin} only %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
@@ -92,12 +92,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
$(".records-subititution .diapo", scope)
|
||||
/* $(".records-subititution .diapo", scope)
|
||||
.bind('click', function(e){
|
||||
$(this).closest('.lazaret-proposals').find('.diapo').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
}
|
||||
);
|
||||
);*/
|
||||
|
||||
$(".records-subititution .captionTips", scope).tooltip();
|
||||
$(".records-subititution .infoTips", scope).tooltip();
|
||||
@@ -176,27 +176,32 @@
|
||||
emptying = true;
|
||||
f();
|
||||
});
|
||||
|
||||
var data;
|
||||
//add lazaret file click action
|
||||
$("button.add-lazaret", scope).bind('click', function () {
|
||||
var that = $(this);
|
||||
var lazaretId = getLazaretId(that);
|
||||
var destinationCollectionId = getDestinationId(that);
|
||||
var container = $(this).closest('.wrapper-item');
|
||||
var form = $(this).closest("form");
|
||||
|
||||
/*fix POST on firefox*/
|
||||
data = form.serializeArray();
|
||||
var allData = that.parent().closest('.wrapper-item').find(".change-record-wrapper").html();
|
||||
that.closest(".form-backup ").append(allData);
|
||||
that.parent().closest('.wrapper-item').find(".change-record ").remove();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/prod/lazaret/' + lazaretId + '/force-add/',
|
||||
dataType: 'json',
|
||||
data : {
|
||||
bas_id:destinationCollectionId,
|
||||
keep_attributes: 1
|
||||
},
|
||||
data: data,
|
||||
beforeSend: function () {
|
||||
startAjax(that);
|
||||
},
|
||||
success: function (data) {
|
||||
if (data.success) {
|
||||
that.closest(".wrapper-item").remove();
|
||||
container.remove();
|
||||
} else {
|
||||
var html = _.template($("#alert_error_tpl").html(), {
|
||||
content: data.message
|
||||
@@ -221,6 +226,12 @@
|
||||
$("button.delete-lazaret", scope).bind('click', function () {
|
||||
var that = $(this);
|
||||
var lazaretId = getLazaretId(that);
|
||||
var container = $(this).closest('.wrapper-item');
|
||||
var form = $(this).closest("form");
|
||||
data = form.serializeArray();
|
||||
var allData = that.parent().closest('.wrapper-item').find(".change-record-wrapper").html();
|
||||
that.closest(".form-backup ").append(allData);
|
||||
that.parent().closest('.wrapper-item').find(".change-record ").remove();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
@@ -231,7 +242,7 @@
|
||||
},
|
||||
success: function (data) {
|
||||
if (data.success) {
|
||||
that.closest(".wrapper-item").remove();
|
||||
container.remove();
|
||||
} else {
|
||||
var html = _.template($("#alert_error_tpl").html(), {
|
||||
content: data.message
|
||||
@@ -252,6 +263,89 @@
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
//update status list
|
||||
function resetStatus(that) {
|
||||
that.removeClass('selected');
|
||||
var html = that.parent().closest('.wrapper-item').find(".status-backup").html();
|
||||
that.parent().closest('.wrapper-item').find(".status-container").html('');
|
||||
that.parent().closest('.wrapper-item').find(".status-container").append(html);
|
||||
};
|
||||
$(".span12 img, .reset-status").click(function () {
|
||||
var that = $(this).closest('.wrapper-item').find('.lazaret-proposals .diapo');
|
||||
resetStatus(that);
|
||||
});
|
||||
$(".records-subititution .diapo", scope).bind('click', function () {
|
||||
var that = $(this);
|
||||
var diapo = that.closest('.lazaret-proposals').find('.diapo');
|
||||
var container = that.closest('.wrapper-item');
|
||||
diapo.not(this).removeClass('selected');
|
||||
/*Set selected or not to check for sending ajax request*/
|
||||
if (that.hasClass("selected")) {
|
||||
resetStatus(that);
|
||||
} else {
|
||||
that.addClass('selected');
|
||||
var elements = $(".selected", container);
|
||||
var recordId = elements.first().attr("data-record_id");
|
||||
var sBas = elements.first().attr("sbas");
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: '/prod/lazaret/' + sBas + '/' + recordId + '/status',
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
startAjax(that);
|
||||
},
|
||||
success: function (data) {
|
||||
if (data.status) {
|
||||
html = '';
|
||||
for ([key, value] of Object.entries(data.status)) {
|
||||
if (value.flag == 1) {
|
||||
checkValOff = '';
|
||||
checkValOn = 'checked=checked';
|
||||
} else {
|
||||
checkValOff = 'checked=checked';
|
||||
checkValOn = '';
|
||||
}
|
||||
var labelOff = value['labels_off_i18n']["{{ app['locale'] }}"];
|
||||
var labelOn = value['labels_on_i18n']["{{ app['locale'] }}"];
|
||||
if (labelOff == null || labelOff == "") {
|
||||
labelOff = 'off';
|
||||
}
|
||||
if (labelOn == null || labelOn == "") {
|
||||
labelOn = 'on';
|
||||
}
|
||||
html += '<tr>';
|
||||
html += '<td class="status-tab-left">';
|
||||
if (value['img_off'] != null) {
|
||||
html += ' <img src="{{ value['img_off'] }}" width="16" height="16" />';
|
||||
}
|
||||
;
|
||||
html += '<span>' + labelOff + '</span>';
|
||||
html += '<input type="radio" name="status[' + sBas + '][' + value.bit + ']" value="0" ' + checkValOff + ' />';
|
||||
html += '</td>';
|
||||
html += '<td class="status-tab-right">';
|
||||
html += '<input type="radio" name="status[' + sBas + '][' + value.bit + ']" value="1" ' + checkValOn + ' />';
|
||||
html += '<span>' + labelOn + '</span>';
|
||||
if (value['img_on'] != null) {
|
||||
html += '<img src="' + value['img_on'] + '" width="16" height="16" />';
|
||||
}
|
||||
;
|
||||
html += '</td>';
|
||||
html += '</tr>';
|
||||
}
|
||||
;
|
||||
that.parent().closest('.wrapper-item').find(".status-container").html('');
|
||||
that.parent().closest('.wrapper-item').find(".status-container").append(html);
|
||||
}
|
||||
},
|
||||
complete: function () {
|
||||
stopAjax(that);
|
||||
reloadContent();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//substitute lazaret file click action
|
||||
$("button.subtitute-lazaret", scope).bind('click', function () {
|
||||
var that = $(this);
|
||||
@@ -278,20 +372,27 @@
|
||||
}
|
||||
|
||||
var recordId = elements.first().attr("data-record_id");
|
||||
var form = $(this).closest("form");
|
||||
$(".record_id").val(recordId);
|
||||
|
||||
|
||||
var form = $(this).closest("form");
|
||||
data = form.serializeArray();
|
||||
var allData = that.parent().closest('.wrapper-item').find(".change-record-wrapper").html();
|
||||
that.closest(".form-backup ").append(allData);
|
||||
that.parent().closest('.wrapper-item').find(".change-record ").remove();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/prod/lazaret/' + lazaretId + '/accept/',
|
||||
dataType: 'json',
|
||||
data:{
|
||||
record_id: recordId
|
||||
},
|
||||
data: data,
|
||||
beforeSend: function () {
|
||||
startAjax(that);
|
||||
},
|
||||
success: function (data) {
|
||||
if (data.success) {
|
||||
that.closest(".wrapper-item").remove();
|
||||
container.remove();
|
||||
} else {
|
||||
var html = _.template($("#alert_error_tpl").html(), {
|
||||
content: data.message
|
||||
@@ -311,18 +412,18 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
/*Toggle status block*/
|
||||
$(".toggle-status").click(function () {
|
||||
$(this).nextAll('.status-wrapper').first().toggleClass('hidden');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.lazaret-proposals .diapo {
|
||||
float:none;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% macro lazaretElement(app, file) %}
|
||||
{% import "common/thumbnail.html.twig" as thumb %}
|
||||
{% set records = file.getRecordsToSubstitute(app, true) %}
|
||||
<div class="lazaret-file span4">
|
||||
|
||||
<h5>{{ "Last uploaded version" | trans }}</h5>
|
||||
<ul class="thumbnails">
|
||||
<li class="span12">
|
||||
@@ -344,6 +445,66 @@
|
||||
<p>{{ border_checker_from_fqcn(check.getCheckClassname()).getMessage(app['translator']) }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<form class="change-record" name="change-records-status" action="/" method="POST">
|
||||
<div class="change-record-wrapper">
|
||||
{% set collection = file.getCollection(app) %}
|
||||
<input type="hidden" name="bas_id" value="{{ collection.get_base_id() }}">
|
||||
<input type="hidden" name="keep_attributes" value="1">
|
||||
<input class="record_id" type="hidden" name="record_id">
|
||||
<div class="update-status">
|
||||
<div id="status-{{ collection.get_base_id() }}" class='collection-status'>
|
||||
<a href="#" class="reset-status btn">Reset status</a>
|
||||
<h5 class="toggle-status">{{ 'upload:: Status :' | trans }} <img src="/assets/common/images/icons/icon-right-arrow.svg" width="10" height="10" class="btn-status"></h5>
|
||||
<div class="status-wrapper hidden">
|
||||
<table style="margin: auto">
|
||||
<tbody class="status-container">
|
||||
{% if file.getStatus(app) is not null %}
|
||||
{% for bit, status in file.getStatus(app) %}
|
||||
<tr>
|
||||
<td class="status-tab-left">
|
||||
{% if status['img_off'] is not empty %}
|
||||
<img src="{{ status['img_off'] }}" width="16" height="16" />
|
||||
{% endif %}
|
||||
<span>{{ status['labels_off_i18n'][app['locale']]|default('off') }}</span>
|
||||
<input type="radio" name="status[{{ collection.get_sbas_id() }}][{{ bit }}]" value="0" {% if status['flag'] == 0 %}checked="checked"{% endif%}/>
|
||||
|
||||
</td>
|
||||
<td class="status-tab-right">
|
||||
<input type="radio" name="status[{{ collection.get_sbas_id() }}][{{ bit }}]" value="1" {% if status['flag'] == 1 %}checked="checked"{% endif%} />
|
||||
<span for="labelon">{{ status['labels_on_i18n'][app['locale']]|default('on') }}</span>
|
||||
{% if status['img_on'] is not empty %}
|
||||
<img src="{{ status['img_on'] }}" width="16" height="16" />
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for bit, status in collection.get_databox().getStatusStructure() %}
|
||||
<tr>
|
||||
<td class="status-tab-left">
|
||||
{% if status['img_off'] is not empty %}
|
||||
<img src="{{ status['img_off'] }}" width="16" height="16" />
|
||||
{% endif %}
|
||||
<span>{{ status['labels_off_i18n'][app['locale']]|default('off') }}</span>
|
||||
<input type="radio" name="status[{{ collection.get_sbas_id() }}][{{ bit }}]" value="0" checked="checked"/>
|
||||
|
||||
</td>
|
||||
<td class="status-tab-right">
|
||||
<input type="radio" name="status[{{ collection.get_sbas_id() }}][{{ bit }}]" value="1" />
|
||||
<span for="labelon">{{ status['labels_on_i18n'][app['locale']]|default('on') }}</span>
|
||||
{% if status['img_on'] is not empty %}
|
||||
<img src="{{ status['img_on'] }}" width="16" height="16" />
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" style="text-align:center; padding:5px;">
|
||||
<button class="btn add-lazaret" title="{{ "Add" | trans }}">
|
||||
<img src="/assets/common/images/icons/add.png" width="16" height="16" class="btn-image">{{ "Add" | trans }}
|
||||
@@ -358,6 +519,55 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="hidden form-backup"></div>
|
||||
{# bloc to backup initial value of status list#}
|
||||
<table class="hidden">
|
||||
<tbody class="status-backup">
|
||||
{% if file.getStatus(app) is not null %}
|
||||
{% for bit, status in file.getStatus(app) %}
|
||||
<tr>
|
||||
<td class="status-tab-left">
|
||||
{% if status['img_off'] is not empty %}
|
||||
<img src="{{ status['img_off'] }}" width="16" height="16"/>
|
||||
{% endif %}
|
||||
<span>{{ status['labels_off_i18n'][app['locale']]|default('off') }}</span>
|
||||
<input type="radio" name="status[{{ collection.get_sbas_id() }}][{{ bit }}]" value="0" {% if status['flag'] == 0 %}checked="checked"{% endif%}/>
|
||||
|
||||
</td>
|
||||
<td class="status-tab-right">
|
||||
<input type="radio" name="status[{{ collection.get_sbas_id() }}][{{ bit }}]" value="1" {% if status['flag'] == 1 %}checked="checked"{% endif%} />
|
||||
<span for="labelon">{{ status['labels_on_i18n'][app['locale']]|default('on') }}</span>
|
||||
{% if status['img_on'] is not empty %}
|
||||
<img src="{{ status['img_on'] }}" width="16" height="16"/>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for bit, status in collection.get_databox().getStatusStructure() %}
|
||||
<tr>
|
||||
<td class="status-tab-left">
|
||||
{% if status['img_off'] is not empty %}
|
||||
<img src="{{ status['img_off'] }}" width="16" height="16" />
|
||||
{% endif %}
|
||||
<span>{{ status['labels_off_i18n'][app['locale']]|default('off') }}</span>
|
||||
<input type="radio" name="status[{{ collection.get_sbas_id() }}][{{ bit }}]" value="0" checked="checked"/>
|
||||
|
||||
</td>
|
||||
<td class="status-tab-right">
|
||||
<input type="radio" name="status[{{ collection.get_sbas_id() }}][{{ bit }}]" value="1" />
|
||||
<span for="labelon">{{ status['labels_on_i18n'][app['locale']]|default('on') }}</span>
|
||||
{% if status['img_on'] is not empty %}
|
||||
<img src="{{ status['img_on'] }}" width="16" height="16" />
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
{# Store lazaret file id in hidden input #}
|
||||
@@ -406,3 +616,30 @@
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
<style>
|
||||
.lazaret-proposals .diapo {
|
||||
float:none;
|
||||
}
|
||||
|
||||
.collection-status {
|
||||
margin: 0 11px 14px;
|
||||
background: #f5f5f5;
|
||||
padding-bottom: 10px;
|
||||
color: #151515;
|
||||
}
|
||||
.collection-status h5 {
|
||||
padding: 10px 10px 0 10px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.reset-status {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
background: #fff;
|
||||
border: 1px solid;
|
||||
padding: 2px 5px;
|
||||
margin-top: -4px;
|
||||
margin-right: -6px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@@ -230,6 +230,7 @@ class FieldsTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
'vocabulary-type' => 'User',
|
||||
'vocabulary-restricted' => true,
|
||||
'gui_editable' => true,
|
||||
'gui_visible' => true,
|
||||
'generate_cterms' => true,
|
||||
]);
|
||||
|
||||
|
@@ -48,6 +48,7 @@ class TextNodeTest extends \PHPUnit_Framework_TestCase
|
||||
$query_context->getUnrestrictedFields()->willReturn([$field]);
|
||||
$query_context->getPrivateFields()->willReturn([]);
|
||||
$query_context->localizeField($field)->willReturn(['foo.fr', 'foo.en']);
|
||||
$query_context->truncationField($field)->willReturn([]);
|
||||
|
||||
$node = new TextNode('bar', new Context('baz'));
|
||||
$query = $node->buildQuery($query_context->reveal());
|
||||
@@ -80,12 +81,18 @@ class TextNodeTest extends \PHPUnit_Framework_TestCase
|
||||
$query_context
|
||||
->localizeField($public_field)
|
||||
->willReturn(['foo.fr', 'foo.en']);
|
||||
$query_context
|
||||
->truncationField($public_field)
|
||||
->willReturn([]);
|
||||
$query_context
|
||||
->getPrivateFields()
|
||||
->willReturn([$private_field]);
|
||||
$query_context
|
||||
->localizeField($private_field)
|
||||
->willReturn(['private_caption.bar.fr', 'private_caption.bar.en']);
|
||||
$query_context
|
||||
->truncationField($private_field)
|
||||
->willReturn([]);
|
||||
|
||||
$node = new TextNode('baz');
|
||||
$query = $node->buildQuery($query_context->reveal());
|
||||
@@ -136,6 +143,7 @@ class TextNodeTest extends \PHPUnit_Framework_TestCase
|
||||
$query_context->getUnrestrictedFields()->willReturn([$field]);
|
||||
$query_context->getPrivateFields()->willReturn([]);
|
||||
$query_context->localizeField($field)->willReturn(['foo.fr', 'foo.en']);
|
||||
$query_context->truncationField($field)->willReturn([]);
|
||||
|
||||
$node = new TextNode('bar');
|
||||
$node->setConcepts([
|
||||
@@ -180,12 +188,18 @@ class TextNodeTest extends \PHPUnit_Framework_TestCase
|
||||
$query_context
|
||||
->localizeField($public_field)
|
||||
->willReturn(['foo.fr', 'foo.en']);
|
||||
$query_context
|
||||
->truncationField($public_field)
|
||||
->willReturn([]);
|
||||
$query_context
|
||||
->getPrivateFields()
|
||||
->willReturn([$private_field]);
|
||||
$query_context
|
||||
->localizeField($private_field)
|
||||
->willReturn(['private_caption.bar.fr', 'private_caption.bar.en']);
|
||||
$query_context
|
||||
->truncationField($private_field)
|
||||
->willReturn([]);
|
||||
|
||||
$node = new TextNode('baz');
|
||||
$node->setConcepts([
|
||||
|
@@ -18,7 +18,7 @@ class QueryContextTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$structure = $this->prophesize(Structure::class)->reveal();
|
||||
$available_locales = ['ab', 'cd', 'ef'];
|
||||
$context = new QueryContext($structure, $available_locales, 'fr');
|
||||
$context = new QueryContext(null, $structure, $available_locales, 'fr');
|
||||
$narrowed = $context->narrowToFields(['some_field']);
|
||||
$this->assertEquals(['some_field'], $narrowed->getFields());
|
||||
}
|
||||
@@ -33,10 +33,10 @@ class QueryContextTest extends \PHPUnit_Framework_TestCase
|
||||
'bar' => $bar_field
|
||||
]);
|
||||
|
||||
$context = new QueryContext($structure->reveal(), [], 'fr');
|
||||
$context = new QueryContext(null, $structure->reveal(), [], 'fr');
|
||||
$this->assertEquals([$foo_field, $bar_field], $context->getUnrestrictedFields());
|
||||
|
||||
$narrowed_context = new QueryContext($structure->reveal(), [], 'fr', ['foo']);
|
||||
$narrowed_context = new QueryContext(null, $structure->reveal(), [], 'fr', ['foo']);
|
||||
$this->assertEquals([$foo_field], $narrowed_context->getUnrestrictedFields());
|
||||
}
|
||||
|
||||
@@ -50,10 +50,10 @@ class QueryContextTest extends \PHPUnit_Framework_TestCase
|
||||
'bar' => $bar_field
|
||||
]);
|
||||
|
||||
$context = new QueryContext($structure->reveal(), [], 'fr');
|
||||
$context = new QueryContext(null, $structure->reveal(), [], 'fr');
|
||||
$this->assertEquals([$foo_field, $bar_field], $context->getPrivateFields());
|
||||
|
||||
$narrowed_context = new QueryContext($structure->reveal(), [], 'fr', ['foo']);
|
||||
$narrowed_context = new QueryContext(null, $structure->reveal(), [], 'fr', ['foo']);
|
||||
$this->assertEquals([$foo_field], $narrowed_context->getPrivateFields());
|
||||
}
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@ class StructureTest extends \PHPUnit_Framework_TestCase
|
||||
$field->isFacet()->willReturn(false);
|
||||
$field->hasConceptInference()->willReturn(false);
|
||||
$field->getDependantCollections()->willReturn(['1']);
|
||||
$field->get_databox_id()->willReturn('1');
|
||||
|
||||
$structure->add($field->reveal());
|
||||
$this->assertCount(1, $structure->getAllFields());
|
||||
@@ -60,6 +61,7 @@ class StructureTest extends \PHPUnit_Framework_TestCase
|
||||
$field->isPrivate()->willReturn(false);
|
||||
$field->isFacet()->willReturn(false);
|
||||
$field->hasConceptInference()->willReturn(false);
|
||||
$field->get_databox_id()->willReturn('1');
|
||||
|
||||
$other = new Field('foo', FieldMapping::TYPE_STRING);
|
||||
|
||||
|
@@ -14,14 +14,14 @@ use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Typed;
|
||||
class ValueCheckerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider escapeRawProvider
|
||||
* @dataProvider valueCheckerProvider
|
||||
*/
|
||||
public function testValueCompatibility($subject, $value, $compatible)
|
||||
{
|
||||
$this->assertEquals($compatible, ValueChecker::isValueCompatible($subject, $value));
|
||||
}
|
||||
|
||||
public function escapeRawProvider()
|
||||
public function valueCheckerProvider()
|
||||
{
|
||||
$values = [
|
||||
[FieldMapping::TYPE_FLOAT , 42 , true ],
|
||||
|
@@ -28,6 +28,7 @@ define([
|
||||
"tbranch": "",
|
||||
"generate_cterms": false,
|
||||
"gui_editable": true,
|
||||
"gui_visible": true,
|
||||
"separator": "",
|
||||
"required": false,
|
||||
"report": true,
|
||||
|
@@ -52,6 +52,10 @@ define([
|
||||
this.field.get('gui_editable').should.equal("1");
|
||||
});
|
||||
|
||||
it("should default gui_visible property to '1'", function () {
|
||||
this.field.get('gui_visible').should.equal("1");
|
||||
});
|
||||
|
||||
it("should default separator property to 'empty'", function () {
|
||||
this.field.get('separator').should.equal("");
|
||||
});
|
||||
|
66
yarn.lock
66
yarn.lock
@@ -3815,9 +3815,9 @@ fsevents@^1.0.0, fsevents@^1.1.2, fsevents@^1.2.7:
|
||||
node-pre-gyp "^0.12.0"
|
||||
|
||||
fstream@^1.0.0, fstream@^1.0.2:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171"
|
||||
integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=
|
||||
version "1.0.12"
|
||||
resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045"
|
||||
integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
inherits "~2.0.0"
|
||||
@@ -4049,7 +4049,7 @@ glob@^5.0.15:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@~7.1.1:
|
||||
glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1:
|
||||
version "7.1.4"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
|
||||
integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
|
||||
@@ -4061,6 +4061,18 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@~7.1.1:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.1.3:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@~3.1.21:
|
||||
version "3.1.21"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd"
|
||||
@@ -4166,10 +4178,10 @@ graceful-fs@^3.0.0:
|
||||
dependencies:
|
||||
natives "^1.1.0"
|
||||
|
||||
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@~4.1.4:
|
||||
version "4.1.15"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
|
||||
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
|
||||
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
|
||||
integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
|
||||
|
||||
graceful-fs@~1.2.0:
|
||||
version "1.2.3"
|
||||
@@ -4181,6 +4193,11 @@ graceful-fs@~2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-2.0.3.tgz#7cd2cdb228a4a3f36e95efa6cc142de7d1a136d0"
|
||||
integrity sha1-fNLNsiiko/Nule+mzBQt59GhNtA=
|
||||
|
||||
graceful-fs@~4.1.4:
|
||||
version "4.1.15"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
|
||||
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
|
||||
|
||||
"graceful-readlink@>= 1.0.0":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
|
||||
@@ -4757,7 +4774,12 @@ inherits@1:
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b"
|
||||
integrity sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=
|
||||
|
||||
inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
|
||||
inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
inherits@2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
@@ -5974,9 +5996,9 @@ lodash.keys@~2.4.1:
|
||||
lodash.isobject "~2.4.1"
|
||||
|
||||
lodash.merge@^4.6.0:
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54"
|
||||
integrity sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash.restparam@^3.0.0:
|
||||
version "3.6.1"
|
||||
@@ -6483,9 +6505,9 @@ mitt@^1.1.3:
|
||||
integrity sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==
|
||||
|
||||
mixin-deep@^1.2.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe"
|
||||
integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566"
|
||||
integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==
|
||||
dependencies:
|
||||
for-in "^1.0.2"
|
||||
is-extendable "^1.0.1"
|
||||
@@ -7555,10 +7577,10 @@ phraseanet-common@^0.4.1:
|
||||
js-cookie "^2.1.0"
|
||||
pym.js "^1.3.1"
|
||||
|
||||
phraseanet-production-client@0.34.72-d:
|
||||
version "0.34.72-d"
|
||||
resolved "https://registry.yarnpkg.com/phraseanet-production-client/-/phraseanet-production-client-0.34.72-d.tgz#028a5ccd589e696b5433eea9d53d9367966613c8"
|
||||
integrity sha512-IPaDRqXwyJegoKmzr56bggxTzN4TnmuAqU4O7rDEhh0aqdCiuC8rlH/yzKoLeEIMSrESCw5mBhrI//ccntvv9w==
|
||||
phraseanet-production-client@0.34.80-d:
|
||||
version "0.34.80-d"
|
||||
resolved "https://registry.yarnpkg.com/phraseanet-production-client/-/phraseanet-production-client-0.34.80-d.tgz#1e54bee4306ab11528377cb63c19d8c7491ef0f3"
|
||||
integrity sha512-ilGs7ndDNztwlyeW9MA2TMiMhZC+P1/lNNeIsIuh+KuJH8M3Y3SWBcmsN2lqu5iM1Xg5FbWJ6iXcCSrLWHTqsw==
|
||||
dependencies:
|
||||
"@mapbox/mapbox-gl-language" "^0.9.2"
|
||||
"@turf/turf" "^5.1.6"
|
||||
@@ -8296,9 +8318,9 @@ right-align@^0.1.1:
|
||||
align-text "^0.1.1"
|
||||
|
||||
rimraf@2, rimraf@^2.2.8, rimraf@^2.5.0, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
||||
integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
|
||||
version "2.7.1"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
||||
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
|
Reference in New Issue
Block a user