diff --git a/.build-dkan.make.swp b/.build-dkan.make.swp deleted file mode 100644 index 671cd1713..000000000 Binary files a/.build-dkan.make.swp and /dev/null differ diff --git a/CHANGELOG.md b/CHANGELOG.md index fee4b2c43..0ca4ec5cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ # Change log + +## [1.14.0.0] +- Add admin_views to features master in data_config + ## [1.13.7.0] - Update to dkan version 1.13.7 - Fix ODSM Memory Error #402 diff --git a/assets/modules/data_config/data_config.module b/assets/modules/data_config/data_config.module index 9ec88ae69..6c7b5efa7 100644 --- a/assets/modules/data_config/data_config.module +++ b/assets/modules/data_config/data_config.module @@ -23,6 +23,7 @@ function data_config_enabled_modules() { 'admin_menu' => 'admin_menu', 'admin_menu_source' => 'admin_menu_source', 'admin_menu_toolbar' => 'admin_menu_toolbar', + 'admin_views' => 'admin_views', 'adminrole' => 'adminrole', 'ape' => 'ape', 'autocomplete_deluxe' => 'autocomplete_deluxe', diff --git a/build-dkan.make b/build-dkan.make index 6d91121c6..5f9bf60d7 100644 --- a/build-dkan.make +++ b/build-dkan.make @@ -8,7 +8,5 @@ includes[core] = dkan/drupal-org-core.make projects[dkan][type] = profile projects[dkan][download][type] = git projects[dkan][download][url] = https://github.com/NuCivic/dkan.git -projects[dkan][download][tag] = 7.x-1.13.7 +projects[dkan][download][tag] = 7.x-1.14-RC1 -projects[dkan][patch][] = https://patch-diff.githubusercontent.com/raw/NuCivic/dkan/pull/1976.diff -projects[dkan][patch][] = https://patch-diff.githubusercontent.com/raw/NuCivic/dkan/pull/2095.diff diff --git a/dkan/.ahoy/.scripts/.ht.router.php b/dkan/.ahoy/.scripts/.ht.router.php index 9fa2cfcd8..1f7d9b453 100644 --- a/dkan/.ahoy/.scripts/.ht.router.php +++ b/dkan/.ahoy/.scripts/.ht.router.php @@ -1,5 +1,4 @@ \(.*\),/\1'host' => '$MYSQL_IP',/g" $SETTINGS_PATH + +chmod -w $SETTINGS_PATH +chmod -w $DIR + diff --git a/dkan/.ahoy/.scripts/server.sh b/dkan/.ahoy/.scripts/server.sh index 7cab895b8..3191662f6 100644 --- a/dkan/.ahoy/.scripts/server.sh +++ b/dkan/.ahoy/.scripts/server.sh @@ -9,4 +9,4 @@ cp ./dkan/.ahoy/.scripts/.ht.router.php ./docroot/ cd ./docroot echo $HOST -php -S $HOST:8888 .ht.router.php \ No newline at end of file +php -S $HOST:8888 .ht.router.php diff --git a/dkan/.ahoy/dkan.ahoy.yml b/dkan/.ahoy/dkan.ahoy.yml index b27440566..2dac9ab6e 100644 --- a/dkan/.ahoy/dkan.ahoy.yml +++ b/dkan/.ahoy/dkan.ahoy.yml @@ -20,7 +20,11 @@ commands: if [ -d docroot ] then ahoy confirm "./docroot folder alredy exists. Delete it and reinstall drupal?" && chmod -R 777 docroot/sites/default && rm -rf docroot || - { echo ".. skipping installation"; exit 1;} + { + echo ".. skipping installation"; + ahoy cmd-proxy bash dkan/.ahoy/.scripts/mysql-reconnect.sh $ARGS + exit 1; + } fi ahoy cmd-proxy bash dkan/.ahoy/.scripts/drupal-rebuild.sh $ARGS @@ -46,7 +50,7 @@ commands: if [ ! -d backups ]; then mkdir backups fi - if [ -f backups/last_install.sql ] && ahoy confirm "An existing installation backup exists at backups/last_install.sql, do you want to use that instead of reinstalling from scratch?"; then + if [ -f backups/last_install.sql ] && ahoy confirm "{{args}} An existing installation backup exists at backups/last_install.sql, do you want to use that instead of reinstalling from scratch?"; then ahoy drush sql-drop -y && \ echo "... Removed tables, restoring DB" diff --git a/dkan/.ahoy/site/.ahoy.yml b/dkan/.ahoy/site/.ahoy.yml deleted file mode 100644 index 9cc4805e8..000000000 --- a/dkan/.ahoy/site/.ahoy.yml +++ /dev/null @@ -1,116 +0,0 @@ -ahoyapi: v1 -usage: NuCivic Data cli app for development using ahoy. -commands: - drush: - usage: Run drush via ahoy (helpful for abstraction) - cmd: ahoy cmd-proxy drush --root=docroot "{{args}}" - - build: - usage: A series of commands for dkan development. - import: dkan/.ahoy/site/build.ahoy.yml - hide: true - - dkan: - usage: A series of commands for dkan development. - hide: true - import: dkan/.ahoy/dkan.ahoy.yml - - diagnose: - usage: A series of ahoy-docker setup diagnosis commands. - import: dkan/.ahoy/diagnose.ahoy.yml - hide: true - - doctor: - usage: A series of ahoy-docker setup diagnosis commands. - import: dkan/.ahoy/diagnose.ahoy.yml - hide: true - - confirm: - cmd: ahoy -f dkan/.ahoy/utils.ahoy.yml confirm {{args}} - hide: true - - docker: - usage: A series of docker commands for dkan development (experimental) - import: dkan/.ahoy/docker.ahoy.yml - hide: true - - init: - cmd: echo "ahoy.yml file already exists." - hide: true - - cmd-proxy: - usage: abstraction for commmands. - cmd: | - if [ "$AHOY_CMD_PROXY" == "DOCKER" ]; then - ahoy docker exec "{{args}}" - else - {{args}} - fi - hide: true - - ci: - usage: A series of commands to handle ci setup - import: dkan/.ahoy/site/ci.ahoy.yml - hide: true - - tools: - usage: A series of commands to setup dev tools - import: dkan/.ahoy/site/tools.ahoy.yml - hide: true - - debug: - usage: A series of commands to setup debugging - import: dkan/.ahoy/site/debug.ahoy.yml - hide: true - - launch-checklist: - usage: A series of commands to handle pre launch checks - import: dkan/.ahoy/site/launch-checklist.ahoy.yml - hide: true - - site: - usage: A series of commands for site development - import: dkan/.ahoy/site/site.ahoy.yml - - utils: - hide: true - usage: A series of helper commands (hide the details) - import: dkan/.ahoy/site/utils.ahoy.yml - - remote: - usage: A series of commands for site remote management - import: dkan/.ahoy/site/remote.ahoy.yml - hide: true - - custom: - usage: A series of custom commands specific to a project. - import: config/custom.ahoy.yml - hide: true - - parse: - usage: ahoy parse :filpath :argument, where :argument depth is seperated by underscores. - hide: true - cmd: | - # Attribution: https://gist.github.com/epiloque/8cf512c6d64641bde388#file-yaml-sh - parse_yaml() { - local prefix=$2 - local s - local w - local fs - s='[[:space:]]*' - w='[a-zA-Z0-9_]*' - fs="$(echo @|tr @ '\034')" - sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \ - -e "s|^\($s\)\($w\)$s[:-]$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$1" | - awk -F"$fs" '{ - indent = length($1)/2; - vname[indent] = $2; - for (i in vname) {if (i > indent) {delete vname[i]}} - if (length($3) > 0) { - vn=""; for (i=0; i 0); - --- don't leave e-mail addresses, etc in comments table. --- UPDATE comments SET name='Anonymous', mail='', homepage='http://example.com' WHERE uid=0; - --- Scrub webform submissions. --- UPDATE webform_submitted_data set data='*scrubbed*'; - --- remove sensitive customer data from custom module --- TRUNCATE custom_customer_lead_data; - --- USER PASSWORDS --- Drupal 7 requires sites to generate a hashed password specific to their site. A script in the --- docroot/scripts directory is provided for doing this. From your docroot run the following: --- --- scripts/password-hash.sh password --- --- this will generate a hash for the password "password". In the following statements replace --- $REPLACE THIS$ with your generated hash. - -UPDATE users SET pass = '$S$DAIFIwaPZLsfNqEZkYY1Wklf6TIQal1uObBpIPk1UDUsc6qgPi6b' WHERE uid IN (SELECT uid FROM users_roles WHERE rid=3) AND uid > 0; -UPDATE users SET name = 'admin' WHERE uid = 1; -UPDATE users SET pass = '$S$DAGmJJr.MOF1M6wTF/YEU6yBchL5kkAvaMGgvXQtVVJyD4KXmc5G' WHERE uid = 1; - -TRUNCATE flood; -TRUNCATE history; -TRUNCATE sessions; -TRUNCATE watchdog; - -SELECT concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'access%'; - -SELECT concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'devel_%'; - -SELECT concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'cache%'; - -SELECT concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'migrate_%'; - -SELECT concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'search_%'; diff --git a/dkan/.ahoy/site/.scripts/config.php b/dkan/.ahoy/site/.scripts/config.php deleted file mode 100644 index a278130ee..000000000 --- a/dkan/.ahoy/site/.scripts/config.php +++ /dev/null @@ -1,42 +0,0 @@ - realpath(__DIR__ . '/../.cache'), -)); -$twig->addFunction(new Twig_SimpleFunction('var_export', 'var_export')); - -try { - // Parse yaml. - $yaml = new Parser(); - $config = $yaml->parse(file_get_contents(__DIR__ . '/../../../../config/config.yml')); - - // Render yaml using twig template. - $context = array( - 'config' => $config, - ); - $output = $twig->render( - 'config.php.twig', - $context - ); - - // Write the php file. - $file = fopen(__DIR__ . '/../../../../config/config.php', 'w'); - fwrite($file, $output); -} catch (Exception $e) { - echo "An error happened trying to transpose the config.yml file:\n{$e->getMessage()}\n"; -} finally { - if ($file) { - fclose($file); - } -} - diff --git a/dkan/.ahoy/site/.scripts/drush.alias.sh b/dkan/.ahoy/site/.scripts/drush.alias.sh deleted file mode 100644 index 8903eefcd..000000000 --- a/dkan/.ahoy/site/.scripts/drush.alias.sh +++ /dev/null @@ -1,13 +0,0 @@ -mkdir -p ~/.drush -cp -L ./assets/drush/aliases.local.php ~/.drush -name=$(ahoy utils name) -touch ~/.drush/$name.aliases.drushrc.php - -echo ' - ~/.drush/$name.aliases.drushrc.php diff --git a/dkan/.ahoy/site/.scripts/overrides.php b/dkan/.ahoy/site/.scripts/overrides.php deleted file mode 100644 index 8ff690cb8..000000000 --- a/dkan/.ahoy/site/.scripts/overrides.php +++ /dev/null @@ -1,32 +0,0 @@ -parse(file_get_contents(__DIR__ . '/../../../../config/overrides.make')); - $drupal_org_make = make_parse_info_file(realpath(__DIR__ . '/../../../../dkan/drupal-org.make')); - - if (is_array($overrides_make) && is_array($drupal_org_make)) { - if (isset($overrides_make['projects']['drupal'])) { - unset($overrides_make['projects']['drupal']); - } - $overriden_modules = array_keys($overrides_make['projects']); - foreach ($overriden_modules as $key) { - $module_definition = array_replace_recursive( - $overrides_make['projects'][$key], - $drupal_org_make['projects'][$key] - ); - $overrides_make['projects'][$key] = $module_definition; - } - $dumper = new Dumper(); - $overriden_yaml = $dumper->dump($overrides_make, 4); - file_put_contents(__DIR__ . '/../../../../overriden_make.make', $overriden_yaml); - } - -} catch (Exception $e) { - - echo "An error happened trying to override drupal-org.make:\n{$e->getMessage()}\n"; -} - diff --git a/dkan/.ahoy/site/.scripts/prune-database.php b/dkan/.ahoy/site/.scripts/prune-database.php deleted file mode 100644 index a79fc864c..000000000 --- a/dkan/.ahoy/site/.scripts/prune-database.php +++ /dev/null @@ -1,95 +0,0 @@ -fetchAll(); - foreach ($topics as $topic) { - $terms_to_save[] = $topic->tid; - } - $tags = db_query("SELECT DISTINCT field_tags_tid as tid FROM {field_data_field_tags} LIMIT $number")->fetchAll(); - foreach ($tags as $tag) { - $terms_to_save[] = $tag->tid; - } - $all_terms = array(); - // Leave all formats. - $format_vid = 1; - $terms = db_query("SELECT DISTINCT tid FROM {taxonomy_term_data} WHERE vid != $format_vid")->fetchAll(); - foreach ($terms as $term) { - $all_terms[] = $term->tid; - } - foreach ($all_terms as $tid) { - if (!in_array($tid,$terms_to_save)) { - taxonomy_term_delete($tid); - } - } -} - -/** - * Prunes nodes. - */ -function prune_nodes($number = 25) { - $query = db_select('node', 'n'); - $query->range(0, $number); - $records = $query - ->fields('n', array('nid')) - ->condition('type', 'dataset') - ->condition('status', 1) - ->orderBy('created', 'DESC') - ->execute(); - - $keep_nodes = []; - foreach($records as $record) { - $keep_nodes[] = $record->nid; - } - - $query = db_select('node', 'n'); - $nodes = $query - ->fields('n', array('nid')) - ->condition('type', 'dataset') - ->condition('n.nid', $keep_nodes, 'NOT IN') - ->execute(); - - $delete_nodes = []; - - foreach($nodes as $node) { - $dataset = node_load($node->nid); - $resources = $dataset->field_resources['und']; - $resources = is_array($resources) ? $resources : array(); - try { - node_delete($node->nid); - } - catch(Exception $e) { - print "Skipping dataset $node->nid do to error\n"; - } - foreach($resources as $resource) { - try { - node_delete($resource['target_id']); - } - catch(Exception $e) { - print "Skipping resource $resource[target_id] do to error\n"; - } - } - } -} - diff --git a/dkan/.ahoy/site/.scripts/s3-setup.sh b/dkan/.ahoy/site/.scripts/s3-setup.sh deleted file mode 100644 index b16b59c3a..000000000 --- a/dkan/.ahoy/site/.scripts/s3-setup.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -set -e - -if [ ! -f ~/.s3curl ]; then - if [[ -z "$AWS_ID" || -z "$AWS_KEY" ]]; then - echo "AWS environment variables are not set and there's no .s3curl file available. Aborting." - exit 1; - fi -fi - -if [ ! -f ~/.s3curl ]; then - echo " -%awsSecretAccessKeys = ( - local => { - id => '$AWS_ID', - key => '$AWS_KEY', - } -);" > ~/.s3curl -chmod 600 ~/.s3curl -else - echo ".s3curl file is available. Skipping" -fi diff --git a/dkan/.ahoy/site/.scripts/s3curl.pl b/dkan/.ahoy/site/.scripts/s3curl.pl deleted file mode 100644 index 336b6e7fb..000000000 --- a/dkan/.ahoy/site/.scripts/s3curl.pl +++ /dev/null @@ -1,377 +0,0 @@ -#!/usr/bin/perl -w - -# Copyright 2006-2010 Amazon.com, Inc. or its affiliates. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"). You may not use this -# file except in compliance with the License. A copy of the License is located at -# -# http://aws.amazon.com/apache2.0/ -# -# or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License -# for the specific language governing permissions and limitations under the License. - -use strict; -use POSIX; - -# you might need to use CPAN to get these modules. -# run perl -MCPAN -e "install " to get them. - -use Digest::HMAC_SHA1; -use Digest::MD5; -use FindBin; -use MIME::Base64 qw(encode_base64); -use Getopt::Long qw(GetOptions); - -use constant STAT_MODE => 2; -use constant STAT_UID => 4; - -# begin customizing here -my @endpoints = ( 's3.amazonaws.com', - 's3-us-west-1.amazonaws.com', - 's3-us-west-2.amazonaws.com', - 's3-us-gov-west-1.amazonaws.com', - 's3-eu-west-1.amazonaws.com', - 's3-ap-southeast-1.amazonaws.com', - 's3-ap-northeast-1.amazonaws.com', - 's3-sa-east-1.amazonaws.com', ); - -my $CURL = "curl"; - -# stop customizing here - -my $cmdLineSecretKey; -my %awsSecretAccessKeys = (); -my $keyFriendlyName; -my $keyId; -my $secretKey; -my $contentType = ""; -my $acl; -my $contentMD5 = ""; -my $fileToPut; -my $createBucket; -my $doDelete; -my $doHead; -my $help; -my $debug = 0; -my $copySourceObject; -my $copySourceRange; -my $postBody; -my $calculateContentMD5 = 0; - -my $DOTFILENAME=".s3curl"; -my $EXECFILE=$FindBin::Bin; -my $LOCALDOTFILE = $EXECFILE . "/" . $DOTFILENAME; -my $HOMEDOTFILE = $ENV{HOME} . "/" . $DOTFILENAME; -my $DOTFILE = -f $LOCALDOTFILE? $LOCALDOTFILE : $HOMEDOTFILE; - -if (-f $DOTFILE) { - open(CONFIG, $DOTFILE) || die "can't open $DOTFILE: $!"; - - my @stats = stat(*CONFIG); - - if (($stats[STAT_UID] != $<) || $stats[STAT_MODE] & 066) { - die "I refuse to read your credentials from $DOTFILE as this file is " . - "readable by, writable by or owned by someone else. Try " . - "chmod 600 $DOTFILE"; - } - - my @lines = ; - close CONFIG; - eval("@lines"); - die "Failed to eval() file $DOTFILE:\n$@\n" if ($@); -} - -GetOptions( - 'id=s' => \$keyId, - 'key=s' => \$cmdLineSecretKey, - 'contentType=s' => \$contentType, - 'acl=s' => \$acl, - 'contentMd5=s' => \$contentMD5, - 'put=s' => \$fileToPut, - 'copySrc=s' => \$copySourceObject, - 'copySrcRange=s' => \$copySourceRange, - 'post:s' => \$postBody, - 'delete' => \$doDelete, - 'createBucket:s' => \$createBucket, - 'head' => \$doHead, - 'help' => \$help, - 'debug' => \$debug, - 'calculateContentMd5' => \$calculateContentMD5, -); - -my $usage = < PUT request (from the provided local file) - --post [] POST request (optional local file) - --copySrc bucket/key Copy from this source key - --copySrcRange {startIndex}-{endIndex} - --createBucket [] create-bucket with optional location constraint - --head HEAD request - --debug enable debug logging - common curl options: - -H 'x-amz-acl: public-read' another way of using canned ACLs - -v verbose logging -USAGE -die $usage if $help || !defined $keyId; - -if ($cmdLineSecretKey) { - printCmdlineSecretWarning(); - sleep 5; - - $secretKey = $cmdLineSecretKey; -} else { - my $keyinfo = $awsSecretAccessKeys{$keyId}; - die "I don't know about key with friendly name $keyId. " . - "Do you need to set it up in $DOTFILE?" - unless defined $keyinfo; - - $keyId = $keyinfo->{id}; - $secretKey = $keyinfo->{key}; -} - -if ($contentMD5 && $calculateContentMD5) { - die "cannot specify both --contentMd5 and --calculateContentMd5"; -} - - -my $method = ""; -if (defined $fileToPut or defined $createBucket or defined $copySourceObject) { - $method = "PUT"; -} elsif (defined $doDelete) { - $method = "DELETE"; -} elsif (defined $doHead) { - $method = "HEAD"; -} elsif (defined $postBody) { - $method = "POST"; -} else { - $method = "GET"; -} -my $resource; -my $host; - -if ($calculateContentMD5) { - if ($fileToPut) { - $contentMD5 = calculateFileContentMD5($fileToPut); - } elsif ($createBucket) { - $contentMD5 = calculateStringContentMD5(getCreateBucketData($createBucket)); - } elsif ($postBody) { - $contentMD5 = calculateFileContentMD5($postBody); - } else { - $contentMD5 = calculateStringContentMD5(''); - } -} - -my %xamzHeaders; -$xamzHeaders{'x-amz-acl'}=$acl if (defined $acl); -$xamzHeaders{'x-amz-copy-source'}=$copySourceObject if (defined $copySourceObject); -$xamzHeaders{'x-amz-copy-source-range'}="bytes=$copySourceRange" if (defined $copySourceRange); - -# try to understand curl args -for (my $i=0; $i<@ARGV; $i++) { - my $arg = $ARGV[$i]; - # resource name - if ($arg =~ /https?:\/\/([^\/:?]+)(?::(\d+))?([^?]*)(?:\?(\S+))?/) { - $host = $1 if !$host; - my $port = defined $2 ? $2 : ""; - my $requestURI = $3; - my $query = defined $4 ? $4 : ""; - debug("Found the url: host=$host; port=$port; uri=$requestURI; query=$query;"); - if (length $requestURI) { - $resource = $requestURI; - } else { - $resource = "/"; - } - my @attributes = (); - for my $attribute ("acl", "delete", "location", "logging", "notification", - "partNumber", "policy", "requestPayment", "response-cache-control", - "response-content-disposition", "response-content-encoding", "response-content-language", - "response-content-type", "response-expires", "torrent", - "uploadId", "uploads", "versionId", "versioning", "versions", "website", "lifecycle") { - if ($query =~ /(?:^|&)($attribute(?:=[^&]*)?)(?:&|$)/) { - push @attributes, uri_unescape($1); - } - } - if (@attributes) { - $resource .= "?" . join("&", @attributes); - } - # handle virtual hosted requests - getResourceToSign($host, \$resource); - } - elsif ($arg =~ /\-X/) { - # mainly for DELETE - $method = $ARGV[++$i]; - } - elsif ($arg =~ /\-H/) { - my $header = $ARGV[++$i]; - #check for host: and x-amz* - if ($header =~ /^[Hh][Oo][Ss][Tt]:(.+)$/) { - $host = $1; - } - elsif ($header =~ /^([Xx]-[Aa][Mm][Zz]-.+): *(.+)$/) { - my $name = lc $1; - my $value = $2; - # merge with existing values - if (exists $xamzHeaders{$name}) { - $value = $xamzHeaders{$name} . "," . $value; - } - $xamzHeaders{$name} = $value; - } - } -} - -die "Couldn't find resource by digging through your curl command line args!" - unless defined $resource; - -my $xamzHeadersToSign = ""; -foreach (sort (keys %xamzHeaders)) { - my $headerValue = $xamzHeaders{$_}; - $xamzHeadersToSign .= "$_:$headerValue\n"; -} - -my $httpDate = POSIX::strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime ); -my $stringToSign = "$method\n$contentMD5\n$contentType\n$httpDate\n$xamzHeadersToSign$resource"; - -debug("StringToSign='" . $stringToSign . "'"); -my $hmac = Digest::HMAC_SHA1->new($secretKey); -$hmac->add($stringToSign); -my $signature = encode_base64($hmac->digest, ""); - - -my @args = (); -push @args, ("-H", "Date: $httpDate"); -push @args, ("-H", "Authorization: AWS $keyId:$signature"); -push @args, ("-H", "x-amz-acl: $acl") if (defined $acl); -push @args, ("-L"); -push @args, ("-H", "content-type: $contentType") if (defined $contentType); -push @args, ("-H", "Content-MD5: $contentMD5") if (length $contentMD5); -push @args, ("-T", $fileToPut) if (defined $fileToPut); -push @args, ("-X", "DELETE") if (defined $doDelete); -push @args, ("-X", "POST") if(defined $postBody); -push @args, ("-I") if (defined $doHead); - -if (defined $createBucket) { - # createBucket is a special kind of put from stdin. Reason being, curl mangles the Request-URI - # to include the local filename when you use -T and it decides there is no remote filename (bucket PUT) - my $data = getCreateBucketData($createBucket); - push @args, ("--data-binary", $data); - push @args, ("-X", "PUT"); -} elsif (defined $copySourceObject) { - # copy operation is a special kind of PUT operation where the resource to put - # is specified in the header - push @args, ("-X", "PUT"); - push @args, ("-H", "x-amz-copy-source: $copySourceObject"); -} elsif (defined $postBody) { - if (length($postBody)>0) { - push @args, ("-T", $postBody); - } -} - -push @args, @ARGV; - -debug("exec $CURL " . join (" ", @args)); -exec($CURL, @args) or die "can't exec program: $!"; - -sub debug { - my ($str) = @_; - $str =~ s/\n/\\n/g; - print STDERR "s3curl: $str\n" if ($debug); -} - -sub getResourceToSign { - my ($host, $resourceToSignRef) = @_; - for my $ep (@endpoints) { - if ($host =~ /(.*)\.$ep/) { # vanity subdomain case - my $vanityBucket = $1; - $$resourceToSignRef = "/$vanityBucket".$$resourceToSignRef; - debug("vanity endpoint signing case"); - return; - } - elsif ($host eq $ep) { - debug("ordinary endpoint signing case"); - return; - } - } - # cname case - $$resourceToSignRef = "/$host".$$resourceToSignRef; - debug("cname endpoint signing case"); -} - - -sub printCmdlineSecretWarning { - print STDERR < { - id => '1ME55KNV6SBTR7EXG0R2', - key => 'zyMrlZUKeG9UcYpwzlPko/+Ciu0K2co0duRM3fhi', - }, - - # corporate account - company => { - id => '1ATXQ3HHA59CYF1CVS02', - key => 'WQY4SrSS95pJUT95V6zWea01gBKBCL6PI0cdxeH8', - }, -); - -\$ chmod 600 $DOTFILE - -Will sleep and continue despite this problem. -Please set up $DOTFILE for future requests. -END_WARNING -} - -sub uri_unescape { - my ($input) = @_; - $input =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg; - debug("replaced string: " . $input); - return ($input); -} - -# generate the XML for bucket creation. -sub getCreateBucketData { - my ($createBucket) = @_; - - my $data = ""; - if (length($createBucket) > 0) { - $data = "$createBucket"; - } - return $data; -} - -# calculates the MD5 header for a string. -sub calculateStringContentMD5 { - my ($string) = @_; - my $md5 = Digest::MD5->new; - $md5->add($string); - my $b64 = encode_base64($md5->digest); - chomp($b64); - return $b64; -} - -# calculates the MD5 header for a file. -sub calculateFileContentMD5 { - my ($file_name) = @_; - open(FILE, "<$file_name") || die "could not open file $file_name for MD5 calculation"; - binmode(FILE) || die "could not set file reading to binary mode: $!"; - my $md5 = Digest::MD5->new; - $md5->addfile(*FILE); - close(FILE) || die "could not close $file_name"; - my $b64 = encode_base64($md5->digest); - chomp($b64); - return $b64; -} diff --git a/dkan/.ahoy/site/.scripts/setup-sublime-xdebug.php b/dkan/.ahoy/site/.scripts/setup-sublime-xdebug.php deleted file mode 100644 index 2e5a6108e..000000000 --- a/dkan/.ahoy/site/.scripts/setup-sublime-xdebug.php +++ /dev/null @@ -1,17 +0,0 @@ - realpath(__DIR__ . '/../.cache'), -)); - -$context = array( - 'path' => getenv('PWD'), - 'url' => getenv('URI'), -); - -echo $twig->render( - 'sublime.project', - $context -); \ No newline at end of file diff --git a/dkan/.ahoy/site/.scripts/site-name.php b/dkan/.ahoy/site/.scripts/site-name.php deleted file mode 100644 index cf92bb15b..000000000 --- a/dkan/.ahoy/site/.scripts/site-name.php +++ /dev/null @@ -1,18 +0,0 @@ -/dev/null) - - if [ -z "$exists" ]; then - git checkout -b $branch - fi - - ahoy build update $tag - git add -A - git commit -m "Update $name data_starter_private to $tag - - AC - ========== - - [ ] tests pass" - - - git push origin $branch --force 2> /dev/null - - hub pull-request -m "Update $name data_starter_private to $tag." 2> /dev/null - - popd -done diff --git a/dkan/.ahoy/site/.templates/config.php.twig b/dkan/.ahoy/site/.templates/config.php.twig deleted file mode 100644 index 67c861bf0..000000000 --- a/dkan/.ahoy/site/.templates/config.php.twig +++ /dev/null @@ -1,7 +0,0 @@ - $tempdir/.htaccess.https - sed -e "/#HTTPS/r $tempdir/.htaccess.https" \ - -e "/#HTTPS/d" config/templates/.htaccess.tpl > $tempdir/.htaccess - else - sed -e "s/^#HTTPS$//g" config/templates/.htaccess.tpl > $tempdir/.htaccess - fi - - cp $tempdir/.htaccess config/.htaccess - - # Transpose config.yml to php - cd dkan/.ahoy/site - composer install - php .scripts/config.php - - new: - usage: Sets new client site from data-starter - cmd: | - set -e - AHOY_CMD_PROXY='' - DIRNAME=${PWD##*/} - if [[ "$DIRNAME" != "data_starter_private" ]]; then - echo "This command should only be use from a data_starter_private working copy" - exit 0 - fi - - if [[ "{{args}}" == "" ]]; then - echo "Arguments cannot be empty. Pass a project name." - exit 0 - fi - - if [ -d ../{{args}} ]; then - ahoy confirm "{{args}} site folder alredy exists." - echo ".. skipping installation"; exit 1; - fi - # No ahoy commands after cd-ing out of project folder. - cd .. - git clone 'git@github.com:NuCivic/data_starter_private.git' {{args}} --depth=1 - cd {{args}} - rm -rf .git build.make build-dkan.make drupal-org-core.make - echo "Site {{args}} initiated at ../{{args}}" - git init . - git add . -A - git commit -m "{{args}} codebase setup" - command -v hub >/dev/null 2>&1 || { echo >&2 "Hub not installed, please create repo, push code and create PR manually."; exit 1; } - hub create -p NuCivic/{{args}} - git push origin master - echo "NuCivic/{{args}} Github repo created" - - dkan: - usage: Upgrades/Downgrades dkan to a certain tag 'ahoy build dkan tag 7.x-1.10' or branch 'ahoy build dkan branch 7.x-1.x'. If no arguments are provided it outputs current dkan version. - cmd: | - set -e - AHOY_CMD_PROXY='' - EMPTY="{{args}}" - if [[ -z "${EMPTY// }" ]]; then - echo $(cat dkan/dkan.info | grep 'version' | cut -d '=' -f2 | sed 's/ //g') - exit 0 - fi - DIRNAME=${PWD##*/} - if [[ "$DIRNAME" != "data_starter_private" ]]; then - echo "This command should only be use to update data_starter_private. Run ahoy build update-data-starter instead" - exit 0 - fi - IFS=' ' read -r -a args <<< "{{args}}" - tag_new=${args[0]} - version_new=${args[1]} - if [[ $tag_new != tag && $tag_new != branch ]]; then - echo "First argument should be either 'tag' or 'branch'" - exit 1 - fi - tag_old='branch' - version_old=$(awk -F " = " '/projects\[dkan\]\[download\]\[branch\]/ {print $2}' build-dkan.make) - if grep -Fq "tag" build-dkan.make - then - tag_old='tag' - version_old=$(awk -F " = " '/projects\[dkan\]\[download\]\[tag\]/ {print $2}' build-dkan.make) - fi - pr_branch="UPDATE_$tag_old-$version_old-TO-$tag_new-$version_new" - if [[ `git branch | grep $pr_branch` ]]; then - git branch -D "$pr_branch" - fi - git checkout -b "$pr_branch" - sed "s/$tag_old/$tag_new/g" build-dkan.make > build-dkan.make.new; rm build-dkan.make; mv build-dkan.make.new build-dkan.make - sed "s/$version_old/$version_new/g" build-dkan.make > build-dkan.make.new; rm build-dkan.make; mv build-dkan.make.new build-dkan.make - if [ "$(ahoy custom | grep remake)" != '' ]; - then - ahoy custom remake - else - ahoy build remake - fi - git add . -A - git commit -m "Updates build-dkan.make from $tag_old $version_old to $tag_new $version_new" - command -v hub >/dev/null 2>&1 || { echo >&2 "Hub not installed, please push code and create PR manually."; exit 1; } - git push -f origin "$pr_branch"; - hub pull-request -m "Updates DKAN from $tag_old $version_old to $tag_new $version_new" >/dev/null 2>&1 - - update-data-starter: - usage: Updates data starter. - cmd: | - # It takes time to grab the entire repo. Checking out to git ignored hidden folder. - if [ ! -d .data_starter_private ]; then - git clone 'git@github.com:NuCivic/data_starter_private.git' .data_starter_private --depth=1 - fi - cd .data_starter_private - git checkout master --force - git reset --hard origin/master - ARGS="{{args}}" - if [[ -z "$ARGS" ]]; then - echo "Please provide a Data Starter release (tag) as an argument. Exiting" - exit 0 - fi - git fetch origin "$ARGS:$ARGS" 2> /dev/null - ARGS=`git rev-parse --verify "$ARGS" 2> /dev/null` - echo $ARGS - if [[ -z "$ARGS" ]]; then - echo "You need to specify a valid Data Starter release (tag) or branch. Exiting" - exit 0 - fi - git checkout $ARGS - cd .. - mv config .config - rm -rf * - # You can rsync now - rsync -av --exclude=.git .data_starter_private/* ./ - rm -rf config - mv .config config - rm -rf .data_starter_private - hub clone NuCivic/nucivic-ahoy nucivic-ahoy-private - if [[ $? = '128' ]]; then - echo "You don't have access to NuCivic private ahoy commands. You can ignore this message" - else - mv nucivic-ahoy-private/config.yml . - rm -rf nucivic-ahoy-private - fi - - upgrade-sites: - usage: ahoy build upgrade-sites $tag - cmd: ahoy cmd-proxy bash dkan/.ahoy/site/.scripts/upgrade-sites.sh diff --git a/dkan/.ahoy/site/ci.ahoy.yml b/dkan/.ahoy/site/ci.ahoy.yml deleted file mode 100644 index 8cd789f52..000000000 --- a/dkan/.ahoy/site/ci.ahoy.yml +++ /dev/null @@ -1,34 +0,0 @@ -ahoyapi: v1 -version: 0.0.0 -commands: - setup: - usage: switchs between ci setups - cmd: | - eval $(ahoy parse config/config.yml) - name=$(ahoy utils name) - - if [ "$name" = 'datastarter' ]; then - echo "Site name datastarter. Going with DKAN base install" - ahoy site reinstall - else - echo "Site name set. Pulling database from s3 bucket" - ahoy utils s3-setup - # Configure https settings. - if [ "$default_stage_file_proxy_origin" != "" ] && [ "$default_stage_file_proxy_origin" != "changeme" ]; then - ahoy utils asset-download-db - else - ahoy utils asset-download - ahoy utils files-link - fi - ahoy utils files-fix-permissions - ahoy drush sql-cli < backups/sanitized.sql - fi - - deploy: - usage: deploys within a ci setup - cmd: | - name=$(ahoy utils name) - eval $(ahoy parse config/config.yml) - ahoy utils truncate-watchdog - ahoy cmd-proxy bash hooks/common/post-code-deploy/drush-env-switch.sh $name local - ahoy drush user-password 1 --password=$private-probo-password diff --git a/dkan/.ahoy/site/composer.json b/dkan/.ahoy/site/composer.json deleted file mode 100644 index 9ec83b319..000000000 --- a/dkan/.ahoy/site/composer.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "nucivic/nucivic-ahoy", - "description": "Nucivic Priviate ahoy commands", - "require": { - "symfony/yaml": "~3.0", - "twig/twig": "~1.0" - }, - "require-dev": { - "symfony/yaml": "~3.0" - }, - "authors": [ - { - "name": "dkinzer", - "email": "dtkinzer@gmail.com" - } - ] -} diff --git a/dkan/.ahoy/site/composer.lock b/dkan/.ahoy/site/composer.lock deleted file mode 100644 index a36408a00..000000000 --- a/dkan/.ahoy/site/composer.lock +++ /dev/null @@ -1,128 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "468a0156cfe5ce7cb1a0cd09a204d2e1", - "packages": [ - { - "name": "symfony/yaml", - "version": "v3.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "368b9738d4033c8b93454cb0dbd45d305135a6d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/368b9738d4033c8b93454cb0dbd45d305135a6d3", - "reference": "368b9738d4033c8b93454cb0dbd45d305135a6d3", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2016-09-25 08:27:07" - }, - { - "name": "twig/twig", - "version": "v1.26.1", - "source": { - "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "a09d8ee17ac1cfea29ed60c83960ad685c6a898d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/a09d8ee17ac1cfea29ed60c83960ad685c6a898d", - "reference": "a09d8ee17ac1cfea29ed60c83960ad685c6a898d", - "shasum": "" - }, - "require": { - "php": ">=5.2.7" - }, - "require-dev": { - "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.26-dev" - } - }, - "autoload": { - "psr-0": { - "Twig_": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - }, - { - "name": "Twig Team", - "homepage": "http://twig.sensiolabs.org/contributors", - "role": "Contributors" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "http://twig.sensiolabs.org", - "keywords": [ - "templating" - ], - "time": "2016-10-05 18:57:41" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [] -} diff --git a/dkan/.ahoy/site/debug.ahoy.yml b/dkan/.ahoy/site/debug.ahoy.yml deleted file mode 100644 index 5bde70b13..000000000 --- a/dkan/.ahoy/site/debug.ahoy.yml +++ /dev/null @@ -1,13 +0,0 @@ -ahoyapi: v1 -version: 0.0.0 -commands: - setup-sublime: - usage: Setup project for sublime xdebugging - cmd: | - mkdir -p .cache - cd dkan/.ahoy/site - composer install - cd .. - PROJECT=`pwd` - PROJECT=$(basename "$PROJECT") - PWD=`pwd` URI=`ahoy docker url` php ./dkan/.ahoy/site/.scripts/setup-sublime-xdebug.php > $PROJECT.sublime-project diff --git a/dkan/.ahoy/site/launch-checklist.ahoy.yml b/dkan/.ahoy/site/launch-checklist.ahoy.yml deleted file mode 100644 index 130af5017..000000000 --- a/dkan/.ahoy/site/launch-checklist.ahoy.yml +++ /dev/null @@ -1,296 +0,0 @@ -ahoyapi: v1 -version: 0.0.0 -commands: - run: - usage: Runs the entire checklist to an alias. - cmd: | - set -e - alias={{args}} - alias=${alias#@} - echo "Item, Result, Fix" - ahoy remote launch-checklist file-permissions $alias - ahoy remote launch-checklist security-review $alias - ahoy remote launch-checklist modules-disabled $alias - ahoy remote launch-checklist registration-required $alias - ahoy remote launch-checklist db-updates-pending $alias - ahoy remote launch-checklist modules-up-to-date $alias - ahoy remote launch-checklist pathauto-patterns $alias - ahoy remote launch-checklist cron-running $alias - ahoy remote launch-checklist role-permissions $alias - ahoy remote launch-checklist dummy-content $alias - ahoy remote launch-checklist performance-settings $alias - ahoy remote launch-checklist housekeeping $alias - - file-permissions: - usage: Checks that file permissions are set properly. - cmd: | - alias={{args}} - alias=${alias#@} - ahoy cmd-proxy drush @$alias -q cc drush - # Checks file directory permissions - PERMISSIONS=`ahoy cmd-proxy drush @$alias ssh \"ls -la ../assets/sites\" | grep default` - PERMISSIONS=`echo $PERMISSIONS | awk '{ print $1 }'` - OUTPUT="Files directory permissions" - if [[ "$PERMISSIONS" == "drwxrwx---" ]]; then - echo "$OUTPUT, PASSES," - else - echo "$OUTPUT, FAILS, Permissions on files directory should be drwxrwx--- not $PERMISSIONS" - fi - - security-review: - usage: Runs the whole security-review checks. - cmd: | - alias={{args}} - alias=${alias#@} - # Detects if the module is present in the codebase - MODULES_AVAILABLE=`ahoy cmd-proxy drush @$alias pml --format=json` - MODULES_AVAILABLE=`echo "$MODULES_AVAILABLE" | grep security_review` - OUTPUT="Security Review module available" - if [[ "$MODULES_AVAILABLE" == "" ]];then - echo "$OUTPUT, FAILS, Please add security_review to the codebase" - exit 0; - else - echo "$OUTPUT, PASSES," - fi - # Runs security_review checks - ahoy cmd-proxy drush @$alias -y -q en security_review - ahoy cmd-proxy drush @$alias -q cc drush - SECURITY_REVIEW_NO_RESULTS=`ahoy cmd-proxy drush @$alias security-review` - SECURITY_REVIEW_WITH_RESULTS=`ahoy cmd-proxy drush @$alias security-review --results` - ahoy cmd-proxy drush @$alias -y -q dis security_review - # Output passes - NOERRORS=`echo "$SECURITY_REVIEW_NO_RESULTS" | grep -v error` - printf '%s\n' "$NOERRORS" | while IFS= read -r line - do - line=`echo $line | sed 's/\[success\]//g'` - line=`echo $line | sed 's/\.//g'` - line=`echo $line | xargs` - echo "$line, PASSES," - done - # Output fails - ERRORS=`echo "$SECURITY_REVIEW_WITH_RESULTS" | grep -v success` - ERRORS=`echo "$ERRORS" | tr '\t' '*' | sed -e 's/\*/\* /g' | sed -e 's/\: /\:/g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n\*//g'` - printf '%s\n' "$ERRORS" | while IFS= read -r line - do - if [ ! -z "$line" ]; then - D="\[error\]" - echo $line | sed -e 's/'"$D"'/, FAILS, /g' | sed -e 's/\. //g' | tr -s ' ' - fi - done - - modules-disabled: - usage: Checks that certain modules are modules-disabled - cmd: | - alias={{args}} - alias=${alias#@} - MODULES_AVAILABLE=`ahoy cmd-proxy drush @$alias pml` - MODULES_THAT_NEED_TO_BE_DISABLED="(php),(devel),(views_ui),(field_ui),(maillog),(dblog)" - IFS=, read -a MODULES_THAT_NEED_TO_BE_DISABLED <<<"$MODULES_THAT_NEED_TO_BE_DISABLED" - for module in "${MODULES_THAT_NEED_TO_BE_DISABLED[@]}" - do - OUTPUT="$module needs to be disabled" - MODULE_ENABLED=`echo "$MODULES_AVAILABLE" | grep -e "$module" | grep -e "Enabled"` - if [ -z "$MODULE_ENABLED" ]; then - echo "$OUTPUT, PASSES," - else - echo "$OUTPUT, FAILS, Set this module to be temporary enabled only on development environments using \$conf['features_master_temp_enabled_modules']" - fi - done - - registration-required: - usage: Checks that registration is required - cmd: | - alias={{args}} - alias=${alias#@} - export VARIABLES=`ahoy cmd-proxy drush @$alias vget` - # Check user_register - export VARIABLE_NAME="user_register"; export VARIABLE_DEFAULT="2"; export VARIABLE_EXPECTED="2" - ahoy remote launch-checklist check-variable - # Check user email verification - export VARIABLE_NAME="user_email_verification"; export VARIABLE_DEFAULT="1"; export VARIABLE_EXPECTED="1" - ahoy remote launch-checklist check-variable - - db-updates-pending: - usage: Checks that there are not pending drupal db db-updates-pending - cmd: | - alias={{args}} - alias=${alias#@} - UPDATE_DB_PENDING=`drush @$alias updb -n` - OUTPUT="No Database updates are needed" - if [[ "$UPDATE_DB_PENDING" == "No database updates required" ]];then - echo "$OUTPUT, PASSES," - else - echo "$OUTPUT, FAILS, please run drush updb. You can include the action as part of your deployment process as well." - fi - - modules-up-to-date: - usage: Checks that modules are up to date - cmd: | - alias={{args}} - alias=${alias#@} - UPDATES=`drush @$alias ups --format=csv | grep -v "Checking available update" | grep -v "Proposed version" | grep -v "Unknown" | grep -v "No release history"` - SECURITY_UPDATES=`echo "$UPDATES" | grep -w "SECURITY UPDATE available"` - UPDATES=`echo "$UPDATES" | grep -v "SECURITY UPDATE available"` - printf '%s\n' "$SECURITY_UPDATES" | while IFS= read -r line - do - if [ ! -z "$line" ]; then - IFS=, read -a line <<<"$line" - echo "${line[0]} is up to date, FAILS, Your site is using ${line[1]}. ${line[2]} update has SECURITY fixes. Please upgrade." - fi - done - printf '%s\n' "$UPDATES" | while IFS= read -r line - do - if [ ! -z "$line" ]; then - IFS=, read -a line <<<"$line" - echo "${line[0]} is up to date, FAILS, Your site is using ${line[1]}. ${line[2]} is available" - fi - done - - pathauto-patterns: - usage: Checks that patterns are set for DKAN node bundles - cmd: | - alias={{args}} - alias=${alias#@} - export VARIABLES=`ahoy cmd-proxy drush @$alias vget` - # Check pathauto update action - export VARIABLE_NAME="pathauto_update_action"; export VARIABLE_DEFAULT="2"; export VARIABLE_EXPECTED="1" - ahoy remote launch-checklist check-variable - # Check patterns - BASE_PATTERN="pathauto_TYPE_pattern" - PATTERN_CHECKS="node_dataset,node_resource,node_dkan_data_story,node_group,node_page,node" - IFS=, read -a PATTERN_CHECKS <<<"$PATTERN_CHECKS" - for pattern in "${PATTERN_CHECKS[@]}" - do - check=${BASE_PATTERN/"TYPE"/"$pattern"} - check=`echo "$VARIABLES" | grep "$check"` - if [ ! -z "$check" ];then - echo "Pathauto $pattern set correctly, PASSES, $check" - else - echo "Pathauto $pattern set correctly, FAILS, Please set a pattern for $pattern" - fi - done - - cron-running: - usage: Checks that cron has been running properly - cmd: | - alias={{args}} - alias=${alias#@} - NOW=$(date +%s) - export VARIABLES=`ahoy cmd-proxy drush @$alias vget` - # Check cron method - export VARIABLE_NAME="cron_safe_threshold"; export VARIABLE_DEFAULT="0"; export VARIABLE_EXPECTED="0" - ahoy remote launch-checklist check-variable - # Check time since last cron run - LAST_CRON_RUN=`echo "$VARIABLES" | grep "cron_last"` - LAST_CRON_RUN=${LAST_CRON_RUN/"cron_last: "/""} - TIME_SINCE_LAST_CRON_RUN=`expr $NOW - $LAST_CRON_RUN` - TOLLERABLE_TIME_SPREAD_BETWEEN_CRONS=10000 - if [ "$TIME_SINCE_LAST_CRON_RUN" -gt "$TOLLERABLE_TIME_SPREAD_BETWEEN_CRONS" ];then - echo "Cron has been running, FAILS, more than $TOLLERABLE_TIME_SPREAD_BETWEEN_CRONS seconds have passed since last cron run" - else - echo "Cron has been running, PASSES, Cron last run was $TIME_SINCE_LAST_CRON_RUN seconds ago" - fi - - role-permissions: - usage: Checks that permissions are properly set - cmd: | - alias={{args}} - alias=${alias#@} - ROLES=`ahoy cmd-proxy drush @$alias rls` - # Grasp IDS and query permissions for roles - AUTH_ID=`echo "$ROLES" | grep "anonymous user" | awk '{ print $1}'` - ANON_ID=`echo "$ROLES" | grep "authenticated user" | awk '{ print $1}'` - AUTH_PERMISSIONS=`ahoy cmd-proxy drush @$alias rls $AUTH_ID | grep -v "Permission"` - ANON_PERMISSIONS=`ahoy cmd-proxy drush @$alias rls $ANON_ID | grep -v "Permission"` - # Check that anon users can access content - ANON_CAN_ACCESS_CONTENT=`echo "$ANON_PERMISSIONS" | grep "access content"` - if [ -z "$ANON_CAN_ACCESS_CONTENT" ];then - echo "Anon users can access content, FAILS, Please give the anon role the \"access content\" permission" - else - echo "Anon users can access content, PASSES," - fi - # Check that the auth role is not missing permissions granted to the anon role - echo "$AUTH_PERMISSIONS" | sed 's/[[:space:]]*$//' > auth_permissions.txt - echo "$ANON_PERMISSIONS" | sed 's/[[:space:]]*$//' > anon_permissions.txt - AUTH_ANON_DIFF=`diff auth_permissions.txt anon_permissions.txt | grep "<"` - rm auth_permissions.txt anon_permissions.txt - if [ ! -z "$AUTH_ANON_DIFF" ]; then - AUTH_ANON_DIFF=`echo $AUTH_ANON_DIFF | xargs` - echo "Auth users are not missing anon users permissions, FAILS, $AUTH_ANON_DIFF" - else - echo "Auth users are not missing anon users permissions, PASSES," - fi - - dummy-content: - usage: Checks that there is no dummy content set - cmd: | - alias={{args}} - alias=${alias#@} - # Check nodes create by the admin user - ADMIN_SQL_ID=`ahoy cmd-proxy drush @$alias sql-query "'select * from users'" | grep admin | awk '{print $1}'` - ADMIN_NODES=`ahoy cmd-proxy drush @$alias sql-query "'select * from node where node.uid=$ADMIN_SQL_ID'" | awk '{ print $1}'` - OUTPUT="No content created by admin user" - if [ ! -z "$ADMIN_NODES" ];then - ADMIN_NODES=`echo "$ADMIN_NODES" | sed 's/^/node\//' | xargs` - echo "$OUTPUT, FAILS, All these nodes were created by the admin user: $ADMIN_NODES" - else - echo "$OUTPUT, PASSES," - fi - # Check nodes that have dummy or test in the title - DUMMY_MATCHES="test\|dummy" - DUMMY_NODES=`ahoy cmd-proxy drush @$alias sql-query "'select nid,title from node'"` - DUMMY_NODES=`echo "$DUMMY_NODES" | grep -i "$DUMMY_MATCHES"` - OUTPUT="No nodes with dummy or test in the title" - if [ ! -z "$DUMMY_NODES" ];then - DUMMY_NODES=`echo $DUMMY_NODES | awk '{print $1}' | sed 's/^/node\//' | xargs` - echo "$OUTPUT, FAILS, All these nodes appear to by dummy content: $DUMMY_NODES" - else - echo "$OUTPUT, PASSES," - fi - - performance-settings: - usage: Check that certain performance tweaks are in place - cmd: | - alias={{args}} - alias=${alias#@} - export VARIABLES=`ahoy cmd-proxy drush @$alias vget` - export VARIABLE_NAME="error_level"; export VARIABLE_DEFAULT="0"; export VARIABLE_EXPECTED="0" - ahoy remote launch-checklist check-variable - export VARIABLE_NAME="cache"; export VARIABLE_DEFAULT="0"; export VARIABLE_EXPECTED="1" - ahoy remote launch-checklist check-variable - export VARIABLE_NAME="preprocess_css"; export VARIABLE_DEFAULT="0"; export VARIABLE_EXPECTED="1" - ahoy remote launch-checklist check-variable - export VARIABLE_NAME="preprocess_js"; export VARIABLE_DEFAULT="0"; export VARIABLE_EXPECTED="1" - ahoy remote launch-checklist check-variable - export VARIABLE_NAME="cache_lifetime"; export VARIABLE_DEFAULT="0"; export VARIABLE_EXPECTED="0" - ahoy remote launch-checklist check-variable - export VARIABLE_NAME="page_cache_maximum_age"; export VARIABLE_DEFAULT="0"; export VARIABLE_EXPECTED="900" - ahoy remote launch-checklist check-variable - - housekeeping: - cmd: | - alias={{args}} - alias=${alias#@} - # Check that CHANGELOG files are being swapped - CHANGELOG_FILES=`ahoy cmd-proxy drush @$alias ssh \"find . -type f -name CHANGELOG.txt\"` - OUTPUT="CHANGELOG.txt files have been swapped" - if [[ ! -z "$CHANGELOG_FILES" ]];then - CHANGELOG_FILES=`echo $CHANGELOG_FILES | xargs` - echo "$OUTPUT, FAILS, The following files have been found $CHANGELOG_FILES" - else - echo "$OUTPUT, PASSES," - fi - - check-variable: - hidden: true - usage: Check a specific VARIABLE - cmd: | - # Check variable value - VARIABLE_CHECK=`echo "$VARIABLES" | grep -w "$VARIABLE_NAME"` - VARIABLE_CHECK=${VARIABLE_CHECK/"$VARIABLE_NAME: "/""} - VARIABLE_CHECK=${VARIABLE_CHECK:-$VARIABLE_DEFAULT} - if [[ "$VARIABLE_CHECK" != "$VARIABLE_EXPECTED" ]]; then - echo "$VARIABLE_NAME set correctly, FAILS, Value is $VARIABLE_CHECK. Please set \$conf['$VARIABLE_NAME'] to $VARIABLE_EXPECTED (or matching constant) in settings.php" - else - echo "$VARIABLE_NAME set correctly, PASSES, Value is $VARIABLE_CHECK" - fi diff --git a/dkan/.ahoy/site/remote.ahoy.yml b/dkan/.ahoy/site/remote.ahoy.yml deleted file mode 100644 index 4976676bf..000000000 --- a/dkan/.ahoy/site/remote.ahoy.yml +++ /dev/null @@ -1,46 +0,0 @@ -ahoyapi: v1 -version: 0.0.0 -commands: - reinstall: - usage: Reinstall the site from scratch (dkan + custom_config + environment). - cmd: | - set -e - alias={{args}} - alias=${alias#@} - echo $alias - ahoy drush @$alias cc drush - ahoy drush @$alias -y si dkan - ahoy drush @$alias cc drush - ahoy drush @$alias -y en custom_config environment devinci - ahoy remote deploy $alias - ahoy remote update-indexes $alias - - deploy: - usage: Standarized deploy process for Nucivic Data. - cmd: | - set -e - alias={{args}} - alias=${alias#@} - ahoy drush @$alias dl -n registry_rebuild - ahoy drush @$alias cc drush - target_env=`ahoy drush @$alias php-eval "'echo ENVIRONMENT;'"` - ahoy drush @$alias cc drush - ahoy drush @$alias -y fr --force custom_config - ahoy drush @$alias env-switch $target_env --force - ahoy drush @$alias cc drush - ahoy drush @$alias rr - - update-indexes: - usage: Updates search api indexes - cmd: | - set -e - alias={{args}} - alias=${alias#@} - ahoy drush @$alias cc drush - ahoy drush @$alias search-api-index datasets - ahoy drush @$alias search-api-index groups_di - ahoy drush @$alias search-api-index stories_index - - launch-checklist: - usage: A series of commands to perform a launch-checklist - import: dkan/.ahoy/site/launch-checklist.ahoy.yml diff --git a/dkan/.ahoy/site/site.ahoy.yml b/dkan/.ahoy/site/site.ahoy.yml deleted file mode 100644 index 4a8e0a0d8..000000000 --- a/dkan/.ahoy/site/site.ahoy.yml +++ /dev/null @@ -1,25 +0,0 @@ -ahoyapi: v1 -version: 0.0.0 -commands: - up: - usage: Start up the dkan site - cmd: | - if [ "$AHOY_CMD_PROXY" == "DOCKER" ]; then - ahoy docker up - fi - ahoy utils setup {{args}} - ahoy ci setup - ahoy ci deploy - - test: - usage: Run the tests for the dkan site - cmd: | - ahoy dkan test - - reinstall: - usage: Reinstall the site from scratch (dkan + custom_config + environment). - cmd: | - ahoy dkan reinstall - ahoy drush -y en custom_config environment devinci - ahoy drush env-switch --force local - diff --git a/dkan/.ahoy/site/tools.ahoy.yml b/dkan/.ahoy/site/tools.ahoy.yml deleted file mode 100644 index 2559b547b..000000000 --- a/dkan/.ahoy/site/tools.ahoy.yml +++ /dev/null @@ -1,37 +0,0 @@ -ahoyapi: v1 -version: 0.0.0 -commands: - dnsmasq: - usage: Setup dnsmasq to avoid hitting production servers from your local accidentaly - cmd: | - PLATFORM=`uname` - if [ "$PLATFORM" == "Darwin" ] - then - brew install dnsmasq - # Prepare directories - mkdir -pv $(brew --prefix)/etc/ - sudo mkdir -pv /etc/resolver - # Prepare dnsmasq conf - CONFIG_PATH="$(brew --prefix)/etc/dnsmasq.conf" - if [ -f "$CONFIG_PATH" ] - then - CONFIG_SET=`cat $CONFIG_PATH | grep 'search-service.hosting.acquia.com'` - else - CONFIG_SET='' - fi - if [ -z "$CONFIG_SET" ] - then - echo 'address=/.search-service.hosting.acquia.com/127.0.0.1' > $CONFIG_PATH - else - echo "DNSmasq configuration already set" - fi - # Prepare resolver conf - sudo rm -rf /etc/resolver/search-service.hosting.acquia.com - sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/search-service.hosting.acquia.com' - # Launch at startup - sudo rm -rf /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist - sudo cp -v $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons - sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist - # Restart - sudo launchctl list - fi diff --git a/dkan/.ahoy/site/utils.ahoy.yml b/dkan/.ahoy/site/utils.ahoy.yml deleted file mode 100644 index 40f65cba4..000000000 --- a/dkan/.ahoy/site/utils.ahoy.yml +++ /dev/null @@ -1,232 +0,0 @@ -ahoyapi: v1 -version: 0.0.0 -commands: - setup: - usage: Setups sites settings - hide: true - cmd: | - # Create an array with the arguments that were input. - ARGS=( {{args}} ) - rm -f assets/sites/default/settings.docker.php - rm -f assets/sites/default/settings.local.php - ahoy cmd-proxy bash ./dkan/.ahoy/site/.scripts/drush.alias.sh - - if [ ! -f assets/sites/default/settings.php ] && [ -f assets/sites/default/default.settings.php ]; then - cp assets/sites/default/default.settings.php assets/sites/default/settings.php - fi - - if [ "$CI" = "true" ]; then - # Drush alias points to /var/www/docroot so we need this here. - sudo ln -sf $HOME/$CIRCLE_PROJECT_REPONAME/docroot /var/www/docroot - fi - - if [ "$AHOY_CMD_PROXY" == "DOCKER" ]; then - cp assets/sites/default/settings.docker.demo.php assets/sites/default/settings.docker.php - ahoy docker up - elif [ "${#ARGS[@]}" -ne 0 ]; then - for i in "${ARGS[@]}"; do - case "$i" in - --db-user=*) - DB_USER="${i#*=}" - ;; - --db-pass=*) - DB_PASS="${i#*=}" - ;; - --db-host=*) - DB_HOST="${i#*=}" - ;; - --db-port=*) - DB_PORT="${i#*=}" - ;; - --db-name=*) - DB_NAME="${i#*=}" - ;; - *) - echo "not recognized flag or param ${i#*=}" - exit 1 - ;; - esac - done - sed \ - -e s/#DB_HOST/$DB_HOST/g \ - -e s/#DB_USER/$DB_USER/g \ - -e s/#DB_PASS/$DB_PASS/g \ - -e s/#DB_PORT/$DB_PORT/g \ - -e s/#DB_NAME/$DB_NAME/g \ - assets/sites/default/settings.local.demo.php > assets/sites/default/settings.local.php - echo "A settings.local.php file was created at assets/sites/default/settings.local.php with your db credentials." - else - cp assets/sites/default/settings.local.demo.php assets/sites/default/settings.local.php - echo "A settings.local.php file was created at assets/sites/default/settings.local.php, but you need you add your own db credentials." - fi - - mysql-dump-sanitized: - usage: Creates a dump of a sanitized and pruned version of the site db - cmd: | - ahoy cmd-proxy exec mkdir -p backups - ahoy drush sql-dump > backups/unsanitized.sql - ahoy drush sql-cli < dkan/.ahoy/site/.mysqlscripts/sanitize.sql | grep -v concat > backups/truncate.sql - ahoy drush sql-cli < backups/truncate.sql - rm backups/truncate.sql - ahoy drush sql-dump > backups/sanitized.sql - ahoy drush -y sql-drop - ahoy drush sql-cli < backups/unsanitized.sql - - mysql-prune: - usage: Prunes datasets and resources from site database - hide: true - cmd: | - ahoy drush php-script dkan/.ahoy/site/.scripts/prune-database.php - - name: - usage: Utility function to determine the site name. - cmd: | - # TODO: use config/config.yml instead - if [ -s assets/drush/aliases.local.php ]; then - ahoy cmd-proxy php -f dkan/.ahoy/site/.scripts/site-name.php - else - echo "Site name not set. Type the alias followed by [ENTER]:" - read ALIAS - cat assets/drush/datastarter.aliases.drushrc.php | sed "s/data_starter/$ALIAS/g" > assets/drush/aliases.local.php - fi - hide: true - - asset-download: - usage: Download database and files assets from S3 to local backups folder. - cmd: | - ahoy utils asset-download-db - ahoy utils asset-download-files - hide: true - - asset-download-db: - usage: Download DB backup asset from S3 to local backups folder. - cmd: | - ahoy utils asset-download-dbs sanitized - - asset-download-db-unpruned: - usage: Download unpruned DB backup asset from S3 to local backups folder. - cmd: | - ahoy utils asset-download-dbs unpruned - - asset-download-dbs: - hide: true - usage: Download DB backup asset from S3 to local backups folder. - cmd: | - eval $(ahoy parse config/config.yml) - ahoy cmd-proxy exec mkdir -p backups - site=$(ahoy utils name) - db={{args}} - asset="$private_aws_scrubbed_data_url/$site.prod.$db.sql.gz" - LC_TIME=en_US.UTF-8 perl dkan/.ahoy/site/.scripts/s3curl.pl --id local $asset > backups/$db.sql.gz - echo "" - echo "Unpacking the $db database." - echo "" - ahoy cmd-proxy gunzip backups/$db.sql.gz -f - cp -f backups/$db.sql backups/last_install.sql - - asset-download-files: - usage: Download files backup asset from S3 to local backups folder. - cmd: | - eval $(ahoy parse config/config.yml) - ahoy cmd-proxy exec mkdir -p backups - site=$(ahoy utils name) - asset="$private_aws_scrubbed_data_url/$site.prod.files.tar.gz" - LC_TIME=en_US.UTF-8 perl dkan/.ahoy/site/.scripts/s3curl.pl --id local $asset > backups/$site.prod.files.tar.gz - echo "" - echo "Unpacking the files asset." - echo "" - tar xvzf backups/$site.prod.files.tar.gz - hide: true - - asset-upload: - usage: Upload database and files assets to dedicated S3 bucket. - cmd: | - ahoy utils asset-db-upload - ahoy utils asset-files-upload - hide: true - - asset-upload-db: - usage: Upload database asset to dedicated S3 bucket. - cmd: echo "TODO:// Implement asset-upload-db feature." - hide: true - - asset-upload-files: - usage: Upload files asset to dedicated S3 bucket. - cmd: echo "TODO:// Implement asset-upload-files feature." - hide: true - - s3-setup: - usage: Utility script for adding aws s3curl credentials. - cmd: bash dkan/.ahoy/site/.scripts/s3-setup.sh - hide: true - - self-update: - usage: Utility function for self updating this repo. - cmd: | - ahoy dkan self-update - rm -fR dkan/.ahoy/site - git clone 'git@github.com:nucivic/dkan/.ahoy/site' --depth=1 - rm -rf dkan/.ahoy/site/.git - rm -rf dkan/.ahoy/site/.gitignore - hide: true - - files-link: - usage: Links files. - cmd: ahoy cmd-proxy ln -s ../../../$(ahoy utils name).prod.files/files docroot/sites/default/files - hide: true - - files-fix-permissions: - usage: Fix the permissiosn for the files. - cmd: | - ahoy cmd-proxy bash ./dkan/.ahoy/site/.scripts/site.files-fix-permissions.sh - hide: true - - test: - usage: Run the tests for site - cmd: | - # Store the arguments as a bash array. - ARGS=( "{{args}}" ) - BEHAT_FOLDER=tests - ALT_CONFIG_FILE="behat.local.yml" - # Crazy bash to get rid of the carriage return. (docker issue) - BEHAT_ENV=$(echo $(ahoy cmd-proxy printenv HOSTNAME) | tr -d "\r" ) - SKIP_COMPOSER_FLAG="--skip-composer" - if [[ ! "${ARGS[@]}" == *"$SKIP_COMPOSER_FLAG"* ]]; then - echo "Installing behat dependencies.." - ahoy cmd-proxy "cd $BEHAT_FOLDER && composer install --prefer-source --no-interaction" - else - echo "Skipping composer install.." - ARGS=( "${ARGS[@]/$SKIP_COMPOSER_FLAG}" ) - fi - if [ -f "$BEHAT_FOLDER/$ALT_CONFIG_FILE" ]; then - echo "Using $BEHAT_FOLDER/$ALT_CONFIG_FILE .." - CONFIG=" -c $ALT_CONFIG_FILE" - elif [ "$BEHAT_ENV" == "cli" ]; then - echo "Using behat.docker.yml config .." - CONFIG=" -c behat.docker.yml" - elif [ "$CI" == "true" ]; then - echo "Using behat.circleci.yml config .." - CONFIG=" -c behat.circleci.yml" - else - echo "$BEHAT_ENV" - echo "Using behat.yml .." - fi - ahoy cmd-proxy "cd $BEHAT_FOLDER && bin/behat $CONFIG ${ARGS[@]}" - - truncate-watchdog: - usage: Truncates the watchdog table. - hide: true - cmd: | - echo "truncate watchdog" | ahoy dkan sqlc; - - fail-when-bad-disable: - usage: Kill the build if modules were incorrectly disabled. - hide: true - cmd: | - error=`echo "select message, variables from watchdog where type = 'custom_config_disable'" | ahoy dkan sqlc` - if [ "$error" ]; - then - echo $error - exit 1 - fi - diff --git a/dkan/.ahoy/utils.ahoy.yml b/dkan/.ahoy/utils.ahoy.yml index 2f864f73e..f354501eb 100644 --- a/dkan/.ahoy/utils.ahoy.yml +++ b/dkan/.ahoy/utils.ahoy.yml @@ -3,10 +3,14 @@ version: 0.0.0 commands: confirm: cmd: | - read -r -p "{{args}} [y/N] " response - if [ "$response" = y ] || [ "$response" = Y ]; - then + if [[ "{{args}}" == *--yes* ]]; then true else - false + read -r -p "{{args}} [y/N] " response + if [ "$response" = y ] || [ "$response" = Y ]; + then + true + else + false + fi fi diff --git a/dkan/.gitattributes b/dkan/.gitattributes new file mode 100644 index 000000000..437485e51 --- /dev/null +++ b/dkan/.gitattributes @@ -0,0 +1,2 @@ +CHANGELOG merge=union + diff --git a/dkan/CHANGELOG.txt b/dkan/CHANGELOG.txt index a455de0ea..09e772d9d 100644 --- a/dkan/CHANGELOG.txt +++ b/dkan/CHANGELOG.txt @@ -1,3 +1,49 @@ +7.x-1.14.x +---------- + - #1946 Fix Datastore API limit not applying consistently. + - #2109 Fix ODSM language token to solve validation errors. + - #2019 DKAN Workflow: Fix 'My Drafts' view to restore content to original user after rejection. + - #1970 Adds topics to harvested datasets on migration. + - #1975 Add landingPage to data.json feed. + - #1967 Added search title to /search panels. + - #1997 Recline.view.nvd3.js: Fixed tooltips that were not being displayed when using some percentage formats. + - #1988 Count and delete resources on Harvest source deletion. + - #1951 Fixed display of number of Groups a user belongs to on the user profile page. + - #1968 Fixed "Reset" button on search page to also resets facets. + - #1985 Add documentation for resource behavior on harvested datasets. + - #1907 Added back TAB delimiter option for datastore imports. + - #1955 Update ahoy docker tooling for local environment usecase. + - #1903 Add support for tab-delimited files (TSV) in resources/recline preview. + - #2001 Improve REST API documentation. + - #1991 Fix host IP replacement on script used to recconect the MySQL container. + - #1942 DevOps: Restore drush commands to deal with orphaned resources. + - #1943 Update tests to be more compatible with client sites, multiple testing and devops improvements. + - #1962 Recline.view.nvd3.js: Fixed display of data with zero as values. + - #1888 Added validation on axis tick settings on visualization_entity. + - #1725 Fix `ahoy dkan uli` output login link. + - #1881 Fix yaml syntaxt to make it standard. + - #1853 Update chart documentation. + - #1839 Add help text and improve UI on the chart form for better clarity. + - #1827 Remove option to import TABed CSV files into datastore. + - #1807 Add admin_views module for enhanced content and file filtering. + - #1990 DevOps: Automatically populate required fields when running behat tests. + - #1938 DevOps: Allow behat tests to be skipped in circle. + - #1842 Add help text to explain the pager on data previews. + - #1542 Creates migration on harvest source import. + +7.x-1.13.7 2017-08-22 +--------------------- + - #2064 Update entityreference to 1.15 + - #2061 Update views to 3.17 + - #2060 Update tests to adjust to client customizations. + - #2060 Removed unused modules menu_token and remote_file_source from drupal-org.make + +7.x-1.13.8 +---------- + - #2058 Improve messages displayed when creating a harvest source. + - #2058 Fix harvest bug when filtering by a key that has 0 matches. + - #2102 Hide toggle buttons inside preview embeds. + 7.x-1.13.7 2017-08-22 --------------------- - #2064 Update entityreference to 1.15 @@ -25,7 +71,7 @@ - #2003 Fix dkan_migrate_base warning: wrong type supplied to foreach. - #1963 Allow Behat dkanExtension to handle custom fields via devel generate - #1938 Allow skipping of features test via config - - #1970 DevOps: Automatically populate required fields when running behat tests. + - #1970 Automatically populate required fields when running behat tests. 7.x-1.13.4 2017-06-30 --------------------- @@ -67,7 +113,7 @@ - #1876 Removed hard coded colors in the menu.scss file. - #1825 Adapt the 'dataQuality' input value druing POD harvest. - #1817 Load empty cells as null in fast import. - - #1846 Adds a hook_update to exclude the data dictionary field from using the markdown toolbar. + - #1846 Adds a hook_update to exclude the data dictionary field from using the markdown toolbar. - #1813 Update the groups page view to sort alphabetically rather than by post date. - NuCivic/recline#89 Only load previews for resources using files; API/website links should always display iframe. - #1841 Fixed mis-named function on dkan_dataset_content_types.api.php @@ -78,13 +124,14 @@ - #1828 Field Frequency Harvest POD integration is missing support for "irregular" value. - #1820 Use "accessURL" during resources harvest if "downloadURL" field is not available. - #1852 Allow the use of multi-polygonal data for Dataset Spatial field. - - #1857 Fixed publishing options not accessible when dkan_workflow is enabled. + - #1857 Fixed publishing options not accessible when dkan_workflow is enabled. + - #1932 Fix windows delimiter for datastore_fast_import. 7.x-1.13.3 2017-04-18 --------------------- - #1863 Update restws module to v2.7 - #1859 Fixed update hooks to correctly set jquery version and remove old modified source date field - - #1864 Update media to 2.0 and remove patch 2534724. + - #1864 Update media to 2.0 and remove patch 2534724. - #1829 Fixed missing properties on warning message during datajson harvest cache. - #1802 Better support for Issued and Updated dataset properties from harvested sources. - #1821 Remove redundant CSS load in dkan_dataset. @@ -100,7 +147,7 @@ - #1811 Apply patches to the rules module that can prevent unnecessary DB lockouts. 7.x-1.13.2 2017-03-16 ----------------------- +--------------------- - #1803 Fix broken access to featured groups sort order view. - #1796 Fix Harvest support for contact name and contact email. - #1795 Update front page test on topics.feature with @customizable. @@ -119,8 +166,9 @@ - #1776 Fix 500 errors when linking or uploading geojson files in resources. - #1767 Better handling of empty values by datastore_api. Also see NuCivic/feeds_flatstore_processor#9 -7.x-1.13 --------------------------- + +7.x-1.13 2017-02-28 +------------------- - #1719 Added site details to settings nuboot_radix to allow change site name, slogan, e-amail address for site manager. - #1717 Upgrading Drupal to 7.54 - #1705 Added css for chart visualizaitons, fixes issue in IE. @@ -205,10 +253,12 @@ - Fixed CSV column validation on visualization entity. - Fixed retrieve of version information on chroma.js. - #1678 Add patch to fix panopoly_widgets overrides OOB. + DKAN Datastore: - #1387 Added DKAN Datastore module into DKAN Core. - #1599 Greatly expand the datastore API to support aggregation functions, better joins, multiple queries. See dkan_datastore_api's README file. - #1599 Fixed bugs when running the datastore via cron. + DKAN Harvest: - #1676 Harvested content is published even if dkan_workflow is enabled. - #1287 Added DKAN Harvest module into DKAN Core. @@ -231,9 +281,11 @@ DKAN Harvest: - Improved PHP Unit tests. - #1468 Add support "Compound" fields on Filters/Overrides/Excludes/Default in DKAN Harvest. - #1488 Replace field notes by field body in harvest source content type. + DKAN Migrate Base: - #1387 Added DKAN Migrate Base module into DKAN Core. - #1462 Removed row from migration map table when a dataset is deleted. + DKAN Workflow: - Add patch for workbench_moderation to avoid php shutdown function errors. - #1690 Added patch for workbench_moderation: Invalid argument supplied for foreach() 2360973. @@ -245,6 +297,7 @@ DKAN Workflow: - #1481 Updated workbench_email from 3.9 to 3.11 - #1667 Fixed admin menu source when dkan_workflow is enabled. - #1663 Moved workbench links from dkan_sitewide_menu to dkan_workflow. + DKAN Dataset: - #1696 Disable/uninstall dkan_dataset_api if enabled because it is deprecated in favor open_data_schema_map. - Leaflet draw widget usability improvements @@ -283,6 +336,7 @@ DKAN Topics: - #1486 Make the icon field required if the icon type is set to 'font'. - #1656 Fix topics icon selector functionality. + 7.x-1.12.13 2017-01-04 ---------------------- - Fix broken recline (resource CSV) preview embeds caused by how recline module loads bootstrap @@ -302,6 +356,7 @@ DKAN Topics: - Fix hidden body field on page content type - Improve access check/security on datastore pages - unauthorized users could perform certain datastore functions - Use dashes in links to tags to avoid "page not found" errors + DKAN Datastore: - Add limit to proxy resources. - Better support of downloading remote files from the resource view page @@ -321,13 +376,13 @@ DKAN Datastore: 7.x-1.12.10 2016-09-07 --------------------------- +---------------------- - Fix JS error on IE browsers preventing previews from appearing - Provide upgrade paths for older sites upgrading to newer BU editor config 7.x-1-12.9 2016-08-31 --------------------------- +--------------------- - Fix data dictionary field to use html input format and improvements to the field's display and help text. - Update dkan_workflow content type legend to include all content types with correct icons. - Fix to new bug introduced in recline module in 1.12.7; previews would not display if file smaller than max preview size, even if loading from datastore. @@ -335,7 +390,7 @@ DKAN Datastore: 7.x-1.12.8 2016-08-19 --------------------------- +--------------------- - Patch panelizer module to correct bug introduced in previous release. See release notes for details. - Add validation to Group form to prevent duplicate groups from being created - Update and patch panels and panelizer to fix critical security issue. See release notes. @@ -343,7 +398,7 @@ DKAN Datastore: 7.x-1-12.7 2016-08-09 --------------------------- +--------------------- - Update contrib modules uuid, services, manualcrop, markdown, panelizer, panopoly_widgets, panopoly_images - Fix bug that produced a "Cannot use a scalar value" error when trying to add a content pane to a data story node in panels. - Change theming on resource to remove iframe to "API or link URL" if remote file field also populated @@ -355,7 +410,7 @@ DKAN Datastore: 7.x-1.12.6 2016-07-26 --------------------------- +--------------------- - Sanitize theme output for facets to avoid any security issue from search input - Fix a potential XSS vulnerability in search facets by adding some validation hooks for facet input - Theme updates back ported from dev branch, including topics icons in topics drop-down menu @@ -364,19 +419,19 @@ DKAN Datastore: 7.x-1.12.5 2016-07-13 --------------------------- +--------------------- - Update restws to 7.x-2.6 (critical security update) - Update to latest version of recline.js to fix map tiles (Mapquest discontinued open access) - Upgrade Drupal core to 7.50 7.x-1.12.4 2016-07-12 --------------------------- +--------------------- - Update permissions in DKAN Permissions module to allow anonymous users to access RDF endpoints for individual datasets. 7.x-1.12.3 2016-06-30 --------------------------- +--------------------- - Open Data Schema Map update: improves performance of package_show endpoint - Point to new release of visualization entity, which cleans up some make files and brings visualization_entity_charts into the same project repository. - Fix editor permissions to allow access to visualizations list from admin menu @@ -395,12 +450,12 @@ DKAN Datastore: 7.x-1.12.2 2016-06-09 --------------------------- +--------------------- - Fix problems in visualization entity charts creation due to version of CSV.js referenced in recline.make 7.x-1.12.1 2016-06-07 --------------------------- +--------------------- - New version of Visualization Entity Charts fixes a number of UI bugs and restores support for Google Sheets and Data Proxy - Fix XSS vulnerability by adding sanitization for titles on workbench view - Upgrade of: Colorizer, Admin Menu Source, Honey Pot, Panopoly Widgets, Panopoly Images, Pathauto, Rules, Restws, Manual Crop, Image Cache Actions, Features, Search API, Organic Groups, Chosen, Date, Entity, Facet API, Facet API Bonus, Facet API Pretty Paths, UUID, Views, Select or other, Remote Stream Wrapper, Link, Libraries, Beauty Tips, Gravatar, OG Extras, Services and Workbench Email. @@ -409,7 +464,7 @@ DKAN Datastore: 7.x-1.12 2016-04-20 --------------------------- +------------------- - Fixed regex used to rewrite font file paths on Dkan Topics, which was breaking filepaths in data.json - Rename dkan_featured_topics to dkan_topics before release - Add "data dashboard" creation link to user admin menu (in dkan_sitewide_menu) @@ -428,14 +483,21 @@ DKAN Datastore: - Upgrade of Panopoly Widgets, Panopoly Images and Fieldable Panels Panes. -7.x-1.12 2015-04-01 --------------------------- +7.x-1.12 2016-04-01 +------------------- DKAN_Datastore: - Add update function enable field_hidden module +NuBoot Radix Theme: + - Add managed file support to logo and hero image + - Add check on filenames to remove spaces and special characters that can break functionality. + - Make date facets consistent with other facets styling + - Upgraded to use Radix 3.3. + - Fix node--search-result.tpl.php file to check the $group_list variable before printing markup + 7.x-1.11 2016-02-02 --------------------------- +------------------- DKAN Dataset: - Fix some bugs breaking the resource links on dataset pages - Re-arranged group links on group landing pages; membership links now in sidebar rather than tabs @@ -446,9 +508,16 @@ DKAN Dataset: - Hide "add resource" button on datasets from users who do not have permission to do so - Numerous small improvements and bug fixes +NuBoot Radix Theme: + - Theming improvements to support new search page design + - Fix the Additional Info field in datasets to hide extra-long rows + - Fix a bug that prevented sub-themes of Nuboot Radix from retrieving their own settings + - Styling for re-arranging of group links on group pages DKAN Dataset + - Numerous small styling and code fixes + 7.x-1.11 2016-02-01 --------------------------- +------------------- - Re-designed dataset/search page. "Datasets" link on default menu bar now goes to a page that lets you browse and search all site content, not just datasets, but does filter by dataset. Search box will search all content by default. See note below. - Add new dkan_permissions module, refactoring default roles and permissions and using new export method. See note below. - Moved group permissions from old dkan_sitewide_roles_perms into new dkan_dataset_groups_perms @@ -501,12 +570,12 @@ $ drush en dkan_dataset_groups_perms -y $ drush fr dkan_dataset_groups_perms -y DKAN Dataset: -- See the DKAN Dataset release notes for 7.x-1.11 for notes specific to the DKAN Dataset module. + - See the DKAN Dataset release notes for 7.x-1.11 for notes specific to the DKAN Dataset module. 7.x-1.10 2015-11-10 --------------------------- -DKAN Distribution +------------------- +DKAN Distribution: - A number of improvements to our test infrastructure - Improved user experience for user photos and Gravatar image fallback - Improvements to views on group pages @@ -515,21 +584,24 @@ DKAN Distribution - Added better HTTPS by loading certain external images over HTTPS - Upgraded to Drupal version 7.x-1.41 - Added a CONTRIBUTING.md file to provide community contribution guidelines for DKAN project. -DKAN Dataset Module + +DKAN Dataset Module: - NOTE: 7.x-1.10 Was re-released on 2015-11-18 to address bugs in the teaser preview links. - Various improvements to dataset teaser displays. - Support for external previews (opening catalogued resources instantly in third-party visualization services, * including ArcGIS and CartoDB) - Support for Flaticon at module level, so vector icons work on any theme - Minor improvements and bugfixes -DKAN Datastore + +DKAN Datastore: - Upgrade Feeds module to latest dev version -NuBoot Radix Theme + +NuBoot Radix Theme: - Style improvements for "open with" button - Fix default logo path when svg not available 7.x-1.9 2015-09-17 --------------------------- +------------------ - Added "Data Dashboards" and "Data Stories" content types with customizable layouts - Added Panopoly Widgets for use in Dashboards, Stories, the front page and panel pages - Added new custom DKAN widgets for use on panel pages @@ -540,9 +612,17 @@ NuBoot Radix Theme - Drupal now on version 7.39. - Many bug fixes and code cleanups - See release notes for nuboot_radix theme and individual DKAN modules for additional release notes + +NuBoot Radix Theme: + - Add support for SVG logos + - New option to use solid color for background/hero graphic instead of image + - Improved Colorizer support for different page elements + - Numerous bug fixes and small styling improvements + DKAN Datastore: - Better UX/behavior for the "add to datastore" button: https://github.com/NuCivic/dkan_datastore/pull/39 - Small bugfixes and improvements + DKAN Dataset: - Fixed issues around the group/publisher field in search indexes and facets - When multiple resources are available for a dataset, new option to download all as zip file @@ -571,7 +651,7 @@ distros on Drupal.org. 7.x-1.8 2015-04-02 --------------------------- +------------------- - Drupal core update to 7.36 - Some tweaks to display properly drupal admin pages using nuboot_radix - Removed unnecessary drupal warning messages (colorizer, updates, etc) @@ -579,6 +659,7 @@ distros on Drupal.org. - Security updates for contrib modules - DKAN_Datastore: Adding CRUD functions to Datastore.inc class - DKAN_Datastore: Adding drush interface to CRUD functions in order to create instances from the cli + DKAN Dataset: - Several recline.js tweaks - Updated open_data_schema_map to include module that allows to hook your own custom output formatters (xml example included) @@ -586,11 +667,12 @@ DKAN Dataset: 7.x-1.7 2015-02-20 --------------------------- +------------------- - Adds Panels to DKAN for Drag and Drop layouts: http://docs.getdkan.com/dkan-documentation/dkan-users-guide/customize-dkan-pages-layouts-and-components-using-panels - Adds Open Data Schema to DKAN https://github.com/NuCivic/open_data_schema_map#open-data-schema-map - Adds 'saved states' to Recline data preview - DKAN_Datastore: Remove schema patch + DKAN Dataset: - Adds Project Open Data v1.1 schema through open_data_schema_map update - Adds dkan data.json v1.1 complaint implementation through open_data_schema_map_dkan update @@ -599,14 +681,16 @@ DKAN Dataset: - Security updates for several modules -7.x-1.6 ---------- +7.x-1.6 2014-11-20 +------------------ - core update to 7.34 - fix issues with javascript in behat tests - freezing behat drupal extension to 1.0.2 - dkan_sitewide modules now report to github + DKAN_Datastore: - Fix services module reference at dkan_datastore.make file + DKAN Dataset: - Creating taxonomies during setup test - Updating ref_field patch @@ -614,22 +698,24 @@ DKAN Dataset: 7.x-1.5 2014-10-15 --------------------------- +------------------ - Drupal core security update. Upgrades to 7.32 7.x-1.4 2014-10-10 --------------------------- +------------------- - Replaced tid hardcoding during profile install with proper taxonomy_vocabulary_machine_name_load - Removed duplicates in dkan.make already present in dkan_dataset.make - Footer branding updated - Editable dkan blocks - Sort on search - New rebuild script to keep dkan updated on custom installs + DKAN_Datastore: - Many warnings fixed with proper isset calls - Added dkan_datastore_api_count implementation - Optimisations on GET parameters processing + DKAN Dataset: - Many warnings fixed with proper isset calls - Changes in make file (fixed versions on some components) @@ -637,13 +723,13 @@ DKAN Dataset: - Added docx as allowed format for field_upload -7.x-1.3 --------------------------- +7.x-1.3 2014-09-25 +------------------ - Issue #192 drupal security update -7.x-1.2 --------------------------- +7.x-1.2 2014-07-18 +------------------ - Issue #184 drupal security update - Updating makefile back to 7.x-1.x state - + 1.1 Release commit + changing git urls with https urls in order to travis to not fail during make @@ -668,9 +754,13 @@ DKAN Dataset: - adding slack integration for travis - Update to make files +NuBoot Radix Theme: + - Switch to radix as a base theme + - Updates for panels layouts + - Switch to flat icons for files http://www.flaticon.com/packs/file-formats-icons 7.x-1.1 2013-06-27 --------------------------- +------------------ - Moved dkan development to Nucivic's github: https://github.com/NuCivic/dkan - Grabbing dkan_dataset.make and dkan_datastore.make fiels from github cdn - Several bugs fixed. @@ -686,18 +776,26 @@ DKAN Dataset: - Fix license block #123 - Issue #111 Fix facetapi_pretty_paths makefile definition #97 - Update drupal-org.make #84 + DKAN_Datastore: - Moved dkan_datastore development to NuCivic: https://github.com/NuCivic/dkan_datastore - DKAN_Datastore: Several bugs fixed. + DKAN Dataset: - Change references to NuCivic organization on github - Several bug fixes - Some changes for Project Open Data compliance, including data.json self-reference +nüBoot Theme: + - Styles for resource download button + - Change nuams references to NuCivic to reflect branding changes + - Left floating resource list + - Improve colorizer functionality -7.x-1.0 --------------------------- + +7.x-1.0 2014-04-29 +------------------ - Moved dkan development to github: https://github.com/nuams/dkan - Moved dkan_dataset development to github: https://github.com/nuams/dkan_dataset - Moved dkan_datastore development to github: https://github.com/nuams/dkan_datastore @@ -711,14 +809,13 @@ DKAN Dataset: - Added nuboot theme (http://drupal.org/project/nuboot) as default dkan theme - Completed 508 compliance on dkan default theme - Several bugs fixed. - - DKAN_Datastore: Moved dkan_datastore development to github: - https://github.com/nuams/dkan_datastore - - DKAN_Datastore: Added WebTestCase test suite for dkan_datastore and dkan_datastore_api: - https://github.com/nuams/dkan_datastore/tree/7.x-1.x/tests + - DKAN_Datastore: Moved dkan_datastore development to github: https://github.com/nuams/dkan_datastore + - DKAN_Datastore: Added WebTestCase test suite for dkan_datastore and dkan_datastore_api: https://github.com/nuams/dkan_datastore/tree/7.x-1.x/tests - DKAN_Datastore: Travis + Github integration for all test suites on every commit - DKAN_Datastore: Several bugs fixed. + - Added nüBoot theme as the main out-of-box theme for DKAN distro. -7.x-1.0-beta --------------------------- +7.x-1.0-beta 2013-09-30 +----------------------- - First tagged release. Further tags will include a changelog. diff --git a/dkan/PATCHES.txt b/dkan/PATCHES.txt deleted file mode 100644 index 2606e0c2b..000000000 --- a/dkan/PATCHES.txt +++ /dev/null @@ -1,5 +0,0 @@ -The following patches have been applied to this project: -- https://patch-diff.githubusercontent.com/raw/NuCivic/dkan/pull/1976.diff -- https://patch-diff.githubusercontent.com/raw/NuCivic/dkan/pull/2095.diff - -This file was automatically generated by Drush Make (http://drupal.org/project/drush). diff --git a/dkan/README.md b/dkan/README.md index 7ca1eaffb..ab985b148 100644 --- a/dkan/README.md +++ b/dkan/README.md @@ -93,7 +93,7 @@ While the GovDelivery Open Data team leads the DKAN project, there is a worldwid Please file all tickets for DKAN [in this issue queue](https://github.com/NuCivic/dkan/issues). We have several labels in place for you to tag the issue with and identify it with the proper component. -Please follow the [Ticket Template](https://github.com/NuCivic/dkan/blob/7.x-1.x/CONTRIBUTING.md#new-feature-template) when creating new tickets. +Please follow the [Ticket Template](https://github.com/NuCivic/dkan/blob/7.x-1.x/.github/CONTRIBUTING.md#new-feature-template) when creating new tickets. Also, please remember to reference the issue across repositories in order for maintainers to pick up commits and pull requests looking at the issue. You can do that for commits like this: @@ -104,3 +104,7 @@ git commit -m "Issue NuCivic/dkan#: ..." Just replace **** with the actual issue number. You can reference pull requests exactly like that if you add the same text **"NuCivic/dkan#<issue_number>"** in a comment. This really help us detecting changes and pulling them in in faster. + +## License + +DKAN is licensed on the same terms as Drupal, under GPLv2 or later. If you have any questions about the license a good place to start is to look at the Drupal Licensing [FAQ](https://www.drupal.org/about/licensing#q1). The DKAN license also covers the related modules such as recline, open data scheme map, visualization entity feeds flat processor, and the taxonomy features. diff --git a/dkan/circle.yml b/dkan/circle.yml index adf47e9d9..99608c921 100644 --- a/dkan/circle.yml +++ b/dkan/circle.yml @@ -32,6 +32,8 @@ checkout: database: pre: - echo -e 'secure_file_priv = ""' | sudo sh -c "cat >> /etc/mysql/my.cnf" + - echo -e 'max_allowed_packet = 128M' | sudo sh -c "cat >> /etc/mysql/my.cnf" + - echo -e 'innodb_buffer_pool_size=256M ' | sudo sh -c "cat >> /etc/mysql/my.cnf" - sudo /usr/sbin/service mysql restart ## Customize dependencies @@ -79,14 +81,13 @@ dependencies: test: override: - ahoy dkan lint + - PATH=/home/ubuntu/.config/composer/vendor/bin:$PATH ahoy drush en --yes dkan_harvest_test + - ahoy dkan unittests: + parallel: false + - ahoy dkan reinstall --yes - ruby dkan/.ahoy/.scripts/circle-behat.rb docroot/profiles/dkan/test/features: timeout: 1200 parallel: true - - PATH=/home/ubuntu/.config/composer/vendor/bin:$PATH ahoy drush en --yes dkan_migrate_base_example - - PATH=/home/ubuntu/.config/composer/vendor/bin:$PATH ahoy drush en --yes dkan_harvest_test - - PATH=/home/ubuntu/.config/composer/vendor/bin:$PATH ahoy drush dis --yes dkan_default_content - - PATH=/home/ubuntu/.config/composer/vendor/bin:$PATH ahoy drush pm-uninstall --yes dkan_default_content - - ahoy dkan unittests post: - echo $CIRCLE_ARTIFACTS; cp -av dkan/test/assets $CIRCLE_ARTIFACTS: parallel: true diff --git a/dkan/dkan.info b/dkan/dkan.info index 3d58a51da..41f057643 100644 --- a/dkan/dkan.info +++ b/dkan/dkan.info @@ -124,7 +124,3 @@ dependencies[] = dkan_datastore dependencies[] = dkan_datastore_api dependencies[] = open_data_schema_map_dkan dependencies[] = visualization_entity_charts_dkan - -; Information added by DKAN release script on 8/23/2017 -version = 7.x-1.13.7 -project = dkan diff --git a/dkan/dkan.install b/dkan/dkan.install index 3da7a176f..dd0043a9a 100644 --- a/dkan/dkan.install +++ b/dkan/dkan.install @@ -387,3 +387,22 @@ function dkan_update_7022() { variable_set('chosen_jquery_selector', '.page-node select:not([class*="delta-order"], [name*="workbench_moderation"], [class*="filter-list"], [id*="delimiter"],[name*="sort_by"],[name*="sort_order"], [id*="lines-terminated-by"], [id*="lang-dropdown-select-language"])'); } + +/** + * Remove deprecated modules from the db: menu_token and remote_file_source. + */ +function dkan_update_7023() { + if (!module_exists('menu_token')) { + db_delete('system') + ->condition('name', 'menu_token') + ->condition('type', 'module') + ->execute(); + db_drop_table('menu_token'); + } + if (!module_exists('remote_file_source')) { + db_delete('system') + ->condition('name', 'remote_file_source') + ->condition('type', 'module') + ->execute(); + } +} diff --git a/dkan/dkan.profile b/dkan/dkan.profile index bc4e1e31e..c108d7756 100644 --- a/dkan/dkan.profile +++ b/dkan/dkan.profile @@ -326,6 +326,8 @@ function dkan_misc_variables_set(array &$context) { 'og_extras_groups' => TRUE, 'og_extras_members' => TRUE, 'dataset' => TRUE, + 'admin_views_file' => TRUE, + 'admin_views_node' => TRUE, ); variable_set('views_defaults', $views_disable); } diff --git a/dkan/docs/admin/account_access_and_setup.rst b/dkan/docs/admin/account_access_and_setup.rst new file mode 100644 index 000000000..d36e102e1 --- /dev/null +++ b/dkan/docs/admin/account_access_and_setup.rst @@ -0,0 +1,58 @@ +======================== +Account Access and Setup +======================== + +Getting to the site +------------------- + +Your DKAN Open Data site will have a login page located at the site's URL with the ending /user. Once you've accessed the login page, you can log in with your account information. We suggest bookmarking the page for quick access. + +.. image:: ../images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_03.gif + :alt: An animated GIF showing someone typing their username and password into the login screen on a DKAN site. + +Getting your login information +------------------------------ + +For your account details, you may receive an automated email with a link and further instructions for login or simply be contacted directly by the person managing your site. Once you receive your account information, you can access the site, log in, and begin setting up your profile. + +Access the site and log in/log out + +.. image:: ../images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_04.png + :alt: Sample username and password entry page on a DKAN site. + +Get to your DKAN site and log in by either: + +- Finding your DKAN site and typing /user in the web address bar after the site name. +- Following the link sent to you with your login information. + +If you don't remember or can't find your password you can get a new password by clicking the Request new password button. + +Use the login information provided to access the site and your profile. You'll see your most recent content, your profile details, and your profile image. + +.. image:: ../images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_05.png + :alt: Profile page for a user named "sitemgr" displaying their login information and list of uploaded content. + +When you're done adding and editing content on the site, you'll want to make sure you log out to avoid security risks. You can log out from anywhere on the site by using either of the buttons shown in the picture below. The blue navigation bar is not on every page of the site, but the black administration bar (the Admin Menu) always appears. + +.. image:: ../images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_06.png + :alt: An image displaying the two upper right-hand side locations of the "Log out" buttons on DKAN. + +Once you log out, you'll be taken back to the Home page of your DKAN site as if you were a general site visitor. + +.. image:: ../images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_08.png + :alt: Screenshot of the front page of the DKAN demo site. + +Setting up your profile +----------------------- + +.. image:: ../images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_09.gif + :alt: Another GIF showing the login process on a DKAN site. + +Once logged in, you'll see your profile page. By clicking the Edit button above your profile image, you can change the details of your account including: + +- Your Username. +- The email address linked to your account and how you will be contacted. +- Your password (you can also request a new password if you've lost or forgotten it). +- Additional information about you in the About section and your timezone. +- Your profile image. +- You can also see which Groups you belong to and delete your account by clicking the Cancel account button. diff --git a/dkan/docs/admin/admin_menu.rst b/dkan/docs/admin/admin_menu.rst new file mode 100644 index 000000000..fcfc5b502 --- /dev/null +++ b/dkan/docs/admin/admin_menu.rst @@ -0,0 +1,131 @@ +================ +Admin Menu +================ + +The Admin Menu on your site is the main tool for navigating data and content management. Get familiar with the Admin Menu as a first step to mastering your DKAN site. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_01.png + :alt: Image displaying the admin menu, located at the top of the screen. + +When you're logged onto the site, you'll see a black navigation bar at the top of the page. This is the Admin Menu. As a Site Manager, this menu looks different for you than other roles on the site. Editors and Content Creators have fewer options because they have fewer permissions on the site. + +Use the Admin Menu as your anchor on your DKAN site. Everything you can do on the site is accessed through the Admin Menu. + +Admin Menu Items +---------------- + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_02.png + :alt: Image displaying the admin menu, located at the top of the screen. + +Add Content +----------- +Add Content is shortcuts menu item for creating new content. Click on Add Content to go to a page of available content types to create or simply choose from the drop-down menu. As a Site Manager, you have permissions to create all the content types possible. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_03.png + :alt: The "Add Content" dropdown on the DKAN admin menu. + +Content +------- +Click on the **Content** menu item to access all the content that exists on the site. As the Site Manager, you have access to create all the content types possible as well as edit, unpublish, and delete all existing content regardless of who the author is. You can create new content from this page as well as manage all the existing content and files on your DKAN site from here. Files include things like images, videos, font files for icons, other graphics, etc. + +In smaller organizations, Site Managers may both be writing and editing their own content to then directly publish the content to the live site. Larger organizations may have people in other roles like Editors and Content Creators to help with handling a large mass of content on the site. Depending on the scale of your organization and volume of content, you may spend more or less time directly handling content. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_04.png + :alt: A view of the "Content" page in DKAN. + +In any scenario, as a Site Manager you can use this page to look at the content on the site to see who created a particular piece of content, when it was last updated, its status (published or unpublished) and take action on existing content. You can handle individual pieces of content, but you can also perform "bulk actions". This is a particularly useful function especially when dealing with a high volume of content. From this page you can take the same action on several different pieces of content by simply checking the boxes on the left, selecting an update option and clicking the Update button. + +In the example below, the Site Manager is selecting a few pieces of content to perform a single action on. The Site Manager is able to unpublish 3 pieces of content at the same time by using bulk actions. While the example is simple, this function becomes helpful on site that contain thousands of pieces of content. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_05.gif + :alt: An animated example of a Site Manager selecting content in order to perform a bulk action. + +Visualizations +-------------- + +As a Site Manager, you have access to create visualizations on DKAN. This type of content is unique to Site Managers and Editors, and as a Site Manager you have access to manage all content regardless of the author. Typically, you'll use DKAN Charts. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_06.png + :alt: The "Visualizations" dropdown on the DKAN admin menu. + +Charts are a powerful tool for taking data and making it meaningful to the average site visitor who may have little to no experience with data and analysis. Click on the **Visualizations** menu item to access all the existing visualization content in your DKAN site, make edits, delete or create new visual content. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_07.png + :alt: A sample listing of Charts from the DKAN Demo site. + + A sample listing of Charts from the DKAN Demo site. + +People +------ + +From the **People** menu item, you can create new users, manage existing accounts, and get a comprehensive view of all the users on the site. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_08.png + :alt: The "People" menu item on the admin menu on DKAN. + +The People main page gives you all the information about the users on your DKAN site including the username and role as well as the length of the account and when the user last accessed their account. This high-level view is especially helpful for managing a large number of accounts and performing "bulk actions". + +Sort the order of info columns by clicking the title link. In other words you can sort A-Z by clicking the Username title link You can use filters and combinations of filters to search for users with specific roles, permissions, and status. + +Make bulk actions to users by selecting the checkboxes on the the far left of the page, choosing an action from the Update options menu and clicking the **Update** button. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_09.png + :alt: The "People" page, which allows you to perform bulk actions on user accounts in DKAN. + +Site Configuration +------------------ + +These options let you manage general settings of certain features on your DKAN site like how user accounts are set up, search options, which fonts are applied to the text on the site and more. These settings determine how lower-access users interact with the site and give you flexibility to change the default behavior. + +Click the **Site Configuration** menu item to see all the configuration options. + +DKAN +---- + +From the DKAN menu, Site Managers can access some of the more technical operations of DKAN. DKAN is the technical engine that powers DKAN, and the available options in this menu are customized to DKAN and open data publishing. + +Use the **DKAN** menu item to add APIs, enable External Previews, access the Harvest dashboard, manage the Recline configuration, and more. + +Recline configuration +--------------------- + +DKAN Internal Previews provide site visitors a visual snapshot of the contents of a Resource. Previews are powered by a tool called Recline that works in the background. + +In cases where the file is relatively small (under 3MB) the Previews tool, Recline, will display the file contents without issue. To preview contents of a file larger than 3MB there are two options: import the file into the DKANDatastore or adjust the Recline configuration. + +**Import file:** As a best practice, we recommend importing CSV files into the Datastore whenever possible. In the case of Internal Previews, if the file is imported to the Datastore there are no size limits on what a site visitor can preview. + +**Adjust Recline Configuration:** For files that cannot be imported to the Datastore, the entire file is downloaded to be previewed. File size limits maintain a positive user experience by preventing errors or loading errors, however they can also keep a site visitor from seeing the contents of some file. + +Site Managers can adjust the size limitations to be higher or lower with Recline Configuration: + + 1. From the Admin Menu, mouse over the DKAN menu item. + 2. Select the Recline Configuration menu item. + 3. On the Recline Configuration page, enter file size limits using standard conventions (MB, GB, etc.) + +Caches +------ +From the Admin Menu you can access caches to flush directly from the drop-down menu items. + +**More actions (home icon):** On the Admin Menu, you can click on the Home icon any time to return to the Home page of your DKAN site. Additionally, if you hover over the home icon, you'll see two options. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_11.png + :alt: The "Flush All Caches" button available within the admin menu on DKAN. + +**Flush all caches:** Flush all caches is a drop-down menu item that allows you to delete stored information on DKAN. Caches are helpful in storing information on the site that was recently used or likely to be used again in the near future. DKAN has a number of caches that are specialized to capture certain information in different places on the site. + +- While caches are useful for keeping information easily accessible, they can significantly slow down computer speed as the caches accumulate more information. By flushing a cache, you delete the stored information and increase computer speed. Click on the main menu item to simply flush all the caches possible, or hover over the arrow to see all the individual options. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_12.png + :alt: An expanded menu showing options for flushing caches in DKAN. + +**Note:** By clicking any of the options to flush caches, you will not be taken to a landing page as with other menu items. Clicking on these menu items directly performs the task, and you'll get a confirmation message like in the image below. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_13.png + :alt: An example of a successfully cleared cache in DKAN. + +*Drupal.org issue queues:** For Drupal-savvy users, the home icon also has Drupal.org menu items. Clicking directly on Drupal.org will take you the main Drupal website that contains extensive documentation on Drupal features, modules, functions and more. +- You can also hover over the menu item to see a list of queues. These queues are a place to report and see already-reported issues that you may encounter on your DKAN site. Some of the queues are specific to DKAN and others are for general Drupal features. These queues are a good resource for troubleshooting issues and reporting problems so that they can be fixed if you're familiar with Drupal. + +.. figure:: ../images/site_manager_playbook/admin_menu/admin_menu_14.png + :alt: The Drupal issue queue, displayed within DKAN. diff --git a/dkan/docs/admin/appearance.rst b/dkan/docs/admin/appearance.rst new file mode 100644 index 000000000..382809212 --- /dev/null +++ b/dkan/docs/admin/appearance.rst @@ -0,0 +1,273 @@ +========== +Appearance +========== + +You can make your DKAN site look and feel completely aligned with your organization to give site visitors the best possible experience while going through the site. Add your logo, change page layouts, customize the Home page, or pick out the right fonts to match your brand. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_01.png + :alt: The front page of an out-of-the-box DKAN site. + +Colorizer +~~~~~~~~~ +Colorizer is what powers the color scheme on a DKAN site. Color schemes are a large part of a consistent aesthetic, which is especially important when working with many collaborators. + +The default color scheme gives your site a consistent look and feel and meets standard accessibility requirements. You can also customize the color scheme to align with your agency’s image using Colorizer. + +With Colorizer, you can choose a different preset color scheme or create your own custom color scheme for full customization. + +Colorizer can be accessed by navigating to the Site Configuration drop-down menu and selecting "Colorizer." + +.. figure:: ../images/site_manager_playbook/appearance/colorizer_dropdown.png + :alt: The Colorizer option, on the Site Configuration menu. + +Using Colorizer +--------------- + +**Global settings:** The global settings are technical details pulled from the CSS template that powers the Colorizer tool. The global settings remain the same, unless you have your own CSS template. + +**Color scheme settings:** The color scheme settings customize a color scheme that will be consistent throughout your site. + +**Color scheme:** Click on the Color scheme drop-down menu to choose from a list of preset themes. Click on the custom theme to choose your own. + +**Custom color scheme:** Create your custom color scheme in one of the following ways: + +- **Using the color picker:** With the custom color scheme selected, use the color picker to choose the primary color for your color scheme. The secondary colors will automatically update to complement the primary color selected. + +- **Manually:** Hex numbers can be changed individually by manually entering a new hex number. When changed manually, secondary colors do not automatically update. + +**Save as default:** Once the color scheme is selected, whether custom or preset, save the changes by clicking the Save as default button at the bottom of the page. + +**Clear Colorizer Cache:** With custom themes, you can reset to the default theme by clicking the Clear Colorizer Cache at the bottom of the page. Clear the cache to start the customization process over or to simply use the default theme. + +.. figure:: ../images/site_manager_playbook/appearance/colorizer_in_action.png + :alt: An example screencap of Colorizer when choosing from one of the default color schemes. + +Theme Settings +~~~~~~~~~~~~~~ + +.. figure:: ../images/site_manager_playbook/appearance/theme_settings_link.png + :alt: The "Site Configuration" dropdown menu, which contains a link to theme settings. + +The theme settings are options that personalize your website. Page elements like logo, site name, the hero section, etc. can all be customized to reflect your agency’s brand. + +**Using theme settings:** + +**List:** Click the List button to see which site themes are enabled and disabled. From here, enable site themes and choose the default theme. Site themes affect how page elements are displayed on a site. By default, DKAN uses the NuBoot Radix theme. Use the List page to choose your theme. + +**Global settings:** These options control the default display settings for your entire site, across all themes. Unless they have been overridden by a specific theme, these settings will be used. + +.. figure:: ../images/site_manager_playbook/appearance/global_settings.png + :alt: The "global settings" display in DKAN, showing a full list of appearance options. + +- **Toggle display:** Turn the display of page elements on and off with the selected checkboxes. With these options, Site Managers can decide to show or not show the logo, site name, option to login, etc. Pay attention to elements like menus, since these affect how site visitors can navigate the site. + +- **Logo image and Shortcut icon settings:** Uncheck the default logo box to add a custom logo. Small, but high-resolution photos work best for these elements. Using a custom logo and shortcut icon are additional ways to personalize your DKAN site. + +**NuBoot Radix:** These options control the display settings for the NuBoot Radix theme. When your site is displayed using this theme, these settings will be used. Because NuBoot is the default theme, use these settings to make changes. + +.. figure:: ../images/site_manager_playbook/appearance/nuboot_theme.png + :alt: The "theme settings" display in DKAN, showing the current theme of NuBoot Radix. + +- **Footer text:** The footer appears on the bottom of every page on the site. In the Copyright section, edit the footer text for additional branding. + +- **Hero Unit:** The front page display includes a large banner at the top of the page, called the Hero Unit. This image is the first contact a site visitor makes with your site, so it can make a strong visual impression. Add a high-resolution image or choose a solid color. In the example below, the solid blue color is the Hero Unit. + +Featured Groups sort order +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Featured Groups is a type of pane that highlights a set number of Groups on a page. If a DKAN site has a Featured Groups pane, Site Managers can decide which Groups are highlighted by changing the sort order of the Groups list. + +1. Choose the order of how Groups appear in a Featured Groups pane with the sort order: +2. From the Admin Menu hover the mouse over the **DKAN** menu item. +3. From the drop-down menu, select **Featured Groups Sort Order**. +4. View the list of Groups; all Groups are listed. +5. Click and drag the cross icon to change the order of the Groups. + +The pane reflects the order on the Featured Groups Sort Order page. To remove a Group from this display, move it further below on the list. Depending on the site, the Featured Groups pane could have as few as 1 Group or as many as 12. The pane displays the Groups at the top of the list for as many Groups are included in the pane. + +Changing front page content +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The landing page of any website is critical. It's the first impression you give a site visitor, and it may be the deciding factor if that site visitor continues to explore the content on your site or if they move on to the next thing. The content on your front page should be eye-catching to get site visitors interested in exploring more. As a Site Manager, you can customize the content of the front page to be engaging and timely. + +Customize branding elements +--------------------------- + +The logo, shortcut icon, and hero unit on a DKAN website can be customized to fit a specific look and feel on an ongoing basis as designs and logos change over time. + +Change the logo +--------------- + +1. From the Admin Menu, hover over the **Site Configuration** menu link to display the drop-down menu. +2. From the drop-down menu, select **Theme Settings.** +3. On the Theme Settings page, scroll down the page to the section labeled Logo image settings. +4. Uncheck the box labeled, Use the default logo. +5. Paste the URL to a remotely hosted image or upload an image. +6. Click the Save configuration button at the bottom of the page to finalize the changes. + +For the logo, use a high resolution image sized with small to medium dimensions. + +Change the shortcut icon +------------------------ +1. From the Admin Menu, hover over the **Site Configuration** menu link to display the drop-down menu. +2. From the drop-down menu, select **Theme Settings.** +3. On the Theme Settings page, scroll down the page to the section labeled Shortcut icon settings. +4. Uncheck the box labeled, Use the default shortcut icon. +5. Paste the URL to a remotely hosted image or upload an image. +6. Click the Save configuration button at the bottom of the page to finalize the changes. + +For the favicon, use a high resolution image sized with small dimensions. + +Change the hero unit +-------------------- + +The hero unit on a website is the large, banner-like image or color on the front page. This section of the website is the backdrop for the welcome to new and returning site visitors. As the first impression, the hero unit can play an important role in retaining site visitors. + +1. From the Admin Menu, hover over the **Site Configuration** menu link to display the drop-down menu. +2. From the drop-down menu, select **Theme Settings.** +3. On the Theme Settings page, click the tab labeled NuBoot Radix for specific theme settings. +4. Scroll down the page to the section labeled, Hero Unit. +5. For a hero unit using an image, upload the file by clicking the Choose file button (max size is 2MB). +6. For a hero unit using a solid color (recommended), enter the hex value of the color. Hex values use a hashtag with numbers and letter format such as #000000 or #4c9d9b + +Using the In-Place Editor +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The In-place Editor is a tool on DKAN designed to make it easy to add, change, and move around content elements directly on the page. You can use the In-place Editor to add new content, drag-and-drop content that already exists, and see changes on the page in real-time. + +From the front page, click the Customize page button at the bottom of the page to open the In-Place Editor and access the existing content. You may want to leave some elements, like the search bar, or you may want to start completely new. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_02.png + :alt: These two buttons located at the bottom of the screen give you options to customize the page or change the layout accordingly. + +Using the In-place Editor gives you flexibility in the way content is displayed and curated. Add simple content types like images, videos, links, and text or you can add more dynamic content like visualizations and slideshows. + +Because this feature shows changes in real-time, it's well-suited for testing how content will look before clicking the Save button. Play with the placement of content on the page, the styling of the region, and keep tweaking until the page looks right. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_03.gif + :alt: An animated screencap of how to add, edit and delete front page content. + +Add new content (+): +-------------------- + +1. On the bottom of the Page, click the **Customize this page** button. +2. Choose the region to add new content to. +3. The add content button is represented on the In-place Editor by a + icon. Click on the + button to add a new piece of content to the region. +4. Choose what element to add to the page (exe visualization, text box, image, video, etc.) +5. Fill in the details of the form, specific to the type of content. +6. Click the **Finish** button. +7. Preview the changes on the Page. Make edits or rearrange with the In-place Editor. +8. Click the **Save** button at the bottom of the page to finalize the new content. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_05.gif + :alt: An animated screencap of how to add, edit and delete front page content. + +**Which content, where?:** Choosing the right content type will depend on the information and the overall arrangement of the different pieces of content. Visual content, like slideshows (a collection of rotating images), videos, maps, and visualizations grab attention and so they do well near the top of the page. Other content, like text, files, and tables add density to a page so less is more. They're best used for quick bites of information and as complements to visual content. + +In the example below, the Site Manager is using the In-place Editor to move content from region to region and delete irrelevant content. the placement of the content is previewed in real-time so you can see how the page will look once the changes are saved and published to the public site. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_06.gif + :alt: An animated screencap of how to add, edit and delete front page content. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_07.png + :alt: An animated screencap of how to add, edit and delete front page content. + +Edit existing content: +---------------------- + +1. Click the **Customize this page** button at the bottom of the page with the content you want to edit. +2. On the pane of the content, click the the gear icon. Each pane can be edited individually by clicking the gear icon for the specific pane with the content to be edited. +3. A menu will appear with the administrative details included when the content was first created. +4. Use the Content settings section to make changes. +5. Click the **Finish** button at the bottom of the screen to save the changes. +6. Review changes on the Page and continue to make changes as needed with the In-place Editor. +7. Click the **Save** button at the bottom of the page to finalize the new content. + +**Remove content:** +To remove the entire pane and all its contents click the trash can icon to remove the pane in one click. Once you choose to remove a pane it cannot be undone, so be careful when removing content. + +**Style a whole region or a single pane:** +Styling gives you even more control over the experience a site visitor has going through the site. You can style an entire region to affect all the panes within the region to have the same styling. + +Alternatively, you can choose a style for single panes within a region. The style button is represented by the paintbrush icon in the top-right corner of the region or pane. + +Use this button to change the style of the region as a whole or an individual pane. Styling may affect the appearance (like adding rounded corners to the region) or the user experience (like making a region and its content collapsed or exposed by default). + +In the image below, none of the panes have any styling applied. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_08.png + :alt: This image displays DKAN panels without any styling applied. + +In the image below each pane has a style different from the others in the same region (from left to right): rounded corners, collapsible (not by default), no style, collapsible (by default). + +.. figure:: ../images/site_manager_playbook/appearance/appearance_09.png + :alt: This image displays DKAN panels with styling applied. + +In the example below the Site Manager is changing the style for the entire region on a page. The Site Manager chose rounded corners for the style. This style groups together a set of information to help guide the site visitor and create a clear differentiation from the other sets of information. When adding styling, you want to think about how it can improve the experience a site visitor has on your site rather than choosing a style based solely on the aesthetic. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_10.gif + :alt: This animated screencap shows a Site Manager is changing the style for the entire region on a page. + +Choose fonts +~~~~~~~~~~~~ + +As a Site Manager, you can control what fonts are used for the text across your DKAN site. By setting fonts, the text is formatted automatically rather than leaving it to individual users to decide. + +This maintains a consistent style throughout your site which is important to the site visitor’s ease in navigating content. User experience can’t be emphasized enough. It can make the difference of a person going exploring through your content or leaving after clicking on just a couple pages. + +While DKAN defaults to a certain font for text styles, the Site Manager has control over fonts to best match the overall look and feel of the organization. Mix and match which fonts are used for specific text areas. Choose one font for text in description and summary boxes, choose another for all headers or a specific size of header or add custom font specifications. + +Enabling fonts +-------------- + +.. figure:: ../images/site_manager_playbook/appearance/appearance_11.png + :alt: The "Site Configuration" menu and the Fonts selector. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_12.png + :alt: This screencap shows the error message you'll receive if no fonts have been enabled. + +Before making font selections, you first have to enable fonts. + +1. On the Admin Menu, find the **Site Configuration** menu link. +2. From the drop-down, select the **Fonts** menu item to access fonts and set defaults. +3. Displayed is the list of fonts that have been enabled as well as browse fonts to either enable or disable. By default, no fonts are enabled; texts appears in the default font set by the DKAN theme. +4. Click on the **Browse all fonts** link. +5. Select a number of fonts to enable and click on the Enable link for each font selected. Once enabled the font can be used in default settings. +6. Click the Enabled fonts link to view the fonts just enabled. + +Enabled fonts are the options that may be used for default font settings. Browse from a list of over 3000 font options provided by Google fonts. + +The tiles have the name of the font as well as a preview, and tiles in green mean that the font is currently enabled. Switch to a list view of fonts you’ve already enabled (if applicable) by selecting the **Enabled fonts** tab. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_13.png + :alt: The "Browse Fonts" screen. + +Once fonts are enabled, they will appear on the fonts main page and you can set defaults with these fonts. Quickly and easily disable fonts from either the **Enabled fonts** menu or while looking for new fonts in the **Browse all fonts** menu. Click the **Disable** link associated with the font. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_14.png + :alt: This screen shows fonts that have been enabled. + +Selecting default fonts +----------------------- + +Once your fonts are enabled, Site Managers can make selections for how text appears on the site by default. + +From the **Enabled fonts** menu, make selections based on the font or based on the CSS selector. CSS selector is a technical term that refers to headers, body text, and any other selectors. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_15.png + :alt: This screen shows what you'll see when selecting which fonts should be assigned to which CSS selectors. + +Find the font you want to apply and use the drop-down menu in the CSS Selector section to choose the right selector. This is good for quick changes to your font selections. Click the **Save applied CSS selectors** to finalize your choices. + +Alternatively, you can apply fonts to CSS selectors by clicking the By CSS Selector tab. + +Here, you can make several changes to the different selectors and apply font changes. This is a good option when you have many changes to make to your font selections. You can also add fonts to the Fallbacks column for your primary font selections. + +By adding a font in this field under the Fallbacks menu section next to the primary selection the fallback font will appear if the primary font is unable to display. + +You can select multiple fallback fonts by using commas; if none are selected then the default DKAN font will display. + +Click the **Save applied fonts** button at the bottom of the page to save your selections. + +.. figure:: ../images/site_manager_playbook/appearance/appearance_16.png + :alt: This screen shows what you'll see when selecting which fonts should be assigned to which CSS selectors. diff --git a/dkan/docs/admin/data_and_content/adding_new_content.rst b/dkan/docs/admin/data_and_content/adding_new_content.rst new file mode 100644 index 000000000..f7defe7a6 --- /dev/null +++ b/dkan/docs/admin/data_and_content/adding_new_content.rst @@ -0,0 +1,532 @@ +================== +Adding New Content +================== + +Your DKAN site is an access point for citizens to connect with your open data, but data isn't the only content you can add. DKAN is designed to showcase your open data in a number of ways to best engage site visitors and demonstrate tangible value. + +There are a variety of content types at your disposal, and it's up to you to choose which best suits your needs. What are you aiming for? What kind of experience do you want your site visitors to have? The answers to these questions will help you decide which content type is right. + +In some cases, like data content, it's not a complicated choice. Data Stories and Dashboards are less obvious content types to use. As a Site Manager, you think about the site as a whole and how all the content flows together to create a transformative experience for citizens. + +The early stages of creating your DKAN site will involve adding more new content than later stages, which involve more content management. Some content, like Resources, might get added every day as new data is made open in many different data formats. Alternatively, Group is a less frequently added piece of content. + +As a Site Manager, you might be involved in adding content in earlier stages and gradually become less involved, or you might never directly generate content. In any case, it's important to understand what content can be added, how it is used and how often, and the overall process so that you can effectively manage your DKAN site and support your team. + +**Here's the breakdown of content by most frequently added:** + +Resource + The most basic piece of content as well as the most abundant. Resources are the actual files that represent your open data. +Dataset + "Containers" that hold Resources. Datasets are given metadata such as author, open data license type, frequency of publication, and they can be assigned to Groups. +Visualizations + Visualizations take Resources on your DKAN site and generate visual representations to make data understandable and accessible. +Data Story + Similar to a blog post, Data Stories provide a narrative that adds the depth of impact. Stories focus on how data changes real lives every day. +Dashboard + A piece of content that curates all kinds of content on your DKAN site. Dashboards make it easy to put data, media, and narrative into meaningful conversation. +Group + Groups both collect content with a common data publisher as well as provide a workflow for a group of users on your DKAN site. +Page + One of the most basic content types on DKAN is a Page. Though the content type is straightforward it has implications for the structure, appearance, and experience of your DKAN site. + +Where do I add new content? +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Using the Add content menu +-------------------------- + +The most direct path for creating content is through the **Add content** menu item on the Admin Menu bar. If you're ready to jump right into creating content select the content type and begin completing the fields in the form. + +.. image:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_01.png + :alt: An image displaying the location of the "Add content" menu on the DKAN navigation bar. + +Using the Content menu +---------------------- + +In some cases you may want to see what content exists before creating something from scratch. As a Site Manager you're able to view and edit all the content that has been authored on your DKAN site. It's not uncommon that content is added but never completed, is complete but outdated, or simply has an unpublished status. As your site matures and contains more content, it's helpful to check what already exists before starting a new piece of content. + +You can use the **Content** menu item to get to the Content screen where you can see all existing content, filter and search, and add new content. + +.. image:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_02.png + :alt: A screenshot of the DKAN "Content" page. + +The Content page +---------------- + +Select the content type that meets your needs to start adding new content. Most of the time, adding a new piece of content is as straightforward as filling out all the fields in a form where some fields are required and others are optional fields for additional information that provide context. + +In the example below, the Site Manager is adding a new Dataset with Tags, Topics, and other metadata associated with Datasets. Though not all the fields in the form are required, it's best to include as much information as possible. Complete content gives your site visitors confidence that your content is professional, current, and polished. + +.. image:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_03.gif + :alt: An animated screenshot showing the process of creating a new dataset. + +General site visitors typically won't have the context or topical expertise to understand the information on its own, so it's important to be mindful of your audience when deciding what details to include. + +.. image:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_04.gif + :alt: An animated screenshot showing the process of inputting metadata when creating a new dataset. + +The final step in creating a piece of content is using the submenu at the bottom of the form to add the final administrative information to the content. Administrative info is kept behind the scenes, and it helps with content management. Keep in mind that your role gives you more permissions than other users on the site; other users with lower-access roles won't see most of these options. + +**Use this menu to add information about:** + +URL path settings + By default, the Generate automatic URL alias option is selected because DKAN is designed to provide the most intuitive and SEO-optimized URL path. To create your own path, simply uncheck the box and type in your own alias. As a reminder, the URL path is how site visitors access and find your content. You want to use terms that are likely to be searched by a general site visitor. +Revision information + This information is important for content that has been added and then edited. By checking the Create new revision checkbox, DKAN will create a revision of the content. You can think of this like a new version where the changes are tracked and recorded. Revisions can be incredibly helpful if a change is made and published and later you want revert to an old revision. Include notes about the changes in the Revision log message text box to give other users context for changes made to the content. +Authoring information + In DKAN, content must be assigned to an author and given an authoring date so that it can be managed later even if the author is the Anonymous user. An author must be a user on your DKAN site, and this is helpful in knowing which users have added what content. By default, DKAN assigns the author to the user who is logged in when the content is added. Though the author and publishing date is mostly only important for content management behind the scenes, there are some cases when you might want to change the author information on a piece of content. + + To change the author you can begin typing a user and the field will autocomplete. Leave the field blank to assign the author to Anonymous. You can change the Authored on information by simply typing a new date into the field. If you leave the field blank, DKAN will use the date and time of when the content was originally saved. +Publishing options + As a Site Manager you can publish and unpublish content. Published content is saved and visible on your DKAN site. Unpublished content is saved, but it is not visible on your DKAN site. + + As a Site Manager you can publish and unpublish directly from the piece of content. When adding new content, the status will automatically default to published. By unchecking the Published checkbox, you can save the work without publishing it to your live DKAN site. If the content already exists and appears on your DKAN site, you can unpublish the content by unchecking the box and it will no longer be visible or searchable to general site visitors. +Groups + When creating a Dataset, you'll have an additional submenu item to consider. The Groups menu item is unique to Datasets because it's the only content that can be added to a Group. Resources cannot be added themselves to a Group, they must be in a Dataset. When adding a Dataset to a Group, users can add a Dataset to as many Groups as there are on the site. Your groups are Groups that the user authoring the content belongs to, and Other groups are all the Groups of which a user is not a member. + + All users must belong to at least one Group to have the Groups menu item available to them. + + When a Dataset is added to a Group, it will be included on the Group's home page and may be edited by the Administrator members of a Group. As a best practice, users should only add Datasets to Groups that they are a member. Certain users won't be able to access their own content if they assign it to a Group that they do not belong to. + +Adding a Resource +~~~~~~~~~~~~~~~~~ + +A Resource is the most basic piece of content as well as the most abundant. Resources are the actual files that represent your open data. You have 3 different options for how you can add a Resource. + +1. **Upload a file:** Most commonly, Resources are added from the local storage on a computer. That is, files are uploaded directly from a computer. This option is a straightforward process of selecting the file from a computer and then uploaded. + +2. **API or website URL:** Similar to how you can add a Resource by linking to an external link, you can also add an API this way. APIs are used by technical users and are helpful in making your open data more accessible. + +3. **Remote file:** You may have a digital file that is hosted on the web. This is an external link, and you can add a Resource by providing the web link as long as the file extension is supported by DKAN. Later in the form, you can specify exactly what type of file format your data is in. + +Keep in mind, that any CSV files can be imported to the DKAN Datastore *(recommended)*. + +Steps to upload a new resource +------------------------------ + +1. From the **Admin Menu**, hover over the **Add Content** menu link. + +2. On the drop-down menu, select the **Resource** option. + +3. Choose a method for uploading the Resource (upload, API/website, or remote). + +4. Enable Data Previews (optional), select the appropriate delimiter, and if Previews should have an embed option. + +5. Give the Resource a title (required), a description (optional), and add to a Dataset (optional). + +6. Click the Save or Save and add another button at the end of the form to add the Resource. + +It's possible to add a Resource as a stand alone piece of content, but it isn't recommended. Best practice is to add a Resource associated with a Dataset for 2 important reasons: + +- **Resources don't contain metadata:** Dataset is the content type that contains metadata, Tags, Topics and are assigned to Groups. A Resource must be in a Dataset to be associated with that information. Additional information provides a clearer picture of the value of your data and makes it easier for site visitors to find as they browse your DKAN site (and the web in general). Categorizations like Topics and Groups keep relevant content together and ready to discover. Datasets act as containers for Resources with common information and any new Resource added to a Dataset is automatically associated with the metadata. + +- **A Resource can't be added to a Group.** Only Datasets can be added to a Group. Groups may appear similar to Topics because they collect related content, but Groups do much more. Groups represent a common data publisher, and all the Datasets that belong to that publishing Group will appear on the Group's home page. Most importantly, Groups create an additional workflow for how data on the site is added and managed. Datasets in a Group can be managed exclusively by members in that Group. Resources have to be included in a Dataset in order to belong to a Group. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_05.png + :alt: An example of a list of Datasets provided that a Resource could then be assigned to. + + Example of a list of Datasets that a Resource may belong to. + +When adding a new Resource, DKAN provides a list of existing Datasets and you can select the appropriate one. If none of the existing Datasets seem correct, then consider first adding a new Dataset. You can also add a Resource and then later assign it to a Dataset. + +Enabling Data Previews +~~~~~~~~~~~~~~~~~~~~~~ + +As site visitors navigate through resources on a DKAN website, they may want to see the Resource contents before (or instead of) downloading the entire file. Site Managers and Editors can enable Previews on Resources with JSON, geoJSON, XML, ArcGIS REST, WMS, image, PDF, and ZIP data formats. + +Preview tools give site visitors the option to see a basic visual of a Resource as a map, chart, or grid. As site visitors browse through a Dataset and its Resources, they can click the Explore Data button to preview a specific Resource. + +Internal Previews +----------------- + +Internal Data Previews can be enabled for **grids, graphs, and/or maps** depending on what fits the data format. + +1. Click the **Add content** link and select the **Resource** menu option. +2. With the Upload option selected, find the Data Previews box. +3. Check which Previews should be enabled (grid, graph, map). Previews only display if the contents of the Resource match the data format for a Preview. For example, if the map Preview is enabled but the Resource doesn't have latitudinal/longitudinal data, then the Preview page will be blank. + +**Special note:** Data Preview options appear when the Upload option is selected. If the Resource is from a URL or a remote file, first enable Previews and then add the file. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_06.png + :alt: The "Add a Resource" screen, showing the options to enable grid, graph or map previews. + + This image displays where you can enable grid, graph and/or map previews for a Resource. + +**Grids and Graphs:** This type of Data Preview works well with tabular data like CSV or XLS files. Grids appear most similar to a spreadsheet and reflect the greatest precision of the file contents of a Resource. Graphs are more visual and provide quick synthesis of the contents of a Resource. + +Graph previews allow any user to select the values that should appear and the axes that frame the graph. + +**Maps:** Geographic data produces maps with points individually plotted or clustered together at a high-level view. This feature is intended for simple representations to give site visitors a snapshot of the resource contents. A Resource must contain latitude and longitude data to generate a map Preview. + +External Previews +----------------- + +More complex and varied data require more sophisticated visualization tools. With External Previews, site visitors can preview a Resource with more advanced precision using tools that are integrated seamlessly with DKAN. External Previews open the possibility for a wide range of data formats to be previewed in either CartoDB or ArcGIS, depending on the file format. + +Once External Previews are enabled, site visitors can view a Resource and click the Open With button to visualize the contents of the Resource with an External Preview. + +External Previews is a standard feature, however each data format must be individually configured for which visualization tool may be used to view the Resource. + +Choose which visualization tool may be used to open a Resource, based on its data format. + +**To enable External previews:** + +1. On the Admin Menu, hover over the **DKAN** menu link until the drop-down menu appears. +2. Select **Data Previews.** +3. From the Data Previews page, scroll down to the section titled External Preview Settings. +4. In the External Preview Settings section, check the box for the External Previews you want to make available for viewing a Resource. +5. If a data format is not listed in this section, you can add the data format to the list of available formats for Resources. + +Keep in mind that External Previews direct site visitors away from your site, and the visualization tools will prompt site visitors to log in or create an account. + +There are two types of External Previews that may be enabled by Site Managers: **CartoDB** and **ArcGIS**. + +**CartoDB Preview:** CartoDB is an open source platform that takes data and generates complex, yet elegant maps. CartoDB is a leader in mapping technologies known for its ease of use, analytic tools, variety of mapping visualizations, and powerful datastore that can handle files of almost any size. + +Supported formats: CSV, Excel, GeoJSON, KML, OpenXML, XLS + +**ArcGIS Preview:** ArcGIS can be used to create multi-dimensional map (such as the topography of a mountain range, or the flow of a watershed) and doesn’t limit the amount of layers you can add to your map, and allows you to process vast amounts of data using advanced mathematical tools and scripting capabilities. + +External Previews supports ArcGIS to preview data on DKAN. ArcGIS Previews require a URL in the resource API field and will not work with Resource files. As with other tools supported by External Previews, ArcGIS requires an account to open a Resource. + +Supported formats: ArcGIS endpoints + +Adding a Dataset +~~~~~~~~~~~~~~~~ + +Datasets are "containers" that hold Resources. Datasets are given metadata such as author, open data license type, frequency of publication and can be assigned to Groups when they are added. + +The most important thing to remember with Datasets is to include as much information as possible from the Title to Related Content. Descriptions, Tags, coverage area, how often the data are published, a person to contact–it may seem like a lot of information to include, but it provides essential context for site visitors. The level of detail on a Dataset could be the difference between a site visitor simply glossing past and becoming an engaged, active citizen. + +Add a Dataset: +-------------- + +1. From the **Admin Menu**, hover over the **Add Content** menu link. +2. On the drop-down menu, select the **Dataset** option. +3. Add a title, description, Tags, contact information and public access level (required). +4. Optionally, Datasets may be added to Groups and Topics. +5. Add a license to clarify reuse limitations. +6. Click the **Next: add data** button to add at least one Resource. +7. Follow the procedure for adding a Resource. +8. Click the Save button to finalize the addition. + +In the example below, you can see all the fields included when adding a Dataset. Metadata fields make Datasets the most information-rich type of content, and the fields are designed to make your data publishing practices compliant with Project Open Data standards. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_09.gif + :alt: This animated screencap shows the process of editing and saving a dataset. + + This animated screencap displays the process of editing and saving a dataset. + +**Change the Resource URL:** When adding or editing a Dataset, you can change the URL path so that it's easier to read as well as more likely to appear in a site visitor's search. An important consideration when creating titles and labels is to keep in mind how site visitors look for information. It's safe to assume that most site visitors won't start by looking for your DKAN site. More likely is that they'll first do a general search on the web. A random Dataset might be the first and only interaction a person has with your DKAN site. That's why it's best to include lots of contextual information, make it easy to read and scan, and use terms that site visitors are likely to search for. + +Directly under the title of the Dataset, you can change the URL path for your dataset in the dataset/ field. Note that the title and URL path are not linked. That means that you can change the title without affecting the URL path and vice versa. + +.. image:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_10.gif + :alt: This animated screencap shows the process of changing a Resource URL. + +Adding Metadata +~~~~~~~~~~~~~~~ + +Metadata is often described as the "Who, what, when, where, and why" of a Dataset. Metadata gives a high-level view by providing additional information about the files in the Dataset. Without metadata, site visitors could download the contents of a file but they wouldn't have any information about who provided the file, when it was published, how often it is published, the time range and geographic area that the file represents, and so on. + +In addition to providing important context, metadata makes the data published machine-readable. That means that programmers, analysts and other technical users can use the information for their own purposes. + +On DKAN, metadata is added by a series of extra fields that can range from fairly to basic (like the author) to advanced details (like the granularity of the data). Though most metadata is not required, adding more details makes for richer, more usable datasets. It's a good idea to provide additional information whenever it is available. In some cases extra metadata fields are required to be compliant with certain standards and initiatives. + +The fields included in the Additional Info screen are the metadata for the Dataset. These fields are compatible with DCAT, an RDF vocabulary designed to facilitate interoperability between data catalogs published on the web. These fields are also compatible with the Common Core metadata schema from Project Open Data. + +Site Managers can select to make Project Open Data and DCAT fields required for publishing a Dataset by enabling POD and/or DCAT validation. + +When viewing a Dataset, scroll down the page to the Dataset Info section to view its metadata. + +.. image:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_13.png + :alt: The highlighted portion of this screencap shows how the "Dataset Info" box within a dataset's description displays its metadata. + +**Adding more relevant information:** In the image below, you can see a section titled Resources and below that Related Content. In the Resources section you can choose from existing Resources to pull into the Dataset. You can even choose the order Resources appear in by dragging the individual rows up and down. Click the Add another item to add as many Resources as you want to the Dataset. + +.. image:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_14.png + :alt: This screencap displays the portion of the page for adding new resources and related content to a Dataset. + +Scroll to the Related Content section to add links to other content that site visitors should see. This is a great way to link to your Data Stories, Charts, and Dashboards (or external links) that showcase the impact that data can have on the daily lives of citizens. + +Below is a Dataset that has been filled out completely with a description, metadata, assigned to a Group and includes related content. + +.. image:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_15.gif + :alt: This animated screencap displays a a Dataset that has been filled out completely with a description, metadata, assigned to a Group and includes related content. + +Visualizations +~~~~~~~~~~~~~~ + +Visualizations take Resources on your DKAN site and generate visual representations to make data understandable and accessible. DKAN offers several built-in tools for making data visualizations easy. These were designed with ease of use and flexibility in mind. + +A Chart is the means, but the end must be defined by the citizen need. What is important for the site visitor to know about the data? What can we learn by comparing the different information contained in a single Resource? Once a Chart is added you can feature it to support the narrative of a Data Story or complete a Data Dashboard. + +While this tool is incredibly powerful, it also includes more variables that depend on one another. As a Site Manager, you have access to create Visualizations on DKAN. This type of content is unique to Site Managers and Editors, and as a Site Manager you have access to manage all content regardless of the author. + +.. image:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_16.png + :alt: An example of a chart created in DKAN. + +Adding Charts +------------- + +In general, you'll add DKAN Charts for your visualizations. Charts are a powerful tool for taking data and making it meaningful to the average site visitor who may have little to no experience with data and analysis. Charts offer power and flexibility to represent exactly what you’re looking for with minimal effort and no specific technical training required. Data that power charts can come directly from your DKAN data catalog or alternatively any URL, public Google spreadsheet, or data proxy/API. + +Charts are ideal for showing comparative and/or historical information. Site visitors can look at a Chart and quickly discern the relationship between several data points. Charts easily adapt to represent a number of combinations between many values. Visualizations may range from a simple 2-dimensional comparison to more complex, multi-faceted relationships. + +**Supported data and file types:** + +- **Using internal CSV files:** Charts visualize data that has its contents organized into rows and columns (tabular data). DKAN Charts support CSV files when selecting an internal Resource hosted on DKAN. Select the CSV option for the back-end when loading the data source. +- **External CSV and XLS files:** You can create a Chart from files hosted elsewhere on the Web as long as a link is provided. Linked files can be a CSV or XLS. When files are externally linked select the DataProxy option for the backend when loading the data source. +- **Using Google spreadsheets:** Public Google spreadsheets are files created with Google sheets that have been published to the web. You can create your Chart with the public link and by selecting the Google spreadsheet option for the back-end when loading the data source. + +**Choosing your data:** The first step in adding a Chart is choosing which data you want to visualize. Choose a title and add a description, then select the data source. You have a 3 options for selecting the data source: + +- **Upload a new file:** This is a file stored locally (ie a file on your computer’s hard drive) and not already on your DKAN site. Uploading a file to power your Chart does not automatically add the file as a Resource on your DKAN site. Use the Upload button in the File field to choose a file from your computer. Note file size and type limits apply. +- **Choose an existing Resource:** Select a Resource that has been added to your DKAN site. Start typing in the Existing Resource field and DKAN will autocomplete with matching Resources. +- **Link to an external file:** Use the Source field to link to a file hosted elsewhere on the web. + +**Choose a data processor:** Once you select the data source, it’s important to choose the right data back-end to process the data. The processor reads the contents of a file and makes it possible to define which variables should be visualized. This works in the background, but you should know which data sources match which data back-ends. There are 3 data back-end to choose from: + +- **CSV:** CSV is the default selection, and it is used for Charts powered by internal data sources. If you upload a new file or select an existing Resource as your data source then your data back-end is CSV. +- **DataProxy:** If you use an external link for the data source, you may use a CSV or XLS file type. An external link is the only way to power a Chart with an XLS file. If you select a data source by using an external link then your data back-end is DataProxy. +- **Google Spreadsheet:** You can power a Chart with a Google spreadsheet if the document has been published to the Web and made public. If you select the public link to a Google spreadsheet then Google Spreadsheet is your data back-end. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_17.png + :alt: A screencap of the "Load Data" portion of the Visualizations creation page in DKAN. + +**Defining your Chart variables:** In essence, Chart variables are the two axes of your Chart that you set. The x-axis and the y-axis each have their own set of values that run along each respective axis. Because Resources often contain more than two columns (all with their own set of values), you can choose which columns you want as the x- and y-axis as well as add Series. Series can be selected from the different columns within your Resource to compare multiple columns along the Chart axes. This provides flexibility when using large files to create Charts. + +You can choose which contents within the data source to display on your Chart. Some data sources may be fairly simple with only a couple columns while others may contain dozens. Options for the variables are based on the contents of the data source selected to power your DKAN Chart, so you’ll choose from columns and their values. There are 3 variables to select for when adding your Chart: + +- **Series.** Series show the values within a column as the y-axis values mapped along the X-Field values. Once you choose a column to provide the values for the X-Field, Series provide the corresponding y-values. You can choose multiple columns from your Resource to be Series, which can be helpful for showing multiple data points next to one another. +- **X-Field.** The X-Field provides the x-axis values for your Chart. Choose a column from your Resource to populate the X-Field with values. +- **Data Format:** Selecting the correct data format helps Charts to display correctly. Choose the format that matches the format of the values in your X-Field. If you’re not sure, you can leave the selection on Auto and DKAN will make the best selection. If the values are text/non-numeric, select the String format. + +**Choose a Chart type:** Different types of data work better with certain Chart types more than others. DKAN offers a number of different Chart types like line graphs, bar charts, and pie charts and different types of data will work better as a line graph rather than a bar chart. + +For continuous data (like time) use a line Chart to show the movement of the data. For categorical data (like a discrete totals within a category) use bar charts, and for data that totals a sum use a pie chart. + +There are a number of Chart types to best display your data depending on what you want the Chart to show and the contents of your Resource. You can choose a Chart type and then move to the Preview and Adjust screen to make the final modifications to your Chart. You can always change the Chart type by using the Back button, so that you can test and see which Chart type works best with your data. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_18.png + :alt: A screencap displaying the options for Chart types in DKAN. + +In the example below, the Site Manager is adding a Chart that uses an existing Resource. By typing, DKAN suggests an autocomplete option and the Site Manager selects the Resource. Once the Resource is selected, the Site Manager can define the variables of the Chart. In this example, the Resource is very basic with only two columns that be chosen from, but more robust Resources could have several columns to choose from. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_19.gif + :alt: An animated screencap displaying the Chart creation process in DKAN. + +**Adjusting your Chart settings:** After the data is loaded and the variables selected, you can see how your Chart will appear and make adjustments so that your visualization best depicts the meaning of the data. On the Preview and Adjust screen, you make any final modifications to your Chart through a number of options on the Chart Configuration menu. The Chart preview will adjust in real-time to show you what the Chart will look like on your site. Use the preview to test out different adjustments for your Chart settings. + +In the example below, a Site Manager is adjusting the Chart settings for a Chart they're adding. Though there are a number of options, the data here is fairly basic. The Site Manager rotates the labels by putting in a degree of rotation in the X Label Rotation field, changes the color of bars by adding a hex value in the Color field, and adds a label to the x-axis by putting a name in the X Axis Label field. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_20.gif + :alt: An animated screencap displaying the Chart creation process in DKAN. + +As the example continues below, the Site Manager decides to show the title of the Chart and selects the Show Legend option. Show Tooltips and Reduce Ticks are selected by default. Click on the Finish button at the bottom of the page to finalize your selections and see the final results of how the Chart will appear on your DKAN site. + +Unlike other content types, Charts don't automatically collect on a page on your DKAN site. You can make Charts visible by including them in Dashboards and Data Stories. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_21.gif + :alt: An animated screencap displaying the Chart creation process in DKAN. + +Key information when adjusting your Chart settings: +--------------------------------------------------- + +- **Query Editor:** The Query Editor field lets you search the contents of the Resource powering your Chart and visualize the most relevant pieces. This function is useful for especially large Datasets. Use this setting to perform a complex search on the data in your Resource and narrow the focus to display on your Chart. It's good for highlighting key insights in the data. Use the same format conventions as in the Resource (ie $0.00, x/y/z) when performing the search. + +- **Filter Editor:** Terms add a broad filter to highlight characteristics shared by multiple data points in your Resource. This is adds more focus than visualizing all the contents of a Resource, but is not very overly complex. Use this to draw specific comparisons in your visualization. Add multiple filters to give a specific cross-section within the data. + - **Field:** Create a term to filter the data by first choosing a Field from a column within the Resource. All the columns will appear in a drop-down menu to choose from. Use terms to narrow the view of the data. + - **Filter Type:** Choose from the drop-down list to further specify conditions for the data you’re looking for within the Field you’ve already selected. + +- **X-axis Chart Settings:** These settings are specific to the x-axis. + - **X-Format:** Choosing the X-Format lets you specify how the x-axis values are represented rather than as the basic numbers. For example, the value 5.2 will show as $5.20 if the X-Format is $0.00. + - **X Label Rotation:** Use this to rotate the values of the x-axis of your Chart. With 0 degrees rotation, the labels appear side by side. Enter a number to add a degree of rotation and the labels will appear at an angle. + - **Step:** Set the number of increments that will appear on the x-axis. The total distance on the x-axis from the 0 value to the final value will be divided into the number of increments set. By default, the Step is not set. + - **Tick Values:** Set a range of values from your Resource to narrow which values appear on your Chart. By default, every value in the Resource is displayed. + - **X Axis Label:** This is the name that describes the x-axis and appears on your DKAN Chart below the x-axis. Create a label to provide more context for the data being visualized. + +- **Y-axis Chart Settings:** These settings are specific to the y-axis. + - **Format:** Choosing the Format lets you specify how the y-axis values are represented rather than as basic numbers. For example, the value 5.2 will show as $5.20 if the Format is $0.00. + - **Y Axis Label:** This is the name that describes the y-axis and appears on your DKAN Chart below the y-axis. Create a label to provide more context for the data being visualized. + - **Distance:** The distance of the Y Axis Label from the left edge of the page. The larger the number, the closer the label appears to the y-axis of your Chart. + +- **General Chart Settings:** + - **Margin:** Margins add padding (extra white space) around your Chart, measured in pixels. Padding is added to the top, right, bottom and left respectively. Adjust the padding to accommodate long labels, Chart values, label rotations, etc. + - **Transition Time:** Change the time it takes to animate the data in a Chart. Longer transition time will make the sections of a Chart appear more slowly. Note: this does not affect pie charts. + - **Color:** Change the color of the segments of your Chart by adding color names (blue, green, etc.) or the hexadecimal numbers of specific hues (#FFD9AA , #FFFFFF). You can also use the color selection tool to visually select a color rather than by typing it in. You can add any number of different colors for the Chart segments by adding commas in between colors. + - **Sort:** Choose which criteria the Chart sorts data by and displays on the graph, like A-Z or highest to lowest. Criteria could be values from the Chart variables or left to the default sort setting. + - **Goal:** This setting creates a line at the value you designate on the Chart. It signifies a baseline, an average, or a goal among the values to compare the rest of the data. Enter a value in the Goal field to select the value to appear parallel to the x-axis. You can also choose the color of the line, whether you want to show the label (the label is "Target" and cannot be changed), and if the label should appear directly on the chart or outside of it. + +- **Checkboxes:** + - **Show title:** A Chart must be titled when it is created. By checking this box, you can display that title as a header on the Chart. + - **Show controls:** Select the Show controls option to make your Chart interactive. On bar charts, you can include buttons for site visitors to choose how data is displayed on the Chart either as Grouped and Stacked. Check this box to show buttons that show data either as a single stack composed of all the Series (Stacked) or the data are grouped together but have discrete bars (Grouped). + - **Show legend:** When selected, this shows site visitors the names of the Series included in your Chart. Site visitors can show and hide Series on the Chart when Show Legend is checked. + - **Group by X-Field:** With non-numerical discrete data (usually text), you may have repeated x-values on your x-axis. Check this box to add the outputs together and display as a single x-value on your Chart. + - **Show Tooltips:** Check this box so that site visitors can mouse over the individual sections of your Chart and see exact values. If this box is checked, you won’t also need Show Values, which creates a fixed label for each value. + - **Reduce Ticks:** In a value range, you may not need display every value (for example, 1-1000). Check this box to group values by increments to reduce the number of x-axis values shown on the x-axis. + - **Stagger Labels:** Staggering places labels slightly above and below each other rather than on the same line, so that they don’t overlap. Check this box if your labels don’t appear correctly. + - **Show Values:** Show exact values on your Chart with a fixed label. If this box is checked, you won’t also need Show Tooltips (which creates hover text with values). + - **Show Data Points:** This option only applies to the line chart type. Check the Show Data Points option to add a dot on the line Chart for every unique data point in the Resource. + - **Donut:** This option only applies to the pie chart type. Select the Donut checkbox to change the aesthetic of your pie chart to look like a donut shape. This adds some variety and visual flexibility to the standard pie chart type. + +**Going back to change Chart selections:** To make changes on any of the previous screens, use the Back button rather than the key on your keyboard or back tab in your browser. By moving back without using the Back button, you may lose all your work or encounter other errors. + +Adding a Data Story +~~~~~~~~~~~~~~~~~~~ +Similar to a blog post, Data Stories provide a narrative that adds the depth of impact. Stories focus on how data changes real lives every day. While the form might look familiar, it's helpful to know how the content will appear on DKAN. + +1. Log in to your DKAN site. +2. From the Admin Menu, hover over the **Add Content** link +3. Select the **Data Story** menu item from the drop-down menu. +4. Title the Data Story and provide a banner image +5. Add Tags and Topics to make the content easy to find. +6. Choose a layout for the Data Story. By default, the most basic layout is selected. +7. Click the Save button to create the content. + +Once the Data Story is added, the content may be altered, rearranged or new content added using the In-place Editor. Learn more about how to use the In-place Editor. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/Data_Stories_Summary_13.png + :alt: Examples of data stories in DKAN + +Key information when adding a Data Story: +----------------------------------------- + +- **Image:** Choose a large, high quality image for your Data Story. This image appears in a large format across the top of the Data Story. Because of the size, you'll need a large image (minimum 900x1200 pixels) with high resolution so that it appears as expected. In Data Stories, these images can only be uploaded; there isn't an option to link directly to an image from the web. First select the image by clicking on the Choose file button and then add the image by clicking the Upload button. +- **Edit summary:** Click the Edit summary link to open another text box. In the Summary text box, you can add unique details about your Data Story. This text appears as teaser text as site visitors browse through the Stories page. If you don't want to write additional summary text, DKAN will simply pull the first portion of your Data Story in the Body text (about 100 words). Including a summary can be useful in adding more key search terms or using a different tone to intrigue site visitors to learn more. +- **Body:** This is the section where the contents of your Data Story appear. Because DKAN doesn't automatically save content and publishes directly to the site once you save, we recommend drafting in a separate text editor so that you can write at your own pace and use your own review process before pasting into the Body section of your Data Story. +- **Text editor options:** Use the Body text box for the contents of your Data Story. Use the tools in the text editor to format and style the body of your text. With these tools you can add images, links, quotes, and line breaks directly in the text box. + +**Adding Tags and Topics:** You can add Tags and Topics to your Data Story so that it's easy to find in a search and as site visitors browse the content on your DKAN site. Tags are free-form, so they can be newly added in the field and can contain any words. + +Think of Tags as keywords either within or related to the content. So if you have a Data Story about chickenpox vaccines in the state of Mississippi you might include a Tag for "chickenpox", "vaccines", "Mississippi" and additionally "public health" and "viruses". By including Tags on your Data Story, the Data Story associated with those terms will appear when the terms are included in a search. + +Topics are similar but distinct from Tags. Topics are preset and they act more as a category that content is collected under on your DKAN site. Topics aren't limited to a common data publisher or common metadata; they represent a conceptual relationship between pieces of content. As a Site Manager, you can preset which Topics may be assigned to content. + +**Choosing a layout:** Layouts are like templates for the design of a page. In most cases, you would need to have technical experience with code to change the way that content appears on a page and what content is allowed. With DKAN layouts you can choose from a set of layouts pre-made to beautifully combine different content in the same place without needing to touch any code. + +Choose the layout for your Data Story and add data, media, text, etc. in the different panels. By default the most basic layout (Boxton) is selected, but choose the layout best fits the types of content you want to include for your Data Story. + +Layouts are composed of different regions. Each rectangle and square shown in the different layouts is a region, and each region can contain one or more (or zero) pieces of content. Choosing the right layout is often a matter of trial and error depending on how the content is oriented and how you want it arranged. The regions in a layout are suited better for some content than others; as you add your content you can easily change the layout to meet your needs without losing any of the content. + +Adding a Data Dashboard +~~~~~~~~~~~~~~~~~~~~~~~ + +DKAN Dashboards provide the ultimate flexibility in bringing content together. Layouts are like templates for the design of a page. In most cases, you would need to have technical experience with code to change the way that content appears on a page and what content is allowed. With DKAN layouts you can choose from a set of layouts pre-made to beautifully combine different content in the same place without needing to touch any code. + +Add a Dashboard: +---------------- + +1. From the Admin Menu, hover over the **Add Content** menu link until a drop-down list appears. +2. From the list, select the **Data Dashboard** link. +3. Give the Dashboard a title that is short so that it's easy for site visitors to search and find. +4. Optionally, choose one or more Topics to associate with the Dashboard. +5. Give a brief summary of the dashboard in the description field explaining what kind of information it contains. +6. Choose a layout that best fits the expected arrangement of the content. Content will automatically be resized to fit the dimensions of the layout. Once a Dashboard is added, the layout may be changed at any time without losing its contents. +7. Click the **Save** button at the bottom of the page to add the Data Dashboard. + +Once the Dashboard itself is added, content is added to the layout of the Dashboard in panes. Add visualizations, media, text, etc. to the Dashboard. + +Example Data Dashboards can be found on the Dashboards page of demo.getdkan.com. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/Dashboards_Summary_13.png + :alt: Examples of a Data Dashboard in DKAN + +Layouts for Dashboards and Data Stories +--------------------------------------- + +Layouts are composed of different regions. Each rectangle and square shown in the different layouts is a region, and each region can contain one or more (or zero) pieces of content. Choosing the right layout is often a matter of trial and error depending on how the content is oriented and how you want it arranged. The regions in a layout are suited better for some content than others; as you add your content you can easily change the layout to meet your needs without losing any of the content. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_23.png + :alt: Examples of layouts in DKAN. + +**Using the In-place Editor:** Once you've selected the layout and save, you can begin adding content to the regions in the layout using the In-place Editor. The In-place Editor is a drag-and-drop tool that lets you visually place content within your selected layout and see a real-time preview of what it will look like once saved. + +- **Add ( + ) button:** The button to add content is represented on the In-place Editor by a + icon. Click on the + button to add a new piece of content to the region. You can add as many pieces of content to a region as you want. The content will fit to the region of the layout regardless of how many pieces of content are added. +- **Style button:** The button to add styling to a region is represented by the paintbrush icon in the top-right corner of the region. Use this button to change the style of the region as a whole. That might affect the appearance (like adding rounded corners to the region) or the user experience (like making a region and its content collapsed or exposed). +- **Edit button:** You might think the Edit button is how you edit the content contained on your Dashboard. This button actually lets you edit the administrative details of the Dashboard. That includes information like the Title of the Dashboard, assigned Topics, authoring information, published status, etc. + +**Customize display:** Site Managers can change the layout even after adding content to your Dashboard or reset if you want to remove all content. You can also use the content menu to see another view of the content on your Dashboard. This is useful for rearranging content after changing layouts or shifting several pieces of content on a Dashboard. Click on the content link to open another set of options. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_25.png + :alt: The "customize display" dialog in DKAN. + +- **Title type.** The Title type refers to how the title is set. Leave the selection at Manually set for your Dashboard to keep the original title. You won't change the title of your Dashboard here; this title is added and changed in the Edit menu with other administrative information. + +- **Substitutions:** You won't need to manage Substitutions, so you can leave this option hidden. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_26.png + :alt: A screencap showing data dashboard customizations in DKAN. + +**Gear button:** On the Customize display screen, you can use the gear icon on the region sections to add and manage content for the whole region as well as change the appearance settings. You can also edit each piece of content within a region using the individual gear icons in the content boxes. + +Adding a Page +~~~~~~~~~~~~~ +One of the most basic content types on DKAN is a Page. Though the content type is straightforward it has implications for the structure, appearance, and experience of your DKAN site. + +**Key Information when adding a Page:** + +Choosing a layout + Layouts are like templates for the design of a page. In most cases, you would need to have technical experience with code to change the way that content appears on a page and what content is allowed. + With layouts you can choose from a set of layouts pre-made to beautifully combine different content in the same place without needing to touch any code. Choose the layout for your Page and add data, media, text, etc. in the different panels. + By default the most basic layout (Boxton) is selected, but choose the layout best fits the types of content you want to include for your Page. Keep in mind, you can change your layout anytime. +Creating a menu link + The most important piece of creating a page is adding the navigation for it. In order for site visitors to find your page and benefit from its content, add a menu link and decide the parent menu item. For high-priority content, like a Contact page, put the link on the main menu bar. Otherwise, decide which parent page the new page belongs to. + Special note: we recommend that you do not add menu links to the Datasets, Groups, Stories, Dashboards, or Topics pages. + +Adding a Group +~~~~~~~~~~~~~~ + +Groups are both a way to collect common Datasets and enable an additional workflow on DKAN. On the outward-facing side, site visitors are able to browse and search Datasets specifically published by a Group, which is the common publisher of a number of Datasets. + +Behind the scenes, Groups add an additional set of roles and permissions that ensure quality and security when publishing your data. Group roles and permissions ensure that Content Creators can add new data but only to their assigned Group. This is especially important for large sites that may have several working groups publishing data to the site. Read more about Group roles and permissions. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_29.png + :alt: An example of Groups within DKAN. + +When first adding a new Group, the form has only a few fields. This is the basic information about the Group itself that should tell site visitors what to expect from the Datasets in the Group. + +Key information when adding a Group: +------------------------------------ + +- **Title:** Name your Group to reflect the agency or whoever the common data publisher is for the datasets that will belong to the Group. +- **Image:** The image here acts like the logo for your Group. It appears on the overview Groups page as well as the individual page of the Group itself. It's best to choose a square image to fit the dimensions of the thumbnail. Whether you choose an image, a logo, or an icon you can use any image that meets the size and file type requirements. As a Site Manager, you may want to add generic icons to the Groups you add if a current logo is unavailable. +- **Body text:** This text is the full description for your Group similar to an About page. The description includes details about the agency, its goals, and information about the data it publishes. While you want to include all the relevant information of the Group, the best descriptions are 1-2 paragraphs long and include a link to the agency's main web page for more details. +- **Summary text:** You can use the Summary to create unique text for your Group. This text appears as a snippet under the Group image on the Group overview page. If left blank the first portion of the body text will be used (about 100 words). Including a summary can be useful in adding more key search terms or using a different tone to intrigue site visitors to learn more. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_30.png + :alt: This screencap displays pointers on what to do when adding a Group to DKAN. + +Adding Datasets to a Group +-------------------------- + +Once you've added a new Group, you can assign Datasets (and their Resources) to that Group. Adding a Dataset to a Group is part of the content creation process when adding a new Dataset. The final step in creating any piece of content is using the submenu at the bottom of the form to add the final administrative data to the content. In the case of Datasets that includes adding Datasets to Groups. + +When adding a Dataset to a Group, users can add a Dataset to as many Groups as there are on the site. Your groups are Groups that the user authoring the content belongs to, and Other groups are all the Groups of which a user is not a member. **All users must belong to at least one Group to have the Groups menu item available to them.** + +When a Dataset is added to a Group, it will be included on the Group's home page and may be edited by the Administrator members of a Group. As a best practice, **users should only add Datasets to Groups that they are a member.** Certain users won't be able to access their own content if they assign it to a Group that they do not belong to. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_31.png + :alt: This image shows what happens when editing a Dataset and how you have the option to add it to one of your Groups. + +Adding members to a Group +------------------------- + +Groups have members, who must be first approved, and members have different roles in the Group. A user's membership status affects how they can interact with the Group. As a Site Manager, you can add members to a Group and give members different roles. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_32.png + :alt: An example of a Group called "Advisory Council on Infectious Disease" on the DKAN demo site. + +I added my content, where did it go? +------------------------------------ + +You added new content, filled out the fields, included all the details, and then hit the Save button. Now what? + +Regardless of the type, once you click on the Save button you'll next see a preview of how your content looks. Keep in mind that once content is saved (and if it has a published status) it is live on your DKAN site. That means the content is visible to the public. Most users can only save their content and have it directly published. Only Site Managers can add content in an unpublished state. The Preview screen shows you how the content will look to site visitors, so that you can make any final quick edits before moving on. + +In the image below, you can see that the content is on the View screen and the content has just been created. This is how the Data Story will appear to a general site visitor (without the ability to edit, of course). At this point, you can get a sense of the appearance and use the In-place Editor to make any final changes. + +.. figure:: ../../images/site_manager_playbook/adding_new_content/adding_new_content_33.png + :alt: An example of a Data Story created within DKAN, with the "Customize this page" and "Change layout" buttons at bottom. + +**Manage existing content:** Once content is saved it is published and can be managed as existing content. diff --git a/dkan/docs/admin/data_and_content/content_types.rst b/dkan/docs/admin/data_and_content/content_types.rst new file mode 100644 index 000000000..5d04e9020 --- /dev/null +++ b/dkan/docs/admin/data_and_content/content_types.rst @@ -0,0 +1,135 @@ +================== +DKAN Content Types +================== + +While DKAN handles data as content along with many other types, not all content is the same. You can think of content in three different ways on DKAN: data, narrative, and curation content. Narrative and curation content support the data content published on your DKAN site. They help highlight the investment and value of open data that might not otherwise be apparent. + +Data content types +------------------ + + +Data content is specifically for publishing and managing open data. That is, the actual files in which your open data is contained. These include Resources and Datasets. + +Resources +~~~~~~~~~ + +Resources are the most basic content type on DKAN. They represent the actual file that can be viewed and downloaded by site visitors. DKAN supports a large range of file formats including csv, html, xls, json, xlsx, doc, docx, rdf, txt, jpg, png, gif, tiff, pdf, odf, ods, odt, tsv, geojson and xml. Resources may be uploaded alone, but in order to include metadata you must add the Resource to a Dataset. + +.. figure:: ../../images/site_manager_playbook/data_and_content/resources_list_on_dataset_page.png + :alt: resource list + + Example of a list of resources on a dataset page. + +Add a Resource when you're trying to: + +- Upload files of open data to your DKAN site. +- Link to data from an online, external source. +- Publish many different formats of the same data. + +Datasets +~~~~~~~~ + +Datasets are often described as "containers" because they group related pieces of data (Resources). Grouping Resources together in Datasets gives the data a common summary description, licensing information, and a unique URL to easily share the dataset directly. The image above shows the Resources, which are the actual files that can be previewed and downloaded by site visitors. + +In the image below everything surrounding the Resources is the "container", or Dataset. It includes a name for the Dataset, a description of the collection of Resources, tags, license information, the data author, and other metadata about the Resources. Resources may be uploaded alone, but metadata is associated with the dataset and cannot be individually attributed to a Resource. + +.. figure:: ../../images/site_manager_playbook/data_and_content/dataset_page.png + :alt: dataset page + + Example of a dataset page. + +Add a Dataset when you're trying to: + +- Collect Resources with common metadata (such as author, open data license information, tags, etc.) +- Create a unique URL to link site visitors directly to a Dataset. + +Narrative content types +----------------------- + +Narrative content is designed to tell the story and reveal insights of data. Narrative content allows you to add context and bring the personal elements of data out to the front. These include Data Stories and Visualizations. + +Data Stories +~~~~~~~~~~~~ + +Data Stories show the people in data. It's not always obvious how rows and columns can make a difference in the world of citizens. Data Stories help show the impact data can make in our everyday lives by adding context and synthesis through a narrative form. This content type is easy to use and similar to writing a blog post. Use Data Stories to combine narrative, media, and data for a compelling way to connect to data. + +.. figure:: ../../images/site_manager_playbook/data_and_content/stories_page.png + :alt: stories page + + Example of the Stories page. + +Add a Data Story when you're trying to: + +- Tell the story within the data on your DKAN site. +- Show the impact of data on citizens' daily lives. +- Demonstrate the value and return on investment of open data. + +Visualizations +~~~~~~~~~~~~~~ + +Visualizations on DKAN create a powerful access point for users. Visual representations of data are simpler to comprehend, regardless of technical expertise, and make large quantities of data consumable rather than overwhelming. DKAN Charts (pictured below) can also be interactive, letting site visitors toggle which data points are shown in the Chart. Use Visualizations to make your data more than just available. + +.. figure:: ../../images/site_manager_playbook/data_and_content/multiple_pie_charts.png + :alt: pie charts + + Example of the pie chart visualizations added to a Data Story page. + +Add a Visualization when you're trying to: + +- Make large datasets understandable instead of overwhelming. +- Make your data available and accessible to site visitors regardless of technical expertise. +- Use data-driven decision making for internal use. + +Curation content types +---------------------- + +Curation content types bring both data and narrative content types into conversation to create context and bring out meaning. These include: Pages, Dashboards, and Groups. + +Pages +~~~~~ + +One of the most basic content types on DKAN is a Page. Though the content type is straightforward it has implications for the structure, appearance, and experience of your DKAN site. You can think about Pages as the anchors of your site. + +With a Page, not only do you add content but you create additional space on your DKAN site. With other pieces of content, like Dashboards and Data Stories, the content is collected onto a single page. In contrast, Pages typically won't change themselves, though the content on them could change at any frequency. + +Add a Page when you're trying to: + +- Add a new space on your DKAN site for key information (like an About page). +- Add a space that itself won't change, though the contents within it might (like a Contact page). + +Data Dashboards +~~~~~~~~~~~~~~~ + +Dashboards provide the ultimate flexibility for you to give site visitors the best experience possible while also showcasing the data and content on your DKAN site. Using this curation content type, you can mix and match all kinds of content without ever touching code. + +Mix videos, images slideshows, DKAN Visualizations, text, tables, and maps to most effectively deliver your content. With more than 20 responsive layouts to choose from and our easy to use drag and drop interface, any user can create compelling data-powered content within minutes. + +.. figure:: ../../images/site_manager_playbook/data_and_content/page_layout_options.png + :alt: page layouts + + Different layouts that can be used to build Dashboards. + +Add a Dashboard when you're trying to: + +- Combine many different types of content in one place. +- Put data and narrative content in conversation to better connect open data to citizens. +- Use flexible layouts for easy content curation. + +Groups +~~~~~~ + +Groups are both a way to collect common Datasets and enable an additional workflow on DKAN. On the outward-facing side, site visitors are able to browse Datasets published by a specific Group, which is the common publisher of a number of Datasets. + +Behind the scenes, Groups add an additional set of roles and permissions that ensure quality and security when publishing data. Group roles and permissions ensure that Content Creators can add new data but only to their assigned Group. This is especially important for large sites that may have several working groups publishing data to the site. Read more about :ref:`Group roles and permissions ` . + +.. _`Group roles and permissions`: ./people.rst + +.. figure:: ../../images/site_manager_playbook/data_and_content/groups_list.png + :alt: groups list + + Example of a Groups list. + +Add a Group when you're trying to: + +- Collect and categorize Datasets by a common publisher. +- Need a workflow for Content Creators to publish data to your DKAN site within a specific Group. diff --git a/dkan/docs/admin/data_and_content/data_management.rst b/dkan/docs/admin/data_and_content/data_management.rst new file mode 100644 index 000000000..da1a640fd --- /dev/null +++ b/dkan/docs/admin/data_and_content/data_management.rst @@ -0,0 +1,193 @@ +=============== +Data Management +=============== + +DKAN supports broader data management strategies with tools that simplify and streamline data migration, storage, and usability. The tools are designed to be straightforward so that you don’t need to be a technical expert to use them. Migrate open data efficiently and effectively, store your data, and improve the overall usability of your data. + +Harvest +-------------- + +As you build up your DKAN site with content and data, you can add datasets by uploading or linking to resources and APIs. You can also “harvest” datasets from other data portals that have a public data.json or an XML endpoint. All the datasets published in the source are added to your DKAN site as the Dataset content type. + +Unlike linking to a file hosted on the web, harvested datasets are fully imported from an external source onto your DKAN site. That means that the datasets exist both on the external source and your site independently from one another with all the same information (including title, metadata, tags, etc.). + +By importing datasets from external sources, you can provide more open data on your site without manually managing the dataset content. Site visitors will see that a dataset was harvested and from which portal, promoting visibility across agencies and sectors. Harvest optimizes importing, publishing and updating imported datasets into a single streamlined process. + + +How Harvest Works +~~~~~~~~~~~~~~~~~~~~~~~ + +The source is defined (fetching) + First, identify where the datasets should be imported from. Harvest is compatible with data.json and XML endpoints, and your source may be configured before import. By default, all the datasets and their metadata are imported from a source, but you can further configure exceptions to narrow what information is included (more on that in the Harvest Dashboard section). Site Managers define a source by creating a Harvest Source as a new piece of content. + +Data is stored locally (caching) as a copy + Once the source is identified, Harvest pulls datasets and stores them on the computer’s local hard drive. This is called caching. Site Managers have two options for how cached data is handled. Datasets may be cached and migrated (step 3) automatically or they may be only cached to be reviewed and later migrated manually. You may use a different operation depending on the context and can choose on a case-by-case basis. + +Harvest adds cached data to your site (migration and publishing) + After the dataset information is cached onto the computer’s local hard drive as a JSON file, Harvest reads the file and imports it to your DKAN site. Datasets can be migrated and published to your DKAN site automatically as part of the caching operation. Alternatively, datasets can be only migrated (without caching). + +Harvest is used to check for changes to migrated datasets + Once the dataset information is imported to your DKAN site, its contents exist independently from the original source. That means changes made to a dataset on the original source won’t appear on your DKAN site unless the harvested dataset is updated. It also means that if you make changes to the dataset on your DKAN site, the changes will be overwritten when you run a harvest operation to update the file contents and metadata. + +With Harvest, you can make updates to your harvested datasets by repeating the process of fetching, caching and migrating. Harvest replaces the old information with the current datasets, updating the information to include any changes made to the original source. With defined sources, the process is a quick operation. + +Though most of Harvest works in the background, Site Managers can use the Harvest Dashboard to manage Harvest operations. + +Harvest Dashboard +~~~~~~~~~~~~~~~~~ + +Harvest Sources have special handling. The Harvest Dashboard displays all the Sources on a site and a comprehensive list of harvested datasets. + +From here, Site Managers can view Harvest Sources, Source metadata such as date last updated and number of datasets in the Source, view harvested datasets individually, filter and search Harvest content, and perform bulk operations on Harvest content. + +The Harvest Dashboard is also used to perform Harvest operations, edit and configure a Source, check the status of a Source, and manage the datasets in a Source. + +Harvest operations +~~~~~~~~~~~~~~~~~~ + +Site Managers use special operations on the Harvest Dashboard to manage the harvesting process for existing Sources. From the Sources tab, Sources may be cached, migrated, harvested (cached and migrated) or deleted. + +Cache Source(s): + This operation parses the Source endpoint (either data.json or XML) stores a subset of the Source data (reflecting parameters set by the Source configuration) on a computer. Caching data from the Source endpoint pulls the latest data, so the datasets on your DKAN site are current. + +Migrate Source(s): + Migrating a Source imports cached data from local computer storage and uploads files as content to your site. For existing Sources, the new data will replace what was previously published or create a new dataset if it wasn’t previously published to your site. + +Harvest Source(s): + The harvest operation combines the cache and migrate operations for a single, streamlined process. This option automates some of the work that would otherwise be done manually, but it also removes the ability to review datasets before migrating to your site. + +Delete Source(s): + By deleting a Source, all the datasets associated with the defined endpoint are removed from your DKAN site. This is a permanent change. + +Edit and configure a Source +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The edit view of a Source opens the same options available when first adding a new Harvest Source. + +Here, you can change the basic information about a Source, like the title and the URI. The basic information of a Source doesn’t typically change once it’s set. + +In this same view, Site Managers configure harvests with filters, excludes, overrides, and defaults. With these options, Site Managers can customize what information is pulled from a Source and how metadata values are handled during the harvesting process. + +Filters: + Filters restrict which datasets imported by setting a pair of key values. For instance, if you are harvesting from a data.json endpoint and want to harvest only health-related datasets, you might add a filter with "keyword" in the first text box, and "health" in the second. With this configuration, only datasets that meet the stated criteria are imported. + +Excludes: + Excludes are the inverse of filters. Values in this field determine which datasets are left out of an import, while all other datasets are included. For example, if there is one publisher included in a Source whose datasets you do not want to bring onto your site, you might add "publisher" in the first text box and "Office of Public Affairs" in the second. + +Overrides: + Values included in the Overrides field will replace metadata values from the Source as it’s migrated in a harvest. For example, to change the name of the publisher, you might add "publisher" in the first text box to be replaced by the value in the second text box, like your own agency’s name. + +Defaults: + In some cases, datasets from a Source may not have all metadata fields filled with a value. Use defaults to replace an empty field. For example, the first box might designate the License metadata value to be replaced if empty. The second box designates which value should replace it, like “Creative Commons”. + +Check the status of a Harvest Source +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As Sources go through the harvesting process, Harvest captures the details and displays the results. After a Harvest Source is created and the datasets harvested are published to your DKAN site, the original source may change. Datasets may be added, removed, edited, and otherwise modified. These changes are reflected in a Harvest Source when a harvest operation is performed as part of the status of that Harvest Source. + +There are two places to find specific details about a harvest operation on the Harvest Dashboard: the Events tab and the Errors tab. + +Events: + Each Harvest Source has an event log under the Events tab. When a Source is harvested, the process is recorded as an event. Sources are updated by running the harvest operation, so there may be several events recorded and detailed in this log. The event log is helpful for checking harvest events and getting the status breakdown on the most recent harvest, the number of new datasets created, datasets updated, datasets that failed to upload, datasets that have become “orphaned” on your site, and unchanged datasets. + +Errors: + Harvest Sources have an error log under the Errors tab to display the details of when a harvest encounters and error with the Source or a dataset in the Source. Error messages appear individually with the time and date it occurred as well as a message for the likely cause of an error. Details in the error log help identify the specifics of an error and find the best solution. + +Manage Harvest Source datasets +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Though harvested datasets appear alongside directly-published Datasets on your DKAN site, it’s best practice for Site Managers to manage harvested datasets with the Harvest Dashboard. The Harvest Dashboard provides more specific information like when a dataset was updated from a harvest, its “orphan” status, and its Harvest Source. + +Site Managers can either permanently delete or unpublish (recommended) harvested datasets. + +Managing orphan datasets +~~~~~~~~~~~~~~~~~~~~~~~~ + +After a Source is harvested, the datasets belonging to the source may change and may be deleted all together. When a dataset is deleted from the Source, but remains published to your DKAN site, the dataset is considered an orphan. + +Because the Source no longer contains the dataset, it isn’t updated as part of a harvest operation. But it isn’t deleted from your DKAN site automatically. Site Managers must make a judgment call on whether to delete the dataset and stay aligned with the Harvest Source, to unpublish the dataset and hide from public view, or to keep the dataset as a stand-alone dataset that won’t be updated through a harvest operation. + +Visit the Adding Content section to learn how to add a Harvest Source. + +Datastore +--------- + +DKAN comes standard with a Datastore to house tabular data imported from your CSV files on DKAN. That is, the Datastore can support files with contents that appear as a table (rows and columns). You can think of the Datastore like a basic database. Files that are imported to the Datastore have the contents of the file copied into a table in the Datastore, and the Datastore as a whole is composed of all the tables copied from imported files on DKAN.The Datastore processes data, stores the contents of Resources (if CSV), and makes them ready to be queried. + +As a Site Manager, you can manage the Datastore by adding and removing files from the Datastore. In most cases you want all CSV files included in the Datastore to support better data previewing, large files, and a more robust API. + +Managing the Datastore +~~~~~~~~~~~~~~~~~~~~~~ + +In broad strokes, managing the DKAN Datastore is deciding which Resources to include in the Datastore. There isn't any management further than that, and every user has the ability to import and remove Resources they've authored. As a Site Manager, you can import or remove any Resource regardless of the author. This allows you to manage what data is included in the Datastore API. + +There may be some sensitive data that should not be included in the Datastore, but in general we recommend increasing your transparency and usability of your data by importing every Resource possible into your Datastore. + +Importing and removing files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Uploading files to the Datastore has major benefits including enhancing the Datastore API and improved user experience of previewing data. The Datastore API makes the Resources more usable and accessible to technical users. Previews display resources as graphs, grids, or maps for geospatial data. In some cases files contain thousands (or millions) of rows. For data on such high order, users can only properly preview the data if the Resource has been imported into the DKAN Datastore. + +.. figure:: ../../images/site_manager_playbook/data_management/resource_page_with_datastore_message.png + :alt: Your file for this resource is not added to the datastore. + + Above is what you should see on a resource page if your Resource file has not yet been added to the datastore. + +.. figure:: ../../images/site_manager_playbook/data_management/manage_datastore_page.png + :alt: manage datastore page + + Above is what you should see when you select Manage Datastore. + +**When to import:** + +- The file is formatted as a CSV. +- The file is very large (and formatted as a CSV). +- To include the file in the Datastore API. + +Importing ++++++++++ + +Once a Resource is added, you can import the file into the Datastore. Click the Manage Datastore button at the top of the screen to open the options included for importing a file into the Datastore. From the import screen, you can select the options that best reflect the contents of your data. By default, DKAN is set to match common data formatting practices. + +In the example below, the Site Manager is importing a Resource into the Datastore from the Manage Datastore page. From the Import tab, the Site Manager selects the delimeter and leaves the rest of the default settings for import. After clicking the Import button at the bottom of the page, the contents of the Resource are now included in the DKAN Datastore as well as the Datastore API. + +.. image:: ../../images/site_manager_playbook/data_management/datastore_import_animation.gif + :alt: animation of datastore import + +Removing +++++++++ + +If you need to remove a Resource from the Datastore you’ll make this change directly from editing the Resource on the Manage Datastore screen. You have two options for removing the contents from the Datastore: + +Delete items + By deleting items, the values are removed from the Datastore. However, the table itself generated by the file import still exists. In this sense, you can think of the file as imported to the Datastore but empty. Again, the CSV file on your DKAN site is separate from the Datastore. By deleting the values in the Datastore, your file won’t be changed. + +Drop Datastore + This option removes both the values in the file as well as the table generated upon import. In this sense, the file is not imported. If you don’t want the contents of a file in the Datastore, we recommend this option. + +.. image:: ../../images/site_manager_playbook/data_management/datastore_actions.png + :alt: delete and drop options + +Updating +++++++++ + +When you import a Resource to the Datastore, the contents of the associate file are copied and added to the Datastore. If the file is changed, the Datastore is not automatically updated with the contents of the new file. If you update a file associated with your Resource, you will also need to update the Datastore by importing the file again. All the old data will be overwritten with the contents of the new file. + +Using Fast Import +~~~~~~~~~~~~~~~~~ + +For datasets with thousands (or millions) of rows, the size of the file increases quickly. By default, DKAN processes the contents of a file before importing to the Datastore. The processing checks that the contents match delimiter, file encoding, etc. for a smooth import. + +Large file sizes can delay the time it takes to import a file into the Datastore as more information needs to be processed before it can be imported. + +.. image:: ../../images/site_manager_playbook/data_management/datastore_import_options.png + :alt: datastore options with fast import + +With the Fast Import option, the time to upload a large file is dramatically reduced. The contents of a file are not processed and directly imported to the Datastore, so files that otherwise might take hours to import only take minutes. + +For smaller files, we recommend using the standard processor and import. When large files must be imported, check the Use Fast Import checkbox to skip the processing and directly import. + +Special Note: This capability is not enabled by default and requires the DKAN Datastore Fast Import module to be enabled. Please contact your site administrator or developer for assistance. + +.. image:: ../../images/site_manager_playbook/data_management/datastore_fast_import_option.png + :alt: datastore import options close up diff --git a/dkan/docs/admin/data_and_content/dkan_apis.rst b/dkan/docs/admin/data_and_content/dkan_apis.rst new file mode 100644 index 000000000..edb97ead5 --- /dev/null +++ b/dkan/docs/admin/data_and_content/dkan_apis.rst @@ -0,0 +1,66 @@ +.. _`user-docs DKAN APIs`: + +========= +DKAN APIs +========= + +In the same way that data on a DKAN site is made accessible to general users through sensory devices like visualizations, dashboards, and data stories, DKAN APIs are essential to developers. DKAN comes with three API’s, the Dataset API, the Datastore API, and the Dataset REST API. These can be queried to discover metadata associated with the catalog or a specific dataset. It can also be harvested by other portals by complying with the API standard data.json. + +Datastore API +------------- + +The DKAN Datastore houses any CSV files that have been uploaded and then imported into the Datastore. One reason for importing CSV files into the Datastore is to make the file part of the public Datastore API. Allowing data from uploaded files to be included in the Datastore API greatly increases ability to discover the information as well as the usability and accessibility of the data. + +The Datastore API enables interactions with specific Resources in the DKAN Datastore down to specific rows. Without the Datastore API data could not be searched with such precision. + +With the Datastore API, technical users can write programs to interact with the information held within the API. This means that the data in the DKAN Datastore can be accurately and efficiently queried (searched) and the data then used in other contexts and applications. The Datastore API is another way to show how open data can be used to provide a tangible return for citizens. + +.. figure:: ../../images/site_manager_playbook/DKAN_APIs/datastore_tab_view.png + :alt: datastore api view + + Datastore API view on a Resource page. + +Using the API +~~~~~~~~~~~~~ + +For any Resource imported to the Datastore, click Manage the Datastore. Then click the Data API button to get information about the Resource. + +You won't perform API queries from here, but you can get linked to a sample query and find :ref:`documentation for more instruction` on how to use the Datastore API. The image below is the information returned on a sample query of the DKAN Datastore using the Datastore API. + +.. figure:: ../../images/site_manager_playbook/DKAN_APIs/datastore_api_output_unformatted.png + :alt: unformatted datastore API query + + This query shows the results in a "raw" form. This is generally more difficult to read, but it is what appears with a standard query. + +.. figure:: ../../images/site_manager_playbook/DKAN_APIs/datastore_api_output_formatted.png + :alt: formatted datastore API query + + This image shows a formatted view of another API query using a web extension to make the results easier to read. + +Dataset API +----------- + +The Dataset API works by combining a number of public, supported APIs. Each API is different in what level of detail it pulls out from the information available on a DKAN site. Together, the suite of APIs makes it possible to pull out information with varying specificity. When data is uploaded to DKAN as a Resource or Dataset, it is automatically included in the Dataset API. With the Dataset API, a public data.json file is also automatically published to follow Project Open Data standards. + +As a Site Manager, you don’t have to worry about managing the Dataset API because all the work happens in the background. At any point you can access the data.json file by simply typing /data.json in the URL after the homepage URL. You’ll get a page with all the information from the Datasets and Resources on your DKAN site. + +.. figure:: ../../images/site_manager_playbook/DKAN_APIs/dataset_api_output_unformatted.png + :alt: formatted data.json + + This shows the results in a "raw" form. This is generally more difficult to read, but it is what appears with a standard query. + +.. figure:: ../../images/site_manager_playbook/DKAN_APIs/dataset_api_output_formatted.png + :alt: formatted data.json + + This shows a formatted view using a web extension to make the results easier to read. + +Dataset REST API +---------------- + +REST continues to be one of the most popular API styles in web development, and it’s quickly becoming the standard for API design. In large part, that’s because REST is designed to be light-weight, fast, portable, and simple to implement. + +With REST APIs, external web applications and services can supplement platforms without significant investment or complexity in programmatic communication. The Dataset REST API leverages the opportunities of REST to open greater possibilities on DKAN. + +With the Dataset REST API, you can take action on your DKAN site programmatically. For example, adding a Dataset through the API. For one or two Datasets it might not seem like a drastic difference; but imagine automating the action of adding dozens, or even hundreds, of Datasets. Or imagine you have an application built in-house that you want to integrate with DKAN. The Dataset REST API makes these actions (and many more) possible. + +We have :ref:`technical documentation on the Dataset REST API` that provides more information on how to use it. diff --git a/dkan/docs/admin/data_and_content/index.rst b/dkan/docs/admin/data_and_content/index.rst new file mode 100644 index 000000000..fa7ab82e9 --- /dev/null +++ b/dkan/docs/admin/data_and_content/index.rst @@ -0,0 +1,19 @@ +================ +Data and Content +================ + +On DKAN the data you publish for site visitors is handled as content. Treating data like content makes it easier for general site visitors to consume information and accessible for people. + +Equally important is making your open data accessible for computers (ie machine-usable). Technologists leverage this access by developing applications to interact with your open data programmatically. This opens an entire realm of possibilities. + +DKAN is provides tools for generating content for the technical and non-technical users of your open data site, along with tools for Site Managers to monitor and manage that content. The following sections explain all of those capabilities. + + +.. toctree:: + :maxdepth: 2 + + content_types + adding_new_content + managing_existing_content + data_management + dkan_apis diff --git a/dkan/docs/admin/data_and_content/managing_existing_content.rst b/dkan/docs/admin/data_and_content/managing_existing_content.rst new file mode 100644 index 000000000..3b1385487 --- /dev/null +++ b/dkan/docs/admin/data_and_content/managing_existing_content.rst @@ -0,0 +1,173 @@ +.. _`user-docs managing existing content`: + +========================= +Managing Existing Content +========================= + +In smaller organizations, Site Managers may both be writing and editing their own content to then directly publish the content to the live site. Larger organizations may have people in other roles like Editors and Content Creators to help with handling a large mass of content on the site. Depending on the scale of your organization and volume of content, you may spend more or less time directly handling content. Learn more about user roles in the :ref:`People` section of this guide. + +Where do I edit existing content? +--------------------------------- + +Site Managers can edit any content on the site, either from the main Content page or directly on the piece of content itself. + +Edit from the Content menu +----------------------------- + +The main Content page is the most comprehensive place to find and access content to edit an individual piece. Though the menu is comprehensive, editing the details of a piece of content can only happen one at a time. From the Admin Menu, click on the **Content** link to access all the content that exists on the site. + +As the Site Manager, you have access to create all content types possible as well as edit, unpublish, and delete all existing content regardless of who the author is. You can create new content from this page as well as manage all the existing content and files on your DKAN site from here. Files include things like images, videos, font files for icons, other graphics, etc. + +In any scenario, as a Site Manager you can use this page to look at the content on the site to see who created a particular piece of content, when it was last updated, its status (published or unpublished) and take action on existing content. + +.. image:: ../../images/site_manager_playbook/managing_existing_content/content_admin_menu.png + :alt: highlighted content option in admin menu + +Which content, when? +-------------------- + +Oversight over the details of content typically falls to the Editor role, but depending on the size of your team the Site Manager may play multiple roles and handle more content review and revision. Ultimately the quality of the content on your DKAN site falls to you as the Site Manager. + +When any user creates a new piece of content it defaults to a published state. That means the content automatically appears on the live site, visible to the general public. Because there isn't a technical review process on DKAN, you'll need a system for reviewing content before it is published as well as system for checking content that is published. + +Though you might not edit every piece of content, you'll generally review all the content that is visible to the public (in a published state) and make edits whenever necessary. Only Site Managers have the ability to edit or delete any piece of content regardless of the author, so use your best judgment when reviewing and editing content. If you're ever unsure, you can unpublish the content and go back to the author before making changes or removing the content. + +.. image:: ../../images/site_manager_playbook/managing_existing_content/content_admin_page.png + :alt: content administration page highlighting admin menu option, add content button, search, and content list + +Find content +--------------- + +Your DKAN site may have hundreds, or even thousands, of pieces of content from Resources to Data Stories; and as a Site Manager you'll have access to every piece of content. You can sift through the content and use filters on the Content main page to find content effectively. Filters help narrow your search by a set of criteria. On the Content main page, there are two types of filters to narrow the results: status and type. + +Status + Choose from the status drop-down menu to show content that fits a specific status, like published or unpublished. The other options on this list, like promoted and sticky, are not typically used. +Type + The type of content includes all the content types that may be added to your DKAN site. Choose from the type drop-down menu to select the content type to show only content that fits the specific type, like Resource or Data Story. + +.. image:: ../../images/site_manager_playbook/managing_existing_content/content_status_dropdown.png + :alt: content search by status dropdown options +.. image:: ../../images/site_manager_playbook/managing_existing_content/content_type_dropdown.png + :alt: content search by type dropdown options + +Edit from the page +------------------ + +As you navigate through your DKAN site, you have more options available to you as a Site Manager than other users. You'll see these options on every page including an option to edit while on the page of a piece of content. You can edit directly from the page by clicking the **Edit** button. The options for editing content are the same as when adding new content, and the form appears the same. + +In general, it's okay to make small changes to content while it's published. Small changes include adding Tags and Topics, adding or removing the content from a Group, spelling and grammar corrections, styling, and other minor updates. + +For major changes to any piece of content, it's best to first unpublish the content and continue to make changes behind the scenes. You can change the status of the content by unchecking the **Published** box in the administrative submenu at the bottom of the form. Major changes include changing the title, changing the layout, adding new information that needs review, adding or changing images, and any other changes that aren't ready to be published immediately. + +.. figure:: ../../images/site_manager_playbook/managing_existing_content/edit_dataset_animation.gif + :alt: animation of editing a dataset + + In this example, a Site Manager visits a Dataset page and decides to edit the content. The Site Manager clicks on the **Edit** button to open the form and make changes to the Dataset. + +View changes +------------ + +When editing content, a user is making changes to something that is published and visible to the general public. Before saving the changes, you can see exactly what changes have been made in a summary form to check that all the changes are correct. Use the View changes button at the bottom of the page of any piece of content to get the breakdown. + +The changes are organized into two columns and sectioned off further by the different parts of the content for a side-by-side comparison of what has changed in the piece of content. On the right side, there is the column with the original version (called Original). On the left side, new additions are added to the Changes column. + +.. image:: ../../images/site_manager_playbook/managing_existing_content/dataset_changes_view.png + :alt: example of viewing dataset changes + +Original + The column titled Original shows what information was in the original version before any changes were made. It contains information that has been removed or, alternatively, what remains when new information is added. The column is further organized into the different fields that make up the content form. These fields include the body text, Topics, Tags, metadata, Groups, etc. so you can see exactly where changes were made. When information is removed, the changes are highlighted in yellow and have a minus sign to the right-hand side. If information remains when new information is added, then the information appears in the Original column, but it's not highlighted and there is no minus sign. In that case, there should be new information in the Changes column. +Changes + The column titled Changes shows what information will appear in the new version once changes are saved. It contains information that has been added or, alternatively, what remains if information is removed. + +.. figure:: ../../images/site_manager_playbook/managing_existing_content/dataset_changes_view_with_additional_edits.png + :alt: example of viewing dataset changes with changes to topics + + In this example, a Topic has been removed and a new Topic added. In the Changes to Tags section, you can see that the "trees" Tag was removed. The Changes column shows the information that will be included in the new version (everything that wasn't removed). + +Revisions +--------- + +Revisions is a powerful capability, especially when working on content that undergoes several changes. Revisions help track and record changes to create a backup of a piece of content, but they're not automatically generated every time a change is made. Create a new revision any time that a significant change is made to create versions of a piece of content. This will create a safety net in case anything major needs to be reversed. It will also document institutional knowledge as there are personnel changes at your organization. + +Keep in mind that once you delete a piece of content, you also delete its revision history. We suggest unpublishing content, rather than deleting it, so that it's not visible to the general public but still exists on your site behind the scenes. + + +Create a new revision +~~~~~~~~~~~~~~~~~~~~~ + +Once a piece of content has been published, you can go back and make changes to the content as needed. When you make a change, you have the option to create a new revision of the content. This creates a new version with the changes incorporated, but also keeps the old version. In general, you don't need to worry about creating a new revision for minor changes unless the information being added is critical. For bigger changes, it's helpful to have a backup especially if you're editing content for someone else. + +Click the **Edit** button to open the content form and go to the bottom of the page. In the Revision information tab, click the option labeled **Create new revision**. This is all you need to create a new version for the piece of content. + +Notice there's another field below the new revision option labeled Revision log message. This is a space to explain the changes you're making and why. This is particularly useful for content that goes between multiple authors. Giving an explanation for changes can help clarify reasons that might not be obvious which helps reduces confusion and mistakes that can be easily avoided. + +.. image:: ../../images/site_manager_playbook/managing_existing_content/content_revision_information.png + :alt: revision information options + + +.. figure:: ../../images/site_manager_playbook/managing_existing_content/content_revision_information_animation.gif + :alt: animation of adding revision information + + In this example, the Site Manager is creating a new revision and includes an overview for what was changed in the Revision log message field. The Site Manager saves the changes, and then finds the new revision on the Revisions page. + +Where to find revisions +~~~~~~~~~~~~~~~~~~~~~~~ + +You can access all the revisions of a piece of content by going directly to the page of the published content in View mode. Click the Revisions button to get to the Revisions page to see all the existing revisions and the revision options. The Revisions page gives an overview of all the existing revisions including when the revision was created, by which user, and the revision log message. Here, you can also compare revisions and go back to an old revision (reverting). + +.. image:: ../../images/site_manager_playbook/managing_existing_content/content_revisions_tab.png + :alt: highlighted button for viewing revisions + +Revision options +~~~~~~~~~~~~~~~~ + +From the Revisions page, there are additional options for what you can do with the different revisions for the piece of content. The most important options are Compare and Revert. + +.. image:: ../../images/site_manager_playbook/managing_existing_content/content_revisions_tab.png + :alt: content revisions view + +Compare + Some content may have several revisions that are difficult to visually scan what the differences are. To get a clear sense of the distinction between two revisions, you can select revisions to compare on after the other. Click on the selection circle and then click the Compare button at the top of the columns. You'll see more details of each revision in comparison with one another. +Revert + As changes are made, you may not create a new revision each time. Revisions typically reflect significant changes to your published content, so lots of small changes can be made in between the previous and current version. You can go back to an older version of a piece content by clicking the Revert link under the Operations column in the row of the revision. Before reverting, it's best to create a new revision of the content with the most recent changes. The most recent revision will still exist in the list of revisions, but you can revert to an older revision, which is what will appear on your DKAN site. + +Managing content on DKAN +-------------------------------------- + +After you add a piece of content you may want to make changes or updates or you may want to replace a piece of content all together. As a Site Manager, you can make changes to any piece of content regardless of the author, type of content, or state of the content. Creating and editing content on DKAN are critical functions of management, and there are even more ways to manage your content. + +Content visibility +------------------ + +In general, most content is published at the same time it's added. Once content is published it appears on your live DKAN site meaning that it can be searched and discovered by the general public. But if you want to work with content without making it public or if you just want to keep a piece of content rather than delete it but don't want it visible on your DKAN site, you can change the visibility. + +There are two states that content can be in that determines its visibility to the public, published and unpublished. + +Published content + Published content is live on your DKAN site and visible to the public. In some cases, you may want to access and change content that was not created recently. You can visit published content on your DKAN site and edit directly from the page for quick changes (spelling, typos, titles). For bigger changes, it's best to not edit live content. First unpublish the DKAN, make changes, and then publish again. +Unpublished content + If content is unpublished that means that it doesn't appear on your live DKAN site, but it still exists behind the scenes. Users can leave content unpublished if they have significant changes or if they want to come back to a piece of content later to finish editing. + + As a Site Manager, you can access all the existing content on your DKAN site through through the Content menu item on the Admin Menu bar. Once you unpublish a piece of content, that content is no longer visible to users with lower permissions (even if they are the author). + + +When content is added, by any user, the content defaults to a published state. Users with fewer permissions can edit the content or delete it, but they can't unpublish content or view unpublished content, even if they authored the content. That means that the content is left visible on your DKAN site until the author makes changes. + +In some cases the changes may be minor revisions, but other scenarios could require heavy editing before the content is ready to be made public. Some content is simply time-sensitive; the information is authored ahead of time but shouldn't be made public until a certain date. Publishing states let you manage the visibility of your content to give Site Managers greater control over the content that appears on your DKAN site. + +Bulk actions +------------ + +Some changes are general and can be applied to multiple pieces of content at the same time. You can use the Update options menu to make changes to content by checking all the pieces of content you want to make updates, selecting an update option, and clicking the Update button. The most frequently used actions for bulk actions on content are unpublishing content and deleting content. + +.. figure:: ../../images/site_manager_playbook/managing_existing_content/editing_bulk_content_animation.gif + :alt: animation of content bulk edits + + In this example, a Site Manager is selecting multiple pieces of content to have a common action taken on all the content—a bulk action. The Site Manager then chooses the unpublish option from the drop-down Update options menu and clicks the Update button to finalize the action. + +Deleting content +---------------- + +In general, we don't recommend deleting content. On DKAN, once content is deleted there is no way to recover it. You want to be completely sure of your decision before making it permanent. + +A better practice is to unpublish content, which keeps the content on the site but doesn't appear to the general public. If you decide that deleting a piece of content is the best action, you can delete a single piece of content from the Content main page using the delete link in the Operations column or directly from the page while in Edit mode using the Delete button at the bottom of the page. You can also delete multiple pieces of content using bulk actions. diff --git a/dkan/docs/admin/index.rst b/dkan/docs/admin/index.rst new file mode 100644 index 000000000..a9883c019 --- /dev/null +++ b/dkan/docs/admin/index.rst @@ -0,0 +1,41 @@ +================== +Site Manager Guide +================== + +.. warning:: + **We are in the process of migrating our legacy, user oriented documentation to this site. There are some new changes to DKAN that have not yet been updated in this documentation, so there may be some inconsistencies with how DKAN works in the latest version. There may also be some formatting issues that still need to be corrected as we transer the documentation from the previous system. Thanks for your patience!** + +The Site Manager role is the highest non-technical role available on DKAN sites. Users assigned to this role need a good understanding of how DKAN works, and what administrative actions may be necessary to support the site and its users. + +**I'm a Site Manager, what do I need to know?** + +The role of *Site Manager* is broad. You'll have access many parts of the site and will need to know what's happening at a high level, but typically a Site Manager isn't dealing with the finer details of content management. + +Other roles, like *Editors* and *Content Creators*, focus on maintaining high quality data and narrative content that both follow standards as well as engage site visitors. Get more information about different user roles in the :ref:`People section` of this playbook. + +As a Site Manager, you build the framework that other roles operate within and build on. With that structure in place, you can focus on the overall experience site visitors have as they navigate your Open Data site. A Site Manager's objective is to make open data meaningful by reaching citizens and connecting them to the right data at the right time. + +**What does a Site Manager handle?** + +Data and Content + One of the biggest pieces of a DKAN site is of course the data itself. A Site Manager can decide how users can add data and create content, and use special visual tools to showcase the stories and insights gained from datasets. + +People + Data and content management can't be done alone. Site Managers handle all the users on the site and decide who has access to what. They can also create Groups for organizations, which have :ref:`even more possibilities for roles and permissions`. Build your team to build your site. + +Structure + Creating new Pages, DKAN Topics, creating Groups, etc. are all forms of structure on a DKAN site. Use these structure types to create a framework for other users to operate within and build upon. + +Appearance + You can make your DKAN site look and feel completely aligned with your organization to give site visitors the best possible experience while going through the site. Add your logo, change page layouts, customize the Home page, or pick out the right fonts to match your brand. + + +.. toctree:: + :maxdepth: 1 + + account_access_and_setup + appearance + data_and_content/index + people/index + structure + admin_menu diff --git a/dkan/docs/admin/people/adding_new_users.rst b/dkan/docs/admin/people/adding_new_users.rst new file mode 100644 index 000000000..d2d812c12 --- /dev/null +++ b/dkan/docs/admin/people/adding_new_users.rst @@ -0,0 +1,26 @@ +================ +Adding New Users +================ + +Adding a user +------------- + +As a Site Manager, a core piece of your role involves adding users to the site. On your DKAN site you may have generic roles like Authenticated User register for an account that simply needs approval from the Site Manager. But trusted roles with access to content like Content Creators and Editors must be created by a Site Manager. The user can change most of the information on their profile once they access the site, but you’ll need to initially provide basic information like a username and password. + +.. figure:: ../../images/site_manager_playbook/adding_a_user/adding_a_user_01.png + :alt: Image displaying the location of the People button at the top of the screen. + +You can add new users by clicking on the **People** link and choosing the Create user menu item for quick access or the main People page. + +.. figure:: ../../images/site_manager_playbook/adding_a_user/adding_a_user_02.png + :alt: Image displaying the "Create User" screen on DKAN. + +Key information when adding a new user +-------------------------------------- + +- **Username:** Create a unique username to create a new user account. The user can change their username once they’re logged in as long as it’s still unique, but you’ll have to choose a name to begin with for the user to first access the site. +- **Email address:** This is how the user will be contacted with notifications about their account and how they can recover a lost password. Choose an email that they are likely to check on a regular basis. +- **Password:** The user should change whatever you originally enter for the password, but you’ll need to choose the initial password so that the user can login to their account and change the profile information. +- **Roles:** As you’re adding a new user you’ll choose which role that person should have from the list of user types detailed in another section. Choosing a role might be obvious in some cases, but in other cases it may be less clear. The role you assign will depend on how much a person needs to do with the site. Higher-level access roles automatically have all the permissions of lower-access roles, but in general we recommend erring on the side of lower-access. + +Once you click the **Create new account** button at the bottom the page, the account is created and can now be managed with other existing user accounts. diff --git a/dkan/docs/admin/people/dkan_user_accounts.rst b/dkan/docs/admin/people/dkan_user_accounts.rst new file mode 100644 index 000000000..4e2e3ec82 --- /dev/null +++ b/dkan/docs/admin/people/dkan_user_accounts.rst @@ -0,0 +1,104 @@ +================== +DKAN User Accounts +================== + +On DKAN, what you can do on the site depends on the permissions given to the role assigned to you. These roles can range from general site visitors to trusted Editors working behind the scenes. User roles and permissions maintain the security of your site, distribute workload without compromising quality, and lead to overall better content on your DKAN site. + +Roles and Permissions Overview +------------------------------ + +There are 6 standard roles with set permissions. The following is a list of each role with a description of its purpose and a general description of what the role is able to do. Multiple roles can be assigned to a user, but generally they are in a hierarchy where any higher level role has equal and greater permissions of a lower level role. + +Anonymous User +~~~~~~~~~~~~~~ + +This is any site visitor accessing the site who is not logged in. Anyone who is not authenticated is an anonymous user. It is sometimes useful to log out of your account to view pages as an anonymous user will see them. + +**Permissions:** + - View and search published content + +Authenticated user +~~~~~~~~~~~~~~~~~~ + +All users with login credentials have this role, but the additional functionality is limited. This role is used for a general site visitor who has created an account, but hasn't been given permission to add or edit content on the site. + +**Permissions:** + - Create a profile + +Content Creator +~~~~~~~~~~~~~~~ + +Content Creators are able to work with the actual content of your DKAN site. This role is good for a user to add their data to your DKAN site, but who doesn’t need to access more sensitive functionality. + +**Permissions:** + - Create most content (Datasets, Resources, Datastories, ...) + - Edit their own content (cannot edit content created by other users or view unpublished content) + - Add Resources to the Datastore + +Editor +~~~~~~ + +An Editor is responsible for managing content from a strategic perspective. This role is fit for a user who will create, edit, revise and delete content on a frequent basis, and should be given to a colleague with expertise on the subject matter at hand. This role is able to make changes to content and where it appears, but it doesn't go further into amidninistrative functions. + +**Permissions:** + - Add, edit and delete most content types + - Cannot create, modify, or delete Groups + - Cannot modify the roles of other users + + +Site Manager +~~~~~~~~~~~~ + +This role is the highest level possible for non-technical users. A Site Manager performs administrative functions, and is a role best suited for a supervisor, manager, or other trusted upper-level employee. The Site Manager is provided with a sweeping overview of the site as well as its content and users. However, they do not deal with the technical back-end. + +**Permissions:** + - Create, edit, and delete all content types created by any user + - Create and manage groups + - Change menu structure + - Administer users + - Configure Harvests + - Modify DKAN specific settings + +Administrator +~~~~~~~~~~~~~ + +Admins hold the highest level of all roles and permissions and have no restrictions. Administrators are able to modify settings of the underlying Drupal platform, and can modify most things of the site to meet user needs. This role is for a web professional with high technical competency and a good understanding of how Drupal works. + +**Permissions:** + - Modify themes and layouts, and enable or disable modules. + - Modify Drupal settings + +Account settings +---------------- + +Some settings in user management are automated to streamline the process of adding new accounts. From the Site Configuration menu, you can change default behaviors for users on the Account settings page. Default behaviors act for all accounts, so you want to make selections that should apply generally to most users. + +Where to change the account settings +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +From the Admin Menu, click the Site Configuration menu link (not an item on the drop-down menu). This link will take you to the main Configuration page. Of the options on this page, find the People section and click on the Account Settings link. + +.. figure:: ../../images/site_manager_playbook/people/people_01.png + :alt: The "Account Settings" link under Site Configuration. + +Account registration +~~~~~~~~~~~~~~~~~~~~ + +Decide who can register an account on your site and how with Account registration settings. On most DKAN sites, an account requires a Site Manager to create the account and login credentials for the user. But there are cases where site visitors should be able to create an account to access certain capabilities. + +Who can register accounts? Choose which users register accounts from three options: + +- **Administrators only:** With this option, only Site Managers are allowed to add new users to the site and assign roles. This option is best if you expect users to be from within your organization. +- **Visitors:** This option allows site visitors to create an account as soon as they fill out a profile and login to the site with their own password. Visitor accounts automatically assign the lowest-permissions role, Authenticated User. These permissions allow a user to create a profile and leave comments, but they don't have access to any of the content on the site. This option is not recommended unless you have measures like Captcha in place to protect from spamming. +- **Visitors but administrator approval is required:** With this option, site visitors can register an account but a Site Manager must first approve the account before a user can login to the site. Approval from an administrator (Site Manager) can help filter out fake accounts and give Site Managers greater control over who is accessing the site. + Require email verification. With this option, users first have to verify their email address before they're allowed to login. Once they verify they will be prompted to change their password. This is an additional option to include in how accounts are registered. This verification can help prevent fake accounts and spamming (recommended). + +Automatic email messages +~~~~~~~~~~~~~~~~~~~~~~~~ + +By default, DKAN comes with template responses for certain actions. You can customize these messages with your own text and by using tokens. Tokens are a way to automate certain information. Instead of typing a new username each time for a welcome message, you could simply use the users token. Click on the Browse available tokens link to see all your options. + +You can also manage notifications of messages in this menu. You can optionally send a notification when certain actions are taken, but not all of these templates are automatically sent. You’ll want to review the email options to make sure the settings meet your needs. + +.. figure:: ../../images/site_manager_playbook/people/people_02.png + :alt: Screenshot of the Account Settings screen where you can modify emails sent to users. diff --git a/dkan/docs/admin/people/dkan_workflow.rst b/dkan/docs/admin/people/dkan_workflow.rst new file mode 100644 index 000000000..2f7130401 --- /dev/null +++ b/dkan/docs/admin/people/dkan_workflow.rst @@ -0,0 +1,166 @@ +.. _`user-docs dkan workflow`: + +============= +DKAN Workflow +============= + +DKAN Workflow is an advanced feature that opens up additional functions to manage an editorial review process for the content on a DKAN site. It also adds a new set of user roles and permissions to distribute the work associated with a review process. + +While there are usually only one or two Site Managers maintaining the entire site, content can be added by dozens of different users. In some cases the amount of content that needs review and management may be on an order that cannot be done by just one or two people. DKAN Workflow helps ensure quality content by introducing a review process, and it distributes the workload with unique Workflow roles and permissions. + +Special Note: This feature is not enabled by default and requires the DKAN Workflow module to be enabled. If you are interested in getting DKAN Workflow, please talk to your site administrator or developer. + +Workflow and the Editorial Process +---------------------------------- + +Data portals can house thousands of files in the form of Resources organized into Datasets, and these Datasets and Resources may originate from a variety of departments and organizations. While there may be one or two Site Managers maintaining the entire site, content may be added by dozens of different users. This empowers agencies to add their data as it becomes available and allows for updating the data portal to be a sustainable endeavor. + +On the other hand, broad contributions add a complicating factor for Site Managers. Contributors from different Groups can add data to the site, but these users may be unfamiliar with open data standards and less knowledgeable about handling data in general. + +DKAN Workflow introduces an editorial process to ensure quality control at any scale. Workflow creates a moderation queue so that content is published only after a designated supervisor has reviewed and approved it. Contributors can still add content to the data catalog, but it is up to a supervisor to act as the gatekeeper in making the content public on the live site. + + +Workflow Roles and Permissions +------------------------------ + +Each user on a DKAN site will have a role (or multiple roles) and have certain permissions for moving content through Workflow. These roles allow users to interact differently with My Workbench, but they do not negate the need for core user roles. This means that every user must be assigned a core role granting a certain level of access to the site, independent of the user's Workflow role. Read about :ref:`user management in the Site Manager Playbook` for additional details. + +Core roles/permissions and Workflow roles/permissions serve different purposes but complement one another. Each set of roles has different permissions that enable the user to interact with certain functions on DKAN. As Workflow roles are assigned, the core role equivalent is automatically selected so that there are no gaps in a user’s permissions. + +There are three roles with Workflow-specific permissions: Workflow Contributor, Workflow Moderator, Workflow Supervisor. + +Workflow Contributor +~~~~~~~~~~~~~~~~~~~~ + +The Workflow Contributor role has the lowest level of permissions while still gaining access to My Workbench. These users add content to the data catalog, but their content needs approval before it is published and made live. Workflow Contributors can save content as a Draft or move it to Needs Review, but they do not have the power to publish content live. + +Workflow Contributors will be assigned the core role of Content Creator. + +Workflow Moderator +~~~~~~~~~~~~~~~~~~ + +The Workflow Moderator reviews the bulk of content that has been added by Workflow Contributors for a single Group and moves it through the publishing pipeline. This role reviews and publishes content--including what they have created themselves--for their Group, rather than the entire site. Read more about how Groups work in the `Group Roles and Permissions section`. + +Moderators can also unpublish content, leaving it in a Needs Review or Draft state and removing it from public view, or delete content altogether. Workflow Moderators will be assigned the core role of Editor. + +Workflow Moderators ensure that data uploaded to the site does not have any sensitive or private information included within it. They also check whether the file format is listed correctly, that the Resource follows open data best practices, and that it is associated with the correct licenses. Lastly, the Workflow Moderator should look over the Dataset or Resource’s metadata to ensure accuracy and completeness. + +Workflow Supervisor +~~~~~~~~~~~~~~~~~~~ + +The Workflow Supervisor role has the highest-level permissions within Workflow because users with this role are not restricted to Group to which they belong. + +Unlike a Moderator, Supervisors can access content from all Groups and moderate content as needed. However, the primary focus of the Supervisor is overseeing My Workbench for the entire site. In general, this is an administrative role rather than a practical one. Supervisors catch any issues that could otherwise fall through the cracks, especially in the case of content that isn’t associated with a specific Group. + +Workflow Supervisors will be assigned the core role of Site Managers. + +My Workbench +------------------ + +My Workbench provides additional content management via a system of “states”. A piece of content could be in either a “draft” state or a “needs review” state before ultimately being published. “Transitions” define in which order content can move from state to state, and who has permissions to do so. As content is drafted, it goes through an editorial workflow managed by trusted roles. + +Content exists in three states: + +Draft + A saved work in progress. +Needs Review + The author feels the content is ready to go on public on the live site, and would like the supervisor to review it. +Published + The content is public and visible on the live site. + +My Workbench stores unpublished content in the Draft and Needs Review states, while Workflow roles give certain users the ability to moderate content through the editorial workflow. Users can view the state of the content as well as its age. + +DKAN Workflow organizes content into five different tabs: My Content, My Drafts, Needs Review, Stale Drafts, and Stale Reviews. + +The Stale Drafts and Stale Reviews tabs contain content that has gone untouched for too long. The default time limit is 72 hours before drafts become stale. + +.. image:: ../../images/site_manager_playbook/workflow/my_workbench.png + :alt: my workbench view + +For Workflow Moderators reviewing a steady stream of content it’s helpful to know how many pieces of content need to be moderated. In the picture above, note that each tab has a bubble with a number located in the top right corner. This number reflects the total pieces of content within that tab. + +For example, a Workflow Moderator may have two drafts and 10 pieces of content in the Needs Review tab. Two of those drafts may have gone stale and would also appear in the Stale Drafts tab. Three of the reviews may also be stale and would appear both in the Needs Review tab as well as the Stale Reviews tab. The quantities of content within each category will appear as a count at the top of each tab. + +Workflow Roles and Permissions At-a-Glance +------------------------------------------ + +Users assigned a DKAN Workflow role are automatically assigned the corresponding level of core DKAN role. The following is the relationship between the roles. + +.. list-table:: + :stub-columns: 1 + + * - Core Role + - Content Creator + - Editor + - Site Manager + * - Workflow Role + - Workflow Contributor + - Workflow Moderator + - Workflow Supervisor + +Overview of workflow permissions: + ++---------------+-------------------------------------+---------------------------------------------------------------------------------------------------+ +| Tab Name | Role (Users that can view the tab) | Tab Function | ++===============+=====================================+===================================================================================================+ +| My Content | All Workflow Roles | All of the content that a user has authored, in any publishing stage. | ++---------------+-------------------------------------+---------------------------------------------------------------------------------------------------+ +| My Drafts | All Workflow Roles | All of the user's own drafts. | ++---------------+-------------------------------------+---------------------------------------------------------------------------------------------------+ +| Needs Review | All Workflow Roles | For Workflow Contributors, this will be content that they have moved to the Needs Review state. | +| | | | +| | | Workflow Moderators see Needs Review content for their specific Group. | +| | | | +| | | Workflow Supervisors see Needs Review content for the entire site. | ++---------------+-------------------------------------+---------------------------------------------------------------------------------------------------+ +| Stale Drafts | Workflow Moderators and Supervisors | All drafts that are more than 72 hours old. | ++---------------+-------------------------------------+---------------------------------------------------------------------------------------------------+ +| Stale Reviews | Workflow Moderators and Supervisors | All Needs Review content that has been in that state for more than 72 hours. | ++---------------+-------------------------------------+---------------------------------------------------------------------------------------------------+ + +Using Workflow +-------------- + +Add Content +~~~~~~~~~~~ + +Adding content with Workflow enabled is similar to the general process for adding content. + +1. From the **Admin Menu** hover over the **Add Content** menu link. +2. From the drop-down menu, select the content type to add. By default, only Resources and Datasets may be moderated as part of Workflow. +3. Fill out the details of the content type. +4. At the bottom of the page, click the **Publishing options** menu item. +5. In this menu, users can change the state of the content. Workflow Supervisors and Moderators can directly publish content, but Contributors may only save content in the Draft or Needs Review states. +6. Choose the state of the Content and click the **Save** button. + +If the content was saved in a Draft state or moved to the Needs Review state, it will appear in the user's My Workbench. Users can draft content to come back to or move it to the review phase by changing the moderation state at any time. + +Content may cycle back and forth between draft and review as it goes through the revision process. + +Moderate Content +~~~~~~~~~~~~~~~~ + +All users moderate content in some capacity. Workflow Contributors moderate their content between the Draft state and the Needs Review state. Workflow Moderators are responsible for publishing their own content as well as content created by Workflow Contributors. + +All content in the Workflow pipeline is accessed in My Workbench. From My Workbench users can see at-a-glance a summary of content and the state it's in. + +1. From the Admin Menu click the My Workbench link. +2. Click on one of the tabs to see all the content in that publishing state. +3. Workflow Contributors can moderate from this page by clicking the Submit for Review button to send a draft to a Workflow Moderator to review. +4. Workflow Moderators can moderate content from this page by clicking the Reject or Publish buttons on a piece of content. + +.. image:: ../../images/site_manager_playbook/workflow/my_drafts.png + :alt: my drafts view + +Review content and make changes: + +1. From My Workbench, navigate to tab with publishing state of the content. +2. Click on the title link of the piece of content. +3. Click the **Edit Draft** button to make changes directly to the content. +4. At the bottom of the page, moderate the publishing state. +5. Workflow Moderators may change the state to draft for revisions or directly publish the content. + +Click the **Moderate** button to see the full revision history and change the publishing state. + +.. image:: ../../images/site_manager_playbook/workflow/moderate.png + :alt: moderate view diff --git a/dkan/docs/admin/people/group_roles_and_permissions.rst b/dkan/docs/admin/people/group_roles_and_permissions.rst new file mode 100644 index 000000000..2d5a28bf8 --- /dev/null +++ b/dkan/docs/admin/people/group_roles_and_permissions.rst @@ -0,0 +1,164 @@ +.. _`user-docs group roles and permissions`: + +=========================== +Group Roles and Permissions +=========================== + +Group roles and permissions +DKAN standard roles and permissions apply across the entire site, but there are also special permissions that apply to only some parts of the site. That includes Group roles and permissions. You can learn more about Groups and how they work in the Data and Content section. + +With large sites there is often a need to have a subset of the content managed by a specific list of users. Think of a large agency or department with sub-departments or programs that produce content. With Groups, you can silo content and users so that the different departments can easily manage and control only the content they are producing. + +To keep content organized and in the hands of its owners, and without introducing the risk of inadvertent (and sometimes irreversible) actions, Group-level permissions give users the ability to do things they couldn’t necessarily do on the site outside of the Group. + +About Group roles and permissions +--------------------------------- + +After adding a new Group, Site Managers can assign Datasets (and their Resources) to that Group. You can also manage the members of a Group, adding new members and giving certain members different roles. + +Members of a Group are bound by the permissions of their role and restricted to the content in their Group. As a Site Manager you have access to all Groups and are not limited by the permissions of the Group. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_01.png + :alt: An example of a Group of an out-of-the-box DKAN site. + +Within Groups there are different levels of access a user can have, which determines another level of permissions. Any user who belongs to a group falls into one of two types: Member or Administrator. Users not in the group are considered Nonmembers. + +Nonmember +~~~~~~~~~ + +A Nonmember is any user on the site who does not belong to the Group. + +**Permissions:** + - Request membership in the Group + - View Group members and content. + +Member +~~~~~~ + +A Member is a basic user within the Group who is mostly adding and editing their own content for the Group. + +**Permissions:** + - Add content to the Group + - Edit own content within a Group (Content assigned to a Group can only be edited by members of that Group) + +Administrator +~~~~~~~~~~~~~ + +An Administrator of a Group plays a similar role to that of an editor. They manage the team of users associated with the Group, and can edit any of the content. It's good practice to have only 1 or 2 users in this role for any given Group. + +**Permissions:** + - Edit all content assigned to the Group (Cannot modify content in other Groups) + - Add Group members and assign group roles + +Add Group Members +----------------- + +For basic members of a Group, there are two ways that you can add a user to a Group: from the user profile and from the Group page. + +**Add a user by editing their user profile:** This way of adding users to a Group is preferred if you are the Site Manager but not the Group Administrator. The Group Administrator should be aware and approve of incoming members. You can submit a request for a user to a Group by selecting the Groups on the user's profile page. + +By adding a user to a Group from the user's profile page, a request is sent to the Group Administrator on their behalf for the Administrator to approve. Edit the user's profile who you want to add to the Group and scroll to the bottom of the page. In the section Group membership section there are two fields, Your groups and Other groups. + +- **Your groups:** These are Groups that you are a member of. Users are not automatically added to Groups, so Groups won't appear in this field unless you add yourself to a Group. + +- **Other groups:** These are simply Groups that you are not a member of. As a Site Manager, you can add any user to a Group regardless if you are a member yourself. But the Group names will not automatically appear like in the Your groups field, so you will have to know the name of the Group to enter it in the Other groups field. + +Once the right Groups have been selected, click the **Save** button at the bottom to submit the requests. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_02.png + :alt: The "Group membership" portion of a user's profile page. + +**Add a user from the Group page:** This option is best if you are the Site Manager and the Group Administrator. You can add a user members directly from the main Group page by clicking the **Group** button and clicking the **Add people** link. On the next page, you can add users by pulling up an existing user and optionally choose if a member should be an Administrator member. + +Begin typing an existing a user and a list of autocomplete options will appear to select from. A user must already have an account to be added to a Group, so if a person needs to be added you should first create a site account for them with the appropriate role. + +By default a user will only have a Member role in the Group. To give the user an Administrator role and permissions, check the **administrator member** box. To finally create the user, click the **Add users** button at the bottom of the page. + +In the example below, the Site Manager goes to the Group, "Committee on International Affairs". From the Group page the Site Manager adds a new user by typing the user name and choosing the autocomplete selection. In this example, Kim Lee should be an Administrator of the Group so the Site Manager checks the administrator member box. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_03.gif + :alt: An animated screencap showing the process of adding a new user to a Group. + +Manage Group members +-------------------- + +You can manage Group members directly from the main Group page by clicking the **Group** button. From this page you can manage existing members by clicking the **People** link. The Group overview page lists all the members of a Group including pending members. From this page you can see how many members are in the group overall, the number of Datasets associated with the Group, access and edit individual member profiles, perform bulk actions and manage membership requests. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_04.png + :alt: The "Group Overview" screen showing Group membership. + +**Find members:** All the members of a Group, including pending members, appear on the members list. There are two ways to find members: by State and by Name. + +- **State:** State refers to the status of a member. Active members are users who regularly add Datasets to the Group. Blocked members are unable to add Datasets to the Group and are not able to request membership. Pending members have requested to join the Group and are waiting for approval from the Group administrator. Use the **State** drop-down menu to find users who fit a common state. This is helpful when you want to perform bulk actions on multiple users at the same time. + +- **Name:** Finding a member by name is a much more specific type of search. You can search for multiple members at the same time by entering the user names in the Name search field separated by commas. This type of search is helpful if you know which specific member you're looking for or if there is a specific group of members that don't have a common state but you want to perform a bulk action on that group of members. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_05.png + :alt: This screen is what you'll see when searching for a Group member by name. + +**Change a user's role:** As a Site Manager you can change the role of a Group member to either be a regular member or an Administrator. In general there are only one or two Administrators managing the Group, so you won't need to change member roles often. When you do, you can change a member's role directly from their profile. + +From the Group's home page, click the **Group** button and then the **People** link to manage the Group. Find the member whose role you want to change, either to an Administrator or remove their Administrator status to make them a regular member. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_06.gif + :alt: This animated screencap shows what it looks like when a Site Manager edits a user's membership within a Group. + +**Remove or block a member:** You can keep users from adding Datasets to the Group in two ways: blocking a member or removing them from a Group. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_07.png + :alt: This screencap shows Group members and whether they're active or have been blocked. + +- **Remove a member:** Removing a member keeps them from adding Datasets to the Group, but these users can later request membership. To remove a member, access the Group overview page where Group members are managed. Find the member you want to remove and click the remove link in the furthest column to the right in the member's row of information. + +- **Block a member:** Blocking a member keeps a member from adding Datasets to the Group, and these users cannot request membership to the Group. To block a member, you'll need to change the status of the member by editing their profile. Find the member you want to block and click the edit link in the furthest column to the right in the member's row of information. From the drop-down Status menu, change the member's status from Active to Blocked. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_08.png + :alt: This screencap shows what you'll see when editing a user's Group membership. + +**Membership requests:** Users may also request Administrator approval to become a member in a Group. When users submit a membership request, they appear in the list of members with a pending status. If you or the Group Administrator directly add a user to the Group, then you don’t need to add any text in the request message box. If the user requested membership, then their request message will appear here as part of the member profile (only visible to the Site Manager and Administrator). + +In the example below, a non-member visits the Group's home page and submits a request for membership with a request message. The member and her message will now appear on the list of members on the Group overview page in a pending state. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_09.gif + :alt: This animated screencap shows the process of a user requesting membership to a Group. + +The Administrator or Site Manager can approve the request by changing the user's status from pending to active. To change a member's status, click the edit link in the furthest column to the right in the member's row of information. From the drop-down Status menu, change the member's status from pending to active. + +Membership requests don't send alerts to the Group Administrator, so the Administrator needs to check for members with a pending state. You can find members by state and select pending to show only pending members who need approval. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_10.gif + :alt: This animated screencap shows the process of editing a user's Group membership. + +**Bulk actions:** Bulk actions help save time because you can select multiple members and perform the same action rather than taking the same action over and over on single members. + +From the Group's home page, click the **Group** button and then the **People** link to manage the Group. + +Find the members you want perform the action on and check the boxes to the left of the member's name for each member. There are three types of bulk actions: Modify OG user roles, Remove from group, and Modify membership status. + +- **Modify OG user roles:** OG user roles refer specifically to Group roles and permissions, which are Member and Administrator. You can change the role of multiple members at the same time with this action. Check all the members whose roles you want to change–for this action, all the members must have the same role to be changed to a new role. Find the drop-down Operations menu, select Modify OG user roles, and click the Execute button. On the next screen you can choose to either add the Administrator role to the selected users or remove the Administrator role to make the users general members. Choose to add or remove the Administrator role and then click the Next button at the bottom of the page and confirm on the next screen. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_11.png + :alt: This screencap shows the process of editing OG user roles. + +- **Remove from group:** Remove several members at once with this bulk action. Check all the members who you want to remove from the Group, find the Remove from group option on the drop-down Operations menu, and click the Execute button. You'll be asked to confirm on the next page and then the members will be removed from the Group. + +- **Modify membership status:** Members in a Group may be in one of three statuses: active, pending, and blocked. + + - The active status means that the member is able to add Datasets to a Group and edit Datasets that they have created. + - Pending members are waiting for approval from the Group Administrator. + - Blocked members exist but are not active and do not have permission to add Datasets to the Group or submit another request for membership. + - Check all the members who you want to change the status of. For this action, all the members must have the same status to be changed to a new status. Find the drop-down Operations menu, select Modify membership status, and click the Execute button. On the next screen, choose the new status and then confirm the changes. + +In the example below, the Group Administrator (Kim Lee) first finds only members with a pending status using the **State** drop-down menu. Then she selects all of the members and chooses the bulk action **Modify membership status** from the drop-down **Operations** menu. On the next screen, she changes the members status to active. This is an example of an easy way to find and approve membership requests quickly using search functions and bulk actions. + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_12.gif + :alt: This animated screencap shows the process of modifying OG user roles. + +**Add and remove Datasets from your Group:** In general, your Group members will publish Datasets associated with the Group, so adding will be more common. On occasion, a Dataset may be added to a Group that does not belong and should be removed (though not deleted). + +.. figure:: ../../images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_13.png + :alt: This screencap shows what you'll see at the bottom of a Dataset's page when editing it and selecting which Groups it should be assigned to. + +**Add a Dataset:** Datasets should be added a Group as part of the initial content creation process of the Dataset. As Group members add new content to the site they should associate the Dataset with the Group before finally publishing. Users who created the content can later edit the Dataset to add to a Group, and as a Site Manager you can add any Dataset regardless of the author. Once the Dataset is published and associated with the Group, it will appear on the Group's home page. Read the section on adding a Dataset to find more detail on how to add a Dataset to a Group. + +**Remove a Dataset:** Though Datasets appear on the Group's home page once a Dataset is published and associated with the Group, they are not managed within the Group. To remove a Dataset, the content author, Group Administrator, or Site Manager needs to edit the Dataset directly and remove the Group associated with the Dataset. Once the Group is removed from the Dataset it will no longer appear on the Group's home page. diff --git a/dkan/docs/admin/people/index.rst b/dkan/docs/admin/people/index.rst new file mode 100644 index 000000000..a732d2d0a --- /dev/null +++ b/dkan/docs/admin/people/index.rst @@ -0,0 +1,15 @@ +.. _`user-docs people`: + +====== +People +====== + +Data and content management can't be done alone. Site Managers handle all the users on the site and decide who has access to what. They can also create Groups for organizations, which have even more possibilities for roles and permissions. Build your team to build your site. + +.. toctree:: + :maxdepth: 2 + + dkan_user_accounts + adding_new_users + group_roles_and_permissions + dkan_workflow diff --git a/dkan/docs/admin/people/users.rst b/dkan/docs/admin/people/users.rst new file mode 100644 index 000000000..a0360a7de --- /dev/null +++ b/dkan/docs/admin/people/users.rst @@ -0,0 +1,92 @@ +DKAN User Management +==================== + +.. warning:: + + This was a document that existed before we did the migration from Insights. This should be reviewed and merged into the People section. + +DKAN uses Drupal's build-in, powerful user account system, with some customizations captured in the DKAN Sitewide User module. Flexible combinations of permissions, restrictions, and authorization schema mean that you can design an open data system that meets the needs of all of your users -- from visitors to data publishers to developers -- securely and easily. + +.. figure:: ../images/site_manager_playbook/managing_users/managing_users_01.png + :alt: The People page, where you can manage users. + +Managing, Editing, and Deleting Existing Users +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Adding a new user +----------------- + +* Log in to your site as the administrative super-user. Note the thin black administration menu that appears at the top of each page once you’ve logged in. This “admin menu” contains shortcuts to all administrative tasks. +* Visit your site’s User Management page by clicking “People” in the admin menu. +* Select the “+ Add user” option at the top of the user management page to add a new user. +* Complete the “add user” form as shown, adding the user to any roles such as “editor” as appropriate. Note the “notify user” option which will send an email with initial login instructions to the user’s email address. +* Click the “Create new account” button when complete. + +Managing existing users +----------------------- + +After creating an account, you can continue to manage users’ profiles from the People menu item in the Admin Menu. From this screen you can see all the existing users, their roles, and details about their account, and by clicking on individual users you can additionally see all the content the user has created. You can also edit their account to change details, add or remove a role, add them to Groups or cancel an account. + +**To edit an existing user's account:** + +* Visit your site’s User Management page by clicking “People” in the admin menu. +* The displayed list of users on the User Management page can be filtered and sorted using the filters at the top of the page. Once you’ve found the user you wish to edit in the user table, click the “edit” link at the end of that user’s row. +* On the resulting “edit user” page, you can edit the user’s username, email, or profile information. You can also set a new password for the user. Click the “Save” button at the bottom of the page to save your changes. +* Use the “Cancel account” at the bottom of the edit user page to delete an account. You will be given the option to preserve or delete any website content added by that user before deletion. + +Finding users and bulk actions +------------------------------ + +On some sites, the list of users can be several pages long. To find a specific user or group of users you can use the filters to narrow the results. + +Filter users and refine results. Filters are most helpful when you're looking for a group of users that can meet a general search criteria. This makes it easy to manage multiple users at the same time or find an individual user without needing to browse through several pages of users. There are two types of filters to narrow users: role and status. + +- **Role.** Filtering users by a role is best used for managing users by permissions. You may want to give a group of users higher permissions or you may want to change the status of a group of users. By selecting a role, the results will only show users that are assigned that specific role. +- **Status.** You can also filter users with a certain status. Click the drop-down menu in the status field and click active to show only active users. Showing only active users ignores users that are not active so that you manage only relevant accounts. + +**Refine results.** If your search is more complex, you can refine the results of the initial results by adding additional search criteria. You can select multiple roles and/or status. So the results would only show users who meet all the criteria. + +.. figure:: ../images/site_manager_playbook/managing_users/managing_users_02.png + :alt: A screencap of the "Show Only Users Where" screen for narrowing down specific users. + +Select the first criteria and click the Filter button to narrow the user list. Once the results are narrowed, you can select an additional search criteria and click the Refine button to narrow the results further. You can do this for multiple search criteria. + +Click the Undo button to remove the last search criteria you added or click the Reset button to remove all the search criteria. Make sure to click the Reset button once you're done with your search. Otherwise the results will remain narrowed, even if you navigate to another page, until all the criteria have been removed. + +.. figure:: ../images/site_manager_playbook/managing_users/managing_users_03.gif + :alt: An animated screencap showing user management on the People page. + +**Bulk actions.** When you have several users that require the same action, you can use this menu to perform bulk actions on a group of users. Rather than spend extra time performing the same action over and over again for individual users, you can select multiple users and make the change for the group with just one click. + +From the People page, select all the user accounts that need to be updated by checking the white check box next to their username. Find the drop-down Update options menu and choose the action you want to perform. You can quickly make changes for a group of users like adding or removing a role and blocking or canceling their accounts. + +In the example below, the Site Manager first uses the status filter to show only blocked users. Then the Site Manager checks the users that should be unblocked, and then finds the Unblock the selected user option in the Update options drop-down menu. Finally, they click the Update button to finalize the changes. + +.. figure:: ../images/site_manager_playbook/managing_users/managing_users_04.gif + :alt: An animated screencap showing user management on the People page. + +Blocking a user or canceling an account +--------------------------------------- + +At some point, most user accounts will need to be deleted or blocked. Typically this is for internal employees who move on from the organization, but there are occasions involving external users. There are a number of options for canceling an account or blocking a user to meet a number of scenarios. + +**Block an account.** Blocking an account is the most simple and straightforward way to suspend an account. Blocking a user account keeps a user from logging in, and accounts can easily be unblocked. A blocked account only means that a user cannot login to their account and access your DKAN site. All of their content and profile details will remain, so nothing is lost if you want to unblock an account and restore access. + +For users accounts belonging to your organization, blocking an account is typically a temporary action. For user accounts that belong to people who may have registered the account themselves, blocking is likely to be more permanent. By blocking an account, you keep users from creating a new account with the same details and avoid repeating the blocking process. + +You can block a single user by editing their profile and changing their status, or you can block several users at once by using the bulk actions function on the People page. In the example below, the Site Manager is blocking a user account by editing an individual user profile. To finalize the changes, the Site Manager must click the Save button at the bottom of the page. + +.. figure:: ../images/site_manager_playbook/managing_users/managing_users_05.gif + :alt: An animated screencap showing how to block unwanted users on the People page. + +**Cancel an account.** Canceling an account can be a permanent action, and there are several options to choose from. Some of the actions cannot be reversed, so you should be careful when deciding which option to choose. Below are the options for canceling an account and the implications of selecting the option. While Site Managers can cancel the account of any user on the site, users may also cancel their own accounts. + +.. figure:: ../images/site_manager_playbook/managing_users/managing_users_06.png + :alt: An image displaying what happens during the process of canceling a user's account. + +- **Disable the account and keep its contents:** If you disable the account, the details of the profile remain in tact but the user is blocked from accessing the site with their user login. By keeping the contents, any content that the user published will remain on the live site. Because the account is only disabled (blocked) the user remains as the author of the content and the profile details may still be accessed. This option is similar to just blocking an account, and it's a good temporary measure in most cases. +- **Disable the account and unpublish its contents:** This option blocks the user from accessing the site and all the content that the user has published will be unpublished. This means that their content will not appear on the live site, but it will still exist behind the scenes. It can be managed out of public view and in the mean time, the user cannot do anything else on the site. This is a good option if you need to review the content a user has published and need it to be off the site but still need to access it. +- **Delete the account and make its contents belong to the Anonymous User:** This is a permanent action. Once you delete an account, you cannot recover any of the details that were associated with the user profile. With this option you can delete the entire account as well as keep its contents. Because the account associated with the user who was the original author no longer exists, the content must be assigned to a different author. This option quickly changes the author so that the content remains on the live site, and you can change the author at any time. Again, this is a permanent option so be careful before making this selection. +- **Delete the account and its contents:** This is a permanent action and the most severe choice when canceling an account. This options not only deletes the user account and all the profile details, it also deletes all the content the user added. Neither the account nor the content can be recovered with this selection. As a general best practice, we recommend never deleting content if it can be edited or simply unpublished. + +**Require email confirmation:** For any option you choose when canceling an account, you can make sure the user is aware by requiring email confirmation. An email will be sent to the email address provided in the user's profile details. When you check the Require email confirmation box, the account won't be canceled until the user confirms through the email. diff --git a/dkan/docs/admin/structure.rst b/dkan/docs/admin/structure.rst new file mode 100644 index 000000000..1f3f63bf2 --- /dev/null +++ b/dkan/docs/admin/structure.rst @@ -0,0 +1,310 @@ +.. `user-docs structure`: + +========= +Structure +========= + +As a Site Manager you handle the structures that other users operate within. This framework reflects the broader organizational priorities and brings greater visibility to the content on your DKAN site. Many of the tools that help organize the content on your DKAN site also make it easier to navigate and find the right content. All of this improves the experience of a site visitor and makes it more likely that citizens can use the data published on your site. + +Site Navigation +--------------- + +Menus +~~~~~ + +Menus organize content and play a critical role in directing site visitors to the content they need. As Pages are added with new content, adding new menu links are the connectors for site visitors to your content. + +Some content (like Datasets or Data Stories) has a menu link in the main menu by default, but new Pages require a new link to navigate to the content. You can customize the default structure of the main menu as it makes sense for your site content. + +Using menus +~~~~~~~~~~~ + +From the Admin Menu, hover over the menu link **Site Configuration**. From the drop-down list, select the **Menus** link to access the Menus page. + +The main menu is persistent, meaning that it appears on every page. This menu acts as an anchor for site visitors as they make their way through your site. Details like the order of menu links, link titles, and number of menu links can all impact how a site visitor interacts and engages with the content of your site. + +Click the **list links** button to view and manage all the links on the main menu. + +As a Site Manager, you can manage the details from the main menu page in the following ways: Add a new link, Order menu links, Enable and disable links, and Edit or delete a menu link. + +Add a new link +~~~~~~~~~~~~~~ + +By default, DKAN comes with preset menu links. These links point to pages that automatically collect content as it’s published, like Datasets and Data Stories. + +For new Pages with new content, create a link and add it to the main menu by clicking the **Add link** button at the top-left of the page. Complete all the fields in the form and click the Save button at the bottom of the page. + +Menu link title + The title is what the site visitor sees as they navigate with the main menu. +Path + The menu link must point to content, so that when a site visitor clicks the link they are appropriately directed. Paste in the URL for the link. +Description + The description essentially acts like alt-text. Make sure you include a description, but keep it brief. +Enabled checkbox + By default, when you create a new link, it’s also enabled. Only enabled links appear on the main menu. Uncheck this box if the link should not appear on the main menu. +Show as expanded + This option only applies to menu links with child menu items. When this box is checked all the child items are displayed. +Parent link + By default, the parent link is the main menu. Links with this parent link will appear on the top-level menu bar. Click the Parent link drop-down menu and select the correct parent. +Weight + Weight determines the order of menu links. High numbers (heavier) are lower on the menu, and smaller numbers (lighter) appear near or at the top of the menu. + +Order menu links +~~~~~~~~~~~~~~~~ + +Change the order of how links appear on the main menu with the simple drag-and-drop interface. Click and hold the cross icon to drag a menu link into a new order. + +If an asterisk appears next to the title of a menu link it indicates that the menu link has been altered, but changes will not be made until saved. + +**Note:** You can also use the drag-and-drop interface to nest or un-nest menu links. + +To nest a link (make a link a child of another menu link), click and hold the cross icon and drag the menu link under and to the right of the new parent menu link. + +To un-nest a link (make a child link a top-level link on the main menu), click and hold the cross icon and drag it above the previous parent link. + +Click the **Save Configuration** button at the bottom of the page to finalize your changes. + +Enable and disable links +~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of deleting a menu link to remove it from the main menu, you can enable and disable menu links. Disabled links remain in the list for you to edit and manage, but site visitors won’t see them on the main menu. + +To disable a menu link, uncheck the box in the **Enabled** column in the row of the menu link you want to disable. + +Edit or delete links +~~~~~~~~~~~~~~~~~~~~ + +Change the details of a menu link by clicking the **Edit** link in the Operations column in the row of the menu link you want to edit. When editing a menu link you can change details like the title, the path (URL), and parent link. + +Click the **Save** button at the bottom of the page to finalize the changes. + +Deleting a menu link is a permanent action and cannot be undone. If you delete a link and want to add it back, you’ll have to create it as a new menu link. Disabling a link is recommended before fully deleting a menu link. + +To delete a link, click the **Delete** link in the Operations column in the row of the menu link you want to delete. + +Adding and editing Topics, Tags, and data formats +------------------------------------------------- + +Topics +~~~~~~ + +Enhanced user experience, branding, and information architecting–the Topics feature touches on all of these areas to add ease-of-use for both site visitors and users working behind the scenes. + +With so much data in a single place, DKAN sites have a number of tools to organize the information for citizens to easily and intuitively find what they are looking for. Topics catch site visitors’ attention right from the Home page. As with most DKAN features, Topics are built to provide a crisp, engaging user experience that is adaptable for customization. Either font icons or images can be used, and these graphics can be customized in appearance and color to fit the individual look and feel of any agency. The default DKAN icon font set includes over 100 icons, and new icon font sets can be added anytime for a broad range of options. + +Topics typically reflect broad categories like transportation or education. These are areas of interest that should remain consistent themselves and collect timely, relevant content. Topics appear on the front page (unless otherwise modified) along with their assigned icons. + +.. figure:: ../images/site_manager_playbook/structure/highlighted_topics.png + :alt: front page with highlighted topics + + The default DKAN frontpage with highlighted Topics section. + +Where Topics are managed +~~~~~~~~~~~~~~~~~~~~~~~~ + +Topics are included in the Structure section of this guide because they're considered a taxonomy. Taxonomies are a high-level way of collecting and organizing information. The smaller pieces of information that make up taxonomies are called terms. So for example, you could have a taxonomy of fruit and individual terms might be "apple" or "banana". + +You'll find Topics in the **Taxonomy** drop-down menu item under the **Site Configuration** menu link on the Admin Menu. + +.. figure:: ../images/site_manager_playbook/structure/topics_admin_menu.png + :alt: location of topics in the admin menu + + Click on the **Topics** link to get to the main page where Topics are managed. + +Adding and managing terms +~~~~~~~~~~~~~~~~~~~~~~~~~ + +DKAN comes with six preset Topics: Transportation, Education, Finance and Budgeting, Health Care, Public Safety, and City Planning. You can add to the existing terms or replace them with different terms. The Topics for your DKAN site depend largely on the data on the site and the areas of interest you believe your site visitors are most interested in. + +Add a term + On the Topics page, click on the Add term button to open the options for adding a new term (a single Topic) to be included in the collection of Topics. The only fields that are important for adding a new Topic are the Title field and icon selection. The title is the name of your Topic that will appear on the front page of your DKAN site under the icon you select. + +.. image:: ../images/site_manager_playbook/structure/default_topics_list.png + :alt: default list of topics + +Icon Type: Font ++++++++++++++++ + +Icon + Choose an icon from your font icon library. Whichever you choose, you want something the is both eye-catching and expressive. Site visitors should know exactly what kind of content the Topic includes from the graphic without relying on the text. +Icon Color + For font icons, you can choose a color for the icon of your Topic. Images do not have an option to change the color. It’s best to choose a single color that all your icons have in common. The color should also fit the look and feel of the rest of your site, either as a matching or complementary color. + +.. image:: ../images/site_manager_playbook/structure/font_icon_options.png + :alt: font icon options + +Icon Type: Image +++++++++++++++++ + +If you have an image that you prefer to use for the Topic icon, select the Image selection instead of font icon. Click the **Choose File** button to find the image on your computer and then click the Upload button to finalize the selection. + +**Note:** there are limits on the file size and type. + +.. image:: ../images/site_manager_playbook/structure/image_icon_options.png + :alt: image icon options + +.. figure:: ../images/site_manager_playbook/structure/topic_options_animation.gif + :alt: configuring topic options + + In this example, the Site Manager is adding a new term to the Topics taxonomy called "Environment". The Site Manager chooses an icon from the library and then chooses a color for the icon. Once the Topic is saved it will appear on the front page. + +When all your selections are made, click the **Save** button at the bottom of the page to finalize your choices and save the term. Once the new Topic is saved it will appear on the front page with all the other Topics. + +It's best to keep your site looking orderly, so you don't want Topics to appear like they do in the image below. For the purposes of this example, a different color was chosen to demonstrate the change, but in practice color schemes should remain consistent across your site. + +Additionally, the number of Topics pushes down to a second line and appears uneven. Keep the number of Topics even appearance by maintaining a certain number of Topics at any given time. Since there are six Topics to a line, that means the number of Topics should follow a factor of six. + +.. image:: ../images/site_manager_playbook/structure/added_topic.png + :alt: seven topics in two rows + +Manage terms +~~~~~~~~~~~~ + +As the appearance of your DKAN site evolves, you may need to also change the appearance and even titles of your existing Topics. It's best to edit existing Topics rather than create completely new ones. If you delete a Topic then all the content that was before associated with the Topic will no longer have any association because the Topic doesn't exist. But if you update a Topic, then the content will still be associated with the Topic with the updated title and icon. + +You can change the title, icon, and icon color of existing terms by clicking the edit link under the Operations column on the row of the Topic you want to edit. The only fields that are important for adding a new Topic are the Title field and icon selection. The title is the name of your Topic that will appear on the front page of your DKAN site under the icon you select. + +Re-order Topics +~~~~~~~~~~~~~~~ + +While many site visitors will be attracted to a Topic based on its visual element (the icon) many site visitors will read Topics from left to right like with text. You might have some Topics that you want to promote to ensure that site visitors don't miss them. You can re-order Topics to follow the rank of importance to the site visitor. + +Notice the compass arrow to the left of each Topic name. You can change the order of the Topics by clicking and holding the compass arrow, then dragging and dropping each Topic either higher or lower on the list. The order determines how the Topics appear on the front page of your DKAN site. The first Topic on the list appears as the first Topic on the front page. It appears on the far left and the rest follow horizontally across the page. + +.. figure:: ../images/site_manager_playbook/structure/ordered_topic_list.png + :alt: list of topics with a new order + + Administrative view of the re-ordered Topics. + +.. figure:: ../images/site_manager_playbook/structure/ordered_topic_display.png + :alt: re-ordered view of topics on the front page + + Front page view of the re-ordered Topics. + +Customizing icon options +~~~~~~~~~~~~~~~~~~~~~~~~ + +A consistent appearance on your DKAN site that aligns with the image of your overall organization is important. While your DKAN site is dedicated to data publishing, getting your data into a central location, and increasing transparency to engage with the broader public, it should be clear to site visitors that the effort is part of the larger organizational priorities. If you do use the default font icon library, you can also manage how the library is used. + +Uploading new font icon libraries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To add greater flexibility in the appearance of Topics to align with your organizational image, you can add your own font icon libraries to choose from for your Topics. By default, DKAN comes with a font icon library called DKAN Topics. It includes over 100 icons to choose from for your Topics. Alternatively, you can also upload your own font icon library if you have one that you prefer. + +.. image:: ../images/site_manager_playbook/structure/font_icon_select_options.png + :alt: font icon select options + +You’ll need to name your library with the Title field to manage it among all the uploaded font libraries. Uploading a library also requires four standard files that make a font: EOT, SVG, TTF, and WOFF. If you don’t have these files then you’ll either need to get the files or use the default DKAN Topics font. + +.. image:: ../images/site_manager_playbook/structure/upload_font_library.png + :alt: upload font library fields + +Editing existing font icon libraries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once a font icon library is uploaded, you can go back and make edits to an individual library under the Uploaded Font Libraries tab. + +Edit Font Options ++++++++++++++++++ + +Click the edit font link to change the details of the font icon library like the title and the files containing the visual elements of the library. + +.. image:: ../images/site_manager_playbook/structure/edit_font_options.png + :alt: font icon select options highlighted second tier options + +Edit Font Blacklist ++++++++++++++++++++ + +Your font icon library may contain hundreds of icons, but there might be some icons that you don’t want users to assign to Topics. You can add unwanted icons to a blacklist to block those icons from appearing as an option. Edit the font library blacklist to choose which icons cannot be assigned to Topics. Click on an icon or remove an icon from the blacklist by click a red icon. + +.. image:: ../images/site_manager_playbook/structure/global_blacklist_selection.png + :alt: global blacklist selection view + +Delete a library +++++++++++++++++ + +You can delete an entire library from your site with one click. If a font icon library is in use it can’t be deleted, so you’ll need to change the active library before deleting a library. Once a library is deleted, the action cannot be undone so be careful when removing font icon libraries. + +Adding and managing Tags +------------------------ + +As content is added by users of all types, authors can add Tags to their content. Tags are free-form, so they can be newly added in the field and can contain any words. Think of Tags as keywords either within or related to the content. By including Tags on your content it will appear when the terms are included in a search. + +.. figure:: ../images/site_manager_playbook/structure/tags_field.png + :alt: tags field on content edit pages + + Tags field on content edit pages. + +Adding Tags to content +~~~~~~~~~~~~~~~~~~~~~~ + +Users can add Tags to Datasets and Data Stories, whether they have been added before or not. Simply type the key term you want to tag your content with and hit the space key on your keyboard. + +Tags are added in single terms, so if you have multiple or compound words they will either have to be combined for a single term or separated with dashes. If a Tag has been used before, DKAN will autocomplete the term for you. If the Tag has not been added previously, then a new Tag will be created and can be used in the future. As a Site Manager, you can add Tags without adding them to content on the Tags menu. + +.. figure:: ../images/site_manager_playbook/structure/tags_list.png + :alt: tags list admin view + + Administrative view of the tags list. + +Managing Tags +~~~~~~~~~~~~~ + +Because Tags are free-form and can be newly added by any user, you may end up with many unnecessary Tags that are counterproductive. Too many Tags can actually make it more difficult to sort through data and confuse site visitors. + +As a Site Manager, you have access to all the terms collected as Tags. You’ll want to keep an eye on your Tags to make sure they stay orderly and relevant. You can edit or remove redundant or incorrect terms from the Tags menu under the **Site Configuration** link on the Admin Menu. + +.. figure:: ../images/site_manager_playbook/structure/delete_tag_animation.gif + :alt: animation of deleting a tag + + In this example, the Site Manager is deleting a partial (and redundant) Tag as well as editing a Tag that is useful, but spelled incorrectly. This will help users avoid associating their content with the wrong Tags. + +Data formats +------------ + +Data added to your DKAN site may come in a number of file formats. You can think of data, or file formats, as labels to tell site visitors what type of data is contained in the file–adding a data format does **not** change or transform the contents of the files themselves. File formats describe how the data is formatted and indicates how it should be read. + +In some cases file formats may be similar like CSV or XLS, which both contain information organized into rows and columns. But in many cases, indicating the file format makes an important difference. Geospatial data formatted in an XML file is read differently than similar data formatted in a JSON file. Data formats allow users to choose the right data format and tell site visitors which type of data they should expect when they download the file. + +Add data formats +~~~~~~~~~~~~~~~~ + +DKAN comes standard with the most common data formats, but you can add more file formats as needed. File formats fall under the **Taxonomy** menu item on the Admin Menu. Use the Add term button to include an additional file format. Keep in mind that data formats are just labels to tell site visitors what type of data is contained in the file–adding a data format does **not** change or transform the contents of the files themselves. + +.. image:: ../images/site_manager_playbook/structure/format_list.png + :alt: list of data formats + +Manage data formats +~~~~~~~~~~~~~~~~~~~ + +If the language used for the data formats changes, you can edit the name of the format rather than delete the old one and add a new one. This is important because any data content that has the old data format will require a new label to tell site visitors what type of format the data is in. If instead you update the existing data format by editing it, all the data content with the old data format with update automatically. + +URL aliases +----------- + +Though it may not be obvious, URL aliases are important to the overall experience a site visitor has even before they get to your DKAN site. Because every URL must be unique to work properly by default most URLs are a string of arbitrary numbers, symbols and letters. + +This serves the purposes of creating a unique URL, but they can be hard to remember, too long to share, and cause alarm about the credibility of the source. Aliases let you create a URL that is easy to read, understand, and share while still maintaining a unique location on the web. + +Managing URL aliases +~~~~~~~~~~~~~~~~~~~~ + +On DKAN, URL aliases are automatically generated for content, unless you (as a Site Manager) specifically unselect that option on a piece of content. Rather than using the automated URL path that is generated for technical administration (usually an indiscernible cluster of numbers of letters) an alias is created that is easy to read, remember, and type into the search bar. On DKAN, the alias is typically the title of a piece of content. + +While aliases are created at the time content is generated, you can also change the URL alias any time. You might find some terms make more sense or appear more frequently in site visitor searches. You can also delete the alias and leave only the administrative title for a piece of content (not recommended). + +From the Admin Menu, click the the **Site Configuration** menu item and find the Search and metadata section. Select the **URL aliases** link to manage URL aliases. + +Options in the URL aliases page under the Search and metadata section show a list of the existing URL aliases and gives you options for either changing the alias or deleting it. In general, you won’t need to make bulk updates or delete groups of aliases, so we recommend using the List button when making changes. + +.. image:: ../images/site_manager_playbook/structure/url_aliases_list.png + :alt: list of url aliases + +Find the URL that you want to change and click the edit link in the column furthest to the right of the URL. Only change the Path alias field; choose a name that is easy to remember, relatively brief so that it's easy to share, and a name that is engaging and tells a site visitor what they'll be reading. + +URL aliases are an excellent opportunity to improve how the content on your DKAN site is discovered because you can include key search terms that commonly appear in site visitors' searches. + +.. figure:: ../images/site_manager_playbook/structure/edit_url_alias_animation.gif + :alt: animation of editing a url alias + + In this example, the Site Manager is editing the URL of a Dataset to make it more specific so that it appears in searches for bike lanes in Miami. diff --git a/dkan/docs/admin/users.rst b/dkan/docs/admin/users.rst deleted file mode 100644 index 0c25fdecb..000000000 --- a/dkan/docs/admin/users.rst +++ /dev/null @@ -1,27 +0,0 @@ -DKAN User Management -==================== - -DKAN uses Drupal's build-in, powerful user account system, with some customizations captured in the DKAN Sitewide User module. Flexible combinations of permissions, restrictions, and authorization schema mean that you can design an open data system that meets the needs of all of your users -- from visitors to data publishers to developers -- securely and easily. - -Adding a new user ------------------- - -In this example we’ll add a new editor user to the site. - -* Login to your site as the administrative super-user. Note the thin black administration menu that appears at the top of each page once you’ve logged in. This “admin menu” contains shortcuts to all administrative tasks. -* Visit your site’s User Management page by clicking “People” in the admin menu. -* Select the “+ Add user” option at the top of the user management page to add a new user. -* Complete the “add user” form as shown, adding the user to any roles such as “editor” as appropriate. Note the “notify user” option which will send an email with initial login instructions to the user’s email address. -* Click the “Create new account” button when complete. - -.. figure:: ../images/new-user.png - -Managing, Editing, and Deleting Existing Users ------------------------------------------------------- - -* Visit your site’s User Management page by clicking “People” in the admin menu. -* The displayed list of users on the User Management page can be filtered and sorted using the filters at the top of the page. Once you’ve found the user you wish to edit in the user table, click the “edit” link at the end of that user’s row. -* On the resulting “edit user” page, you can edit the user’s username, email, or profile information. You can also set a new password for the user. Click the “Save” button at the bottom of the page to save your changes. -* Use the “Cancel account” at the bottom of the edit user page to delete an account. You will be given the option to preserve or delete any website content added by that user before deletion. - -.. figure:: ../images/people.png \ No newline at end of file diff --git a/dkan/docs/apis/datastore-api.rst b/dkan/docs/apis/datastore-api.rst index 6fb69d94f..84d08344e 100644 --- a/dkan/docs/apis/datastore-api.rst +++ b/dkan/docs/apis/datastore-api.rst @@ -1,12 +1,13 @@ +.. _`datastore API`: + Datastore API ============= DKAN offers a Datastore API as a custom endpoint for the Drupal Services module. -This API is designed to be as compatible as possible with the [CKAN -Datastore API] -(http://ckan.readthedocs.org/en/latest/maintaining/datastore.html). +This API is designed to be as compatible as possible with the `CKAN +Datastore API `_. Parameters ---------- @@ -15,7 +16,7 @@ Parameters resource(s) to be searched against. - **filters** (*mixed*) – array or string of matching conditions to select -- **q** (*string*) – full text query +- **q** (*string*) – fulltext search - **offset** (*int*) – offset this number of rows - **limit** (*int*) – maximum number of rows to return (default: 100) - **fields** (*array or comma separated string*) – fields to return diff --git a/dkan/docs/apis/rest-api.rst b/dkan/docs/apis/rest-api.rst index 359fa7060..1b28e04c9 100644 --- a/dkan/docs/apis/rest-api.rst +++ b/dkan/docs/apis/rest-api.rst @@ -1,3 +1,5 @@ +.. _`Dataset REST API`: + ##################### Dataset REST API ##################### @@ -27,7 +29,7 @@ DKAN Dataset REST API comes with a REST Server. Other server types are also incl * XML-RPC **************** -Repsonse Formats +Response Formats **************** * bencode @@ -56,7 +58,7 @@ Authentication Modes Session Authentication ====================== -Session authentication is enabled by default. With session authentication an inital request is made to the user login to requet a session cookie. That session cookie is then stored locally and sent with a request in the X-CSRF-Token header to authenticate the request. +Session authentication is enabled by default. With session authentication an inital request is made to the user login to request a session cookie. That session cookie is then stored locally and sent with a request in the X-CSRF-Token header to authenticate the request. Token Authentication ==================== @@ -68,506 +70,617 @@ Authentication Permissions The permissions with which a user is granted depend on the user role. User roles and permissions are easily configured in the user administration screen at ``admin/people``, and DKAN comes with a number of pre-configured default roles via the `DKAN Permissions `_ module. -******** -Examples -******** +**************** +Request Examples +**************** -Below you can find examples in PHP for the most common use cases, using session authentication. +URL Query Parameters +==================== -For an example of a fully-functional python-based client to the DKAN REST API, see the `pydkan `_ project. +* (string) fields - A comma separated list of fields to get. +* (array) parameters - Filter parameters array such as parameters[title]="test" +* (int) page - The zero-based index of the page to get, defaults to 0. +* (int) pagesize - Number of records to get per page (max = 20). -Log In and get the Session Cookie -================================= +The output from a url is paginated and displays 20 items per page by default. You can specify which page to view by adding a `page` value. And you can change the number of items per page by including a `pagesize` value. For example, the following query will display items 11 - 20: -.. code-block:: php +.. code-block:: bash + + http://demo.getdkan.com/api/dataset/node.json?page=2&pagesize=10 - // Setup request URL. - $request_url = 'http://example.com/api/dataset/user/login'; - // Prepare user data. - $user_data = array( - 'username' => 'theusername', - 'password' => 'theuserpassword', - ); - $user_data = http_build_query($user_data); +To return only a specific node type, include a `type` parameter: - // Setup request. - $curl = curl_init($request_url); - curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json')); +.. code-block:: bash + + http://demo.getdkan.com/api/dataset/node.json?parameters[type]=dataset - // Accept JSON response. - curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST. - curl_setopt($curl, CURLOPT_POSTFIELDS, $user_data); // Set POST data. - curl_setopt($curl, CURLOPT_HEADER, FALSE); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); - curl_setopt($curl, CURLOPT_FAILONERROR, TRUE); - // Execute request and get response. - $response = curl_exec($curl); +To return only the title and node id of published resources: - // Process response. - $logged_user = json_decode($response); +.. code-block:: bash - // Save cookie session to be used on future requests. - $cookie_session = $logged_user->session_name . '=' . $logged_user->sessid; + http://demo.getdkan.com/api/dataset/node.json?fields=title,nid¶meter[type]=resource¶meter[status]=1 -Get the CSRF Token -================== -.. code-block:: php - // Setup request URL. - $request_url = 'http://example.com/services/session/token'; +Below you can find examples in PHP for a basic set of CRUD operations on datasets and resources. This documentation is a work in progress. The examples are raw HTTP requests, with a short example of how to execute a query in PHP as well. - // Setup request. - $curl = curl_init($request_url); - curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json')); // Accept JSON response. - curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST. - curl_setopt($curl, CURLOPT_COOKIE, "$cookie_session"); // Send the cookie session that we got after login. - curl_setopt($curl, CURLOPT_HEADER, FALSE); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); - curl_setopt($curl, CURLOPT_FAILONERROR, TRUE); +For an example of a fully-functional python-based client to the DKAN REST API, see the `pydkan `_ project. - // Execute request and save CSRF Token. - $csrf_token = curl_exec($curl); +Login +===== -Create a Resource -================= +Request +------- -.. code-block:: php +.. code-block:: bash - // Set up request URL. - $request_url = 'http://example.com/api/dataset/node'; + POST http://docker:32774/api/dataset/user/login + Accept: application/json + Content-Length: 29 + Content-Type: application/x-www-form-urlencoded - // Setup resource data. - // A great explanation on how to target each node field can be found on the 'Identifying field names' article linked on the 'Documentation' section. - $resource_data = array( - 'type' => 'resource', - 'title' => 'Example resource', - 'status' => 1, - 'body[und][0][value]' => 'The description' - ); - $resource_data = http_build_query($resource_data); + { + "username": "admin", + "password": "admin" + } - // Setup request. - $curl = curl_init($request_url); - curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json', 'X-CSRF-Token: ' . $csrf_token)); - curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST. - curl_setopt($curl, CURLOPT_POSTFIELDS, $resource_data); // Set POST data. - curl_setopt($curl, CURLOPT_COOKIE, "$cookie_session"); - curl_setopt($curl, CURLOPT_HEADER, FALSE); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); - curl_setopt($curl, CURLOPT_FAILONERROR, TRUE); +Response +-------- - // Execute request and get response. - $response = curl_exec($curl); +.. code-block:: json -Attach a file to a resource -=========================== + { + "sessid": "OBoeXKMQx3zmaZrS_v3FOP7_Ze66fYA61TGhtm9s0Qk", + "session_name": "SESSd14344a17ca11d13bda8baf612c0efa5", + "token": "C2dfCUcN4hjgt6u2Xmv15mc1nkj5uv1Iqpa8QE3d7E8", + "user": { + "access": "1492546345", + "created": "1488377334", + "data": false, + "field_about": [], + "init": "admin@example.com", + "language": "", + "login": 1492546519, + "mail": "admin@example.com", + "name": "admin", + "og_user_node": { + "und": [ + { + "target_id": "1" + }, + { + "target_id": "2" + }, + { + "target_id": "3" + } + ] + }, + "picture": null, + "roles": { + "2": "authenticated user" + }, + "signature": "", + "signature_format": null, + "status": "1", + "theme": "", + "timezone": "UTC", + "uid": "1", + "uuid": "5eb4da39-cfba-4d43-bb45-691ebcde8f70" + } + } -.. code-block:: php +Retrieve session token +====================== - // Set up request URL. - $request_url = 'http://example.com/api/dataset/node/' . $resource_id . '/attach_file'; +Request +------- - // Setup file data. - $file_data = array( - 'files[1]' => curl_file_create($file), - 'field_name' => 'field_upload', - 'attach' => 1 - ); +.. code:: - // Set up request. - $curl = curl_init($request_url); - curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data','Accept: application/json', 'X-CSRF-Token: ' . $csrf_token)); - curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST. - curl_setopt($curl, CURLOPT_POSTFIELDS, $file_data); // Set POST data. - curl_setopt($curl, CURLOPT_COOKIE, "$cookie_session"); - curl_setopt($curl, CURLOPT_HEADER, FALSE); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); - curl_setopt($curl, CURLOPT_FAILONERROR, TRUE); + POST http://docker:32774/services/session/token + Accept: application/json + Cookie: SESSd14344a17ca11d13bda8baf612c0efa5=OBoeXKMQx3zmaZrS_v3FOP7_Ze66fYA61TGhtm9s0Qk + Content-Length: 0 - // Execute request and get response. - $response = curl_exec($curl); +Response +-------- -Create a Dataset -================ +.. code:: -.. code-block:: php + XBWI44XD33XBIANLpyK-rtvRa0N5OcaC03qLx0VQsP4 - // Set up request URL. - $request_url = 'http://example.com/api/dataset/node'; - - // Set up dataset data. - // A great explanation on how to target each node field can be found on the 'Identifying field names' article linked on the 'Documentation' section. - $dataset_data = array( - 'type' => 'dataset', - 'title' => 'Example dataset', - 'status' => 1, - 'body[und][0][value]' => 'The description', - 'field_resources[und][0][target_id]' => 'Madison Polling Places (5)' // Resource title plus node id - 'field_author[und][0][value]' => 'Bob Lafollette' - ); - $dataset_data = http_build_query($dataset_data); +Create dataset +============== - // Set up request. - $curl = curl_init($request_url); - curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json', 'X-CSRF-Token: ' . $csrf_token)); - curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST. - curl_setopt($curl, CURLOPT_POSTFIELDS, $dataset_data); // Set POST data. - curl_setopt($curl, CURLOPT_COOKIE, "$cookie_session"); - curl_setopt($curl, CURLOPT_HEADER, FALSE); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); - curl_setopt($curl, CURLOPT_FAILONERROR, TRUE); +Request +------- - // Execute request and get response. - $response = curl_exec($curl); +.. code-block:: bash -*********************** -Testing in the terminal -*********************** + POST http://docker:32774/api/dataset/node + Content-Type: application/json + Accept: application/json + X-CSRF-Token: XBWI44XD33XBIANLpyK-rtvRa0N5OcaC03qLx0VQsP4 + Cookie: SESSd14344a17ca11d13bda8baf612c0efa5=OBoeXKMQx3zmaZrS_v3FOP7_Ze66fYA61TGhtm9s0Qk + Content-Length: 44 -If you want to quickly test that the functionality is working, you can run the following commands from a terminal. + { + "type": "dataset", + "title": "Test Dataset" + } -Replace the domain, username and password in the commands below to match your development environment, and then replace the token value with the token from the response to the authentication request. +Response +-------- -Users -===== +.. code-block:: json + + { + "nid": "75", + "uri": "http://docker:32774/api/dataset/node/75" + } + +Create resource +=============== -Authentication (login) ----------------------- +Request +------- .. code-block:: bash - curl -X POST -i -H "Content-type: application/json" -H "Accept: application/json" -c cookies.txt -X POST http://demo.getdkan.com/api/dataset/user/login -d '{ - "username":"admin", - "password":"password" - }' + POST http://docker:32774/api/dataset/node + Content-Type: application/json + Accept: application/json + X-CSRF-Token: XBWI44XD33XBIANLpyK-rtvRa0N5OcaC03qLx0VQsP4 + Cookie: SESSd14344a17ca11d13bda8baf612c0efa5=OBoeXKMQx3zmaZrS_v3FOP7_Ze66fYA61TGhtm9s0Qk + Content-Length: 97 + + { + "type": "resource", + "field_dataset_ref": {"und": {"target_id": "75"}}, + "title": "Test Resource" + } +Response +-------- -This will return the cookie and the **CSRF token** that we need to reuse for all -the authenticated user iteration via the API. +.. code-block:: json + { + "nid": "76", + "uri": "http://docker:32774/api/dataset/node/76" + } -Content (Datasets, resource) -============================ +Retrieve parent dataset to check resource ID +============================================ -Retrive dataset ---------------- +Request +------- .. code-block:: bash - curl http://demo.getdkan.com/api/dataset/node/22.json + GET http://docker:32774/api/dataset/node/75 + Accept: application/json + X-CSRF-Token: XBWI44XD33XBIANLpyK-rtvRa0N5OcaC03qLx0VQsP4 + Cookie: SESSd14344a17ca11d13bda8baf612c0efa5=OBoeXKMQx3zmaZrS_v3FOP7_Ze66fYA61TGhtm9s0Qk -Example response: +Response +-------- .. code-block:: json { - "vid": "52", - "uid": "1", - "title": "Wisconsin Polling Places", - "log": "Update to resource 'Madison Polling Places'", - "status": "1", - "comment": "0", - "promote": "0", - "sticky": "0", - "vuuid": "30daa43f-aa4a-477a-b011-047ce3d5007e", - "nid": "22", - "type": "dataset", - "language": "und", - "created": "1360541580", - "changed": "1477369101", - "tnid": "0", - "translate": "0", - "uuid": "934400f2-a5dc-4abf-bf16-3f17335888d3", - "revision_timestamp": "1477369101", - "revision_uid": "1", - "body": { - "und": [ - { - "value": "

Polling places in the state of Wisconsin.

\n", - "summary": null, - "format": "html", - "safe_value": "

Polling places in the state of Wisconsin.

\n", - "safe_summary": "" - } - ] - }, - "field_additional_info": [], - "field_author": { - "und": [ - { - "value": "Wisconsin Board of Elections", - "format": null, - "safe_value": "Wisconsin Board of Elections" - } - ] - }, - "field_conforms_to": [], - "field_contact_email": { - "und": [ - { - "value": "datademo@nucivic.com", - "format": null, - "safe_value": "datademo@nucivic.com" - } - ] - }, - "field_contact_name": { - "und": [ - { - "value": "Couch, Aaron", - "format": null, - "safe_value": "Couch, Aaron" - } - ] - }, - "field_data_dictionary": [], - "field_data_dictionary_type": [], - "field_frequency": { - "und": [ - { - "value": "5" - } - ] - }, - "field_granularity": [], - "field_harvest_source_ref": [], - "field_is_part_of": [], - "field_landing_page": [], - "field_language": [], - "field_license": { - "und": [ - { - "value": "cc-by", - "format": null, - "safe_value": "cc-by" - } - ] - }, - "field_harvest_source_issued": [], - "field_harvest_source_modified": [], - "field_pod_theme": [], - "field_public_access_level": { - "und": [ - { - "value": "public" - } - ] - }, - "field_related_content": [], - "field_resources": { - "und": [ - { - "target_id": "4" - } - ] - }, - "field_rights": [], - "field_spatial": { - "und": [ - { - "wkt": "POLYGON ((-90.415429 46.568478, -90.229213 46.508231, -90.119674 46.338446, -89.09001 46.135799, -88.662808 45.987922, -88.531362 46.020784, -88.10416 45.922199, -87.989145 45.796229, -87.781021 45.675736, -87.791975 45.500474, -87.885083 45.363551, -87.649574 45.341643, -87.742682 45.199243, -87.589328 45.095181, -87.627666 44.974688, -87.819359 44.95278, -87.983668 44.722749, -88.043914 44.563917, -87.928898 44.536533, -87.775544 44.640595, -87.611236 44.837764, -87.403112 44.914442, -87.238804 45.166381, -87.03068 45.22115, -87.047111 45.089704, -87.189511 44.969211, -87.468835 44.552964, -87.545512 44.322932, -87.540035 44.158624, -87.644097 44.103854, -87.737205 43.8793, -87.704344 43.687607, -87.791975 43.561637, -87.912467 43.249452, -87.885083 43.002989, -87.76459 42.783912, -87.802929 42.493634, -88.788778 42.493634, -90.639984 42.510065, -90.711184 42.636034, -91.067185 42.75105, -91.143862 42.909881, -91.176724 43.134436, -91.056231 43.254929, -91.204109 43.353514, -91.215062 43.501391, -91.269832 43.616407, -91.242447 43.775238, -91.43414 43.994316, -91.592971 44.032654, -91.877772 44.202439, -91.927065 44.333886, -92.233773 44.443425, -92.337835 44.552964, -92.545959 44.569394, -92.808852 44.750133, -92.737652 45.117088, -92.75956 45.286874, -92.644544 45.440228, -92.770513 45.566198, -92.885529 45.577151, -92.869098 45.719552, -92.639067 45.933153, -92.354266 46.015307, -92.29402 46.075553, -92.29402 46.667063, -92.091373 46.749217, -92.014696 46.705401, -91.790141 46.694447, -91.09457 46.864232, -90.837154 46.95734, -90.749522 46.88614, -90.886446 46.754694, -90.55783 46.584908))", - "geo_type": "polygon", - "lat": "44.635", - "lon": "-90.0142", - "left": "-92.8855", - "top": "46.9573", - "right": "-87.0307", - "bottom": "42.4936", - "srid": null, - "accuracy": null, - "source": null - } - ] - }, - "field_spatial_geographical_cover": { - "und": [ - { - "value": "Wisconsin, United States", - "format": null, - "safe_value": "Wisconsin, United States" - } - ] - }, - "field_tags": { - "und": [ - { - "tid": "9" - } - ] - }, - "field_temporal_coverage": [], - "og_group_ref": { - "und": [ - { - "target_id": "1" - } - ] - }, - "field_topic": [], - "field_orphan": { - "und": [ - { - "value": "0" - } - ] - }, - "rdf_mapping": { - "rdftype": [ - "sioc:Item", - "foaf:Document" - ], - "title": { - "predicates": [ - "dc:title" - ] - }, - "created": { - "predicates": [ - "dc:date", - "dc:created" - ], - "datatype": "xsd:dateTime", - "callback": "date_iso8601" - }, - "changed": { - "predicates": [ - "dc:modified" - ], - "datatype": "xsd:dateTime", - "callback": "date_iso8601" - }, - "body": { - "predicates": [ - "content:encoded" - ] + "body": [], + "changed": "1492544349", + "comment": "0", + "created": "1492544348", + "data": "b:0;", + "field_additional_info": [], + "field_author": [], + "field_conforms_to": [], + "field_contact_email": [], + "field_contact_name": [], + "field_data_dictionary": [], + "field_data_dictionary_type": [], + "field_frequency": [], + "field_granularity": [], + "field_harvest_source_ref": [], + "field_is_part_of": [], + "field_landing_page": [], + "field_language": [], + "field_license": { + "und": [ + { + "format": null, + "safe_value": "notspecified", + "value": "notspecified" + } + ] }, - "uid": { - "predicates": [ - "sioc:has_creator" - ], - "type": "rel" + "field_modified_source_date": [], + "field_orphan": { + "und": [ + { + "value": "0" + } + ] }, - "name": { - "predicates": [ - "foaf:name" - ] + "field_pod_theme": [], + "field_public_access_level": { + "und": [ + { + "value": "public" + } + ] }, - "comment_count": { - "predicates": [ - "sioc:num_replies" - ], - "datatype": "xsd:integer" + "field_related_content": [], + "field_resources": { + "und": [ + { + "target_id": "76" + } + ] }, - "last_activity": { - "predicates": [ - "sioc:last_activity_date" - ], - "datatype": "xsd:dateTime", - "callback": "date_iso8601" - } - }, - "path": "http://demo.getdkan.com/dataset/wisconsin-polling-places", - "name": "admin", - "picture": "0", - "data": "b:0;" + "field_rights": [], + "field_spatial": [], + "field_spatial_geographical_cover": [], + "field_tags": [], + "field_temporal_coverage": [], + "field_topic": [], + "language": "und", + "log": "", + "name": "admin", + "nid": "75", + "og_group_ref": [], + "path": "http://docker:32774/dataset/test-dataset-16", + "picture": "0", + "promote": "0", + "revision_timestamp": "1492544349", + "revision_uid": "1", + "status": "1", + "sticky": "0", + "title": "Test Dataset", + "tnid": "0", + "translate": "0", + "type": "dataset", + "uid": "1", + "uuid": "d53881b3-d80f-49c2-8815-897321fe926e", + "vid": "117", + "vuuid": "c4663ada-0162-4780-8ee5-347c6c037429" } -Create a new dataset --------------------- +.. note:: -This will need an authenticated user with appropriate permissions. The headers -include the user credentials (cookie and CSRF token). + The correct resource ID, `76`, has been added to `field_resources`. + +Update dataset +============== + +Request +------- .. code-block:: bash - curl -X POST -i -H "Content-type: application/json" -H "X-CSRF-Token: 8RniaOCwrsK8Mvue0al_C6EMAraTg26jzklDdLLgvns" -b cookies.txt -X POST http://demo.getdkan.com//api/dataset/node -d '{ - "title":"A node created via DKAN REST API", - "type":"dataset", - "body": { - "und": [{"value": "This should be the description"}] - } - }' + PUT http://docker:32774/api/dataset/node/75 + Content-Type: application/json + Accept: application/json + X-CSRF-Token: XBWI44XD33XBIANLpyK-rtvRa0N5OcaC03qLx0VQsP4 + Cookie: SESSd14344a17ca11d13bda8baf612c0efa5=OBoeXKMQx3zmaZrS_v3FOP7_Ze66fYA61TGhtm9s0Qk + Content-Length: 34 -Update dataset title --------------------- + {"title": "Updated dataset title"} -To update content we use the PUT HTTP method. This will add the word "UPDATED" to the title: +Response +-------- -.. code-block:: bash +.. code-block:: json - curl -X PUT -i -H "Content-type: application/json" -H "X-CSRF-Token: 8RniaOCwrsK8Mvue0al_C6EMAraTg26jzklDdLLgvns" -b cookies.txt http://demo.getdkan.com//api/dataset/node/22 -d '{ - "title":"A node created with services 3.x and REST server - UPDATED" - }' + { + "nid": "75", + "uri": "http://docker:32774/api/dataset/node/75" + } -Update a dataset field ----------------------- +Add a file to a resource +======================== -Titles are a core property for content in Drupal. Updating additional content-type-specific fields requires a slightly more complex data structure. To update a dataset's frequency, for instance: +Request +------- .. code-block:: bash - curl -X PUT -i -H "Content-type: application/json" -H "X-CSRF-Token: 8RniaOCwrsK8Mvue0al_C6EMAraTg26jzklDdLLgvns" -b cookies.txt http://demo.getdkan.com/api/dataset/node/22 -d '{ - "field_frequency": {"und":{"value": 6}} - }' + POST http://docker:32774/api/dataset/node/76/attach_file + Accept: application/json + X-CSRF-Token: XBWI44XD33XBIANLpyK-rtvRa0N5OcaC03qLx0VQsP4 + Cookie: SESSd14344a17ca11d13bda8baf612c0efa5=OBoeXKMQx3zmaZrS_v3FOP7_Ze66fYA61TGhtm9s0Qk + Content-Length: 474 + Content-Type: multipart/form-data; boundary=5f8b431c36a24c828044cd876b3aa669 + + --5f8b431c36a24c828044cd876b3aa669 + Content-Disposition: form-data; name="attach" + + 0 + --5f8b431c36a24c828044cd876b3aa669 + Content-Disposition: form-data; name="field_name" + + field_upload + --5f8b431c36a24c828044cd876b3aa669 + Content-Disposition: form-data; name="files[1]"; filename="tension_sample_data.csv" + + tension,current,timestamp + 220,10,2016-05-27T19:56:41.870Z + 50,15,2016-05-27T19:51:21.794Z + 230,10,2016-05-27T19:56:41.870Z + --5f8b431c36a24c828044cd876b3aa669-- +.. note:: + + Setting the ``attach`` parameter to ``0`` ensures that the file will replace any existing file on the resource. Setting it to `1` will result in a rejected request if the resource already has an attached file (but it will work if the resource's file upload field is empty). -Because the REST API runs input through the dataset node form for validation, the data structure may differ for different fields. For instance, because it is a "Select or license" field, the structure for changing the License field on a dataset to "cc-nc" (Creative Commons Non-Commercial) would be: + +Response +-------- .. code-block:: json { - "field_license": {"und": {"select": {"value": "cc-nc"}}} + "fid": "38", + "uri": "http://docker:32774/api/dataset/file/38" } -See the `Services documentation on custom fields `_ for more detailed information. +Retrieve the resource to check the file field +============================================= + +Request +------- + +.. code-block:: bash + + GET http://docker:32774/api/dataset/node/76 + Accept: application/json + X-CSRF-Token: XBWI44XD33XBIANLpyK-rtvRa0N5OcaC03qLx0VQsP4 + Cookie: SESSd14344a17ca11d13bda8baf612c0efa5=OBoeXKMQx3zmaZrS_v3FOP7_Ze66fYA61TGhtm9s0Qk + + None + +.. note:: + + We still use the `/api/dataset` endpoint to retrieve a resource node (or any other type of node) by nid. + +Response +-------- + +.. code-block:: json + + { + "body": [], + "changed": "1492544350", + "comment": "0", + "created": "1492544349", + "data": "b:0;", + "field_dataset_ref": { + "und": [ + { + "target_id": "75" + } + ] + }, + "field_datastore_status": { + "und": [ + { + "value": "2" + } + ] + }, + "field_format": { + "und": [ + { + "tid": "32" + } + ] + }, + "field_link_api": [], + "field_link_remote_file": [], + "field_orphan": { + "und": [ + { + "value": "0" + } + ] + }, + "field_upload": { + "und": [ + { + "alt": "", + "delimiter": null, + "embed": null, + "fid": "38", + "filemime": "text/csv", + "filename": "tension_sample_data.csv", + "filesize": "120", + "graph": null, + "grid": null, + "map": null, + "metadata": [], + "service_id": null, + "status": "1", + "timestamp": "1492544350", + "title": "", + "type": "undefined", + "uid": "1", + "uri": "public://tension_sample_data.csv", + "uuid": "87019111-7ef0-48e5-b8a4-ea2c392f2e56" + } + ] + }, + "language": "und", + "log": "", + "name": "admin", + "nid": "76", + "og_group_ref": [], + "path": "http://docker:32774/dataset/updated-dataset-title/resource/34b45055-bc10-416f-a8ba-8b9f27718362", + "picture": "0", + "promote": "0", + "revision_timestamp": "1492544350", + "revision_uid": "1", + "status": "1", + "sticky": "0", + "title": "Test Resource", + "tnid": "0", + "translate": "0", + "type": "resource", + "uid": "1", + "uuid": "34b45055-bc10-416f-a8ba-8b9f27718362", + "vid": "118", + "vuuid": "ac1c1aa3-f6ee-4f76-a2f9-6510d9504680" + } -Add new resource to dataset ---------------------------- +************** +Testing it out +************** -This is a two-step process with the API: +Command Line (curl) +=================== -1. Create the resource node: +If you want to quickly test that the functionality is working, you can use curl to send requests a terminal. + +Authentication +-------------- .. code-block:: bash - curl -X POST -i -H "Content-type: application/json" -H "X-CSRF-Token: 8RniaOCwrsK8Mvue0al_C6EMAraTg26jzklDdLLgvns" -b cookies.txt -X POST http://demo.getdkan.com/api/dataset/node -d '{ - "title":"A resource created via the DKAN REST API", - "type":"resource", - "body": {"und": [{"value": "This should be the description for the resource."}]}, - "field_link_api": {"und": [{"url": "http://data.worldbank.org/"}]} + curl -X POST -i -H "Content-type: application/json" -H "Accept: application/json" -c cookies.txt -X POST http://docker:32774/api/dataset/user/login -d '{ + "username":"admin", + "password":"password" }' -2. Attach the newly created resource node to the parent dataset. Use the node ids that match the dataset and resource created by the commands above. +This will return the cookie and the **CSRF token** that we need to reuse for all +the authenticated user iteration via the API. + +Create a new dataset +-------------------- + +This will need an authenticated user with appropriate permissions. The headers +include the user credentials (cookie and CSRF token). .. code-block:: bash - curl -X PUT -i -H "Content-type: application/json" -H "X-CSRF-Token: 8RniaOCwrsK8Mvue0al_C6EMAraTg26jzklDdLLgvns" -b cookies.txt http://demo.getdkan.com/api/dataset/node/43 -d '{ - "field_resources": {"und": [{"target_id": "A resource created via the DKAN REST APIs (45)"}]} + curl -X POST -i -H "Content-type: application/json" -H "X-CSRF-Token: 8RniaOCwrsK8Mvue0al_C6EMAraTg26jzklDdLLgvns" -b cookies.txt -X POST http://docker:32774/api/dataset/node -d '{ + "title":"A node created via DKAN REST API", + "type":"dataset", + "body": { + "und": [{"value": "This should be the description"}] + } }' +In a PHP script +=============== -.. note:: +Log In and get the Session Cookie +--------------------------------- - The provided value (`A resource create via the DKAN REST API (45)`) is the value expected from the dataset entry form, with "45" being the resource node id. +.. code-block:: php -Query for url/values of previous revision of file. --------------------------------------------------- + // Setup request URL. + $request_url = 'http://docker:32774/api/dataset/user/login'; -The assumption in this example is that the file is stored remotely and we are looking to get the link as it was set in a previous revision of the resource node. + // Prepare user data. + $user_data = array( + 'username' => 'theusername', + 'password' => 'theuserpassword', + ); + $user_data = http_build_query($user_data); -Versions/revisions are tracked via Durpal's ``vid`` identifier. We can query a specific node revision (for example `vid` 89) using the vid as parameter + // Set up request. + $curl = curl_init($request_url); + curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json')); -.. code-block:: bash + // Accept JSON response. + curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST. + curl_setopt($curl, CURLOPT_POSTFIELDS, $user_data); // Set POST data. + curl_setopt($curl, CURLOPT_HEADER, FALSE); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($curl, CURLOPT_FAILONERROR, TRUE); + + // Execute request and get response. + $response = curl_exec($curl); - curl -X GET -gi -H "Content-type: application/json" -H "X-CSRF-Token: 8RniaOCwrsK8Mvue0al_C6EMAraTg26jzklDdLLgvns" -b cookies.txt 'http://demo.getdkan.com/api/dataset/node.json?parameters[vid]=89' + // Process response. + $logged_user = json_decode($response); + + // Save cookie session to be used on future requests. + $cookie_session = $logged_user->session_name . '=' . $logged_user->sessid; +Get the CSRF Token +------------------ + +.. code-block:: php + + // Setup request URL. + $request_url = 'http://example.com/services/session/token'; + + // Setup request. + $curl = curl_init($request_url); + curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json')); // Accept JSON response. + curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST. + curl_setopt($curl, CURLOPT_COOKIE, "$cookie_session"); // Send the cookie session that we got after login. + curl_setopt($curl, CURLOPT_HEADER, FALSE); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($curl, CURLOPT_FAILONERROR, TRUE); + + // Execute request and save CSRF Token. + $csrf_token = curl_exec($curl); + +Create a Dataset +---------------- + +.. code-block:: php + + // Set up request URL. + $request_url = 'http://example.com/api/dataset/node'; + + // Set up dataset data. + // A great explanation on how to target each node field can be found on the 'Identifying field names' article linked on the 'Documentation' section. + $dataset_data = array( + 'type' => 'dataset', + 'title' => 'Example dataset', + 'status' => 1, + 'body[und][0][value]' => 'The description', + 'field_resources[und][0][target_id]' => 'Madison Polling Places (5)', // Resource title plus node id + 'field_author[und][0][value]' => 'Bob Lafollette' + ); + $dataset_data = http_build_query($dataset_data); + + // Set up request. + $curl = curl_init($request_url); + curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json', 'X-CSRF-Token: ' . $csrf_token)); + curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST. + curl_setopt($curl, CURLOPT_POSTFIELDS, $dataset_data); // Set POST data. + curl_setopt($curl, CURLOPT_COOKIE, "$cookie_session"); + curl_setopt($curl, CURLOPT_HEADER, FALSE); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($curl, CURLOPT_FAILONERROR, TRUE); + + // Execute request and get response. + $response = curl_exec($curl); + +Python client +============= + +Be sure to look at the `pydkan Python client `_ to see a working API client you can build on for your own applications. + +Safe FME Integration +==================== + +Building on the pydkan client, the `FME Workflows `_ repo provides code and instructions for integrating DKAN into `Safe FME `_ workflows. + +************ Known issues ------------- +************ * Datasets and other content nodes can only be queried via node id or other entity. UUID support pending. + * There is currently no way to request a previous revision of a dataset or resource. * Upon attaching a file to a resource via the API, DKAN will immediately import this file to the Datastore if it is a valid CSV. This may not always be the desired behavior; more control over datastore behavior should be available to API clients. diff --git a/dkan/docs/components/dataset/datasetfeatures.rst b/dkan/docs/components/dataset/datasetfeatures.rst index ad2ae2e5d..812f3fd1c 100644 --- a/dkan/docs/components/dataset/datasetfeatures.rst +++ b/dkan/docs/components/dataset/datasetfeatures.rst @@ -7,11 +7,11 @@ The metadata in a DKAN Dataset is culled from the DCAT standard as well as Proje The Dataset form allows users to create Datasets and add appropriate metadata: -.. figure:: ../../images/add-dataset-screen-1.png +.. image:: ../../images/add-dataset-screen-1.png The DKAN Dataset API exposes Dataset metadata for individual datasets as well an entire catalog. -.. figure:: ../../images/data-json.png +.. image:: ../../images/data-json.png .. _custom_metadata: @@ -22,7 +22,7 @@ It is easy to add new fields to DKAN which will show up on the Dataset form, mak If there is information that only pertains to one or more datasets then it is possible to use the "Additional Info" field. This allows content editors to add unique field / value entries that exist only on a single dataset: -.. figure:: https://cloud.githubusercontent.com/assets/512243/4188796/57b53a52-3776-11e4-97f6-61e18e3cd90d.png +.. image:: ../../images/dataset_metadata_additional_info.png Globally-available custom fields can also be added through `Drupal's Fields UI `_ and added to public APIs using the :doc:`Open Data Schema Mapper <../open-data-schema>`. diff --git a/dkan/docs/components/dataset/groups.rst b/dkan/docs/components/dataset/groups.rst index 5030685cd..30dee5ba5 100644 --- a/dkan/docs/components/dataset/groups.rst +++ b/dkan/docs/components/dataset/groups.rst @@ -13,7 +13,7 @@ How to use Groups ----------------- Adding a new Group -``````````````````` +****************** When adding a new Group, the form has fields for basic information about the Group itself that should tell site visitors what to expect from the Datasets in the Group. :Title: Name your Group to reflect the agency or whoever the common data publisher is for the datasets that will belong to the Group. @@ -34,7 +34,7 @@ Once you've added a new Group, you can assign Datasets (and their Resources) to .. _group_roles_permissions: Roles and Permissions -````````````````````` +********************* With large sites there is often a need to have special permissions for a group of users to handle a specific set of content. Think of a large agency or department with sub-departments or programs that produce content. On the one hand these users shouldn’t have the ability to manage or edit content for the entire site or other Groups. On the other hand it would be impractical for Editors or Site Managers to handle content for a large number of users. To keep content organized and in the hands of its owners without introducing the risk of inadvertent (and sometimes irreversible) actions, Group-level permissions give users the ability to do things they couldn’t necessarily do on the site outside of the Group. @@ -49,7 +49,7 @@ Within Groups there are different levels of access a user can have, which determ Administrators of Groups are able to add and remove Group members and manage (create/edit/delete) all content within the Group. It’s good practice to have only 1 or 2 users in this role for any given Group. Adding users -```````````` +************ Adding users to a Group is a straightforward process. Click on the "Group" tab on the group page and click "Add people". Begin typing the username of an existing user into the "User name" field and select from the list of autocomplete options. A user must already have an account to be added to a Group, so if a person needs to be added you should first create an account for them with the appropriate role. By default a user will only have a Member role in the Group. To give the user an Administrator role and permissions, check the administrator member box. diff --git a/dkan/docs/components/dataset/usage.rst b/dkan/docs/components/dataset/usage.rst index bfad310c0..c1d8bbae5 100644 --- a/dkan/docs/components/dataset/usage.rst +++ b/dkan/docs/components/dataset/usage.rst @@ -2,7 +2,7 @@ Usage ===== Creating Datasets and Resources ------------------------------------- +------------------------------- DKAN’s data publishing model is based on the concept of :ref:`datasets ` and :ref:`resources `. A dataset is a container for one or more resources; a resource is the actual “data” being published, such as a CSV table, a GeoJSON data file, or a TIFF aerial image. @@ -18,7 +18,7 @@ By default, only authenticated (“logged-in”) users can add new Datasets and The Dataset is the container for the actual data resource files and contains basic information about the data, such as title, description, category tags, and license. Once we’ve entered information about the data, we can click the “Next: Add data” button to begin adding data. Step 2: Add one or more Resources to the Dataset -************************** +************************************************ After creating a dataset, we’re prompted to add one or more data resources to it. There are three types of Resources that can be added to a Dataset, depending on the type and location of the Resource: @@ -53,7 +53,7 @@ At the bottom of the *Add Resource* page, we can choose: In our example, we’re only adding a single resource, so we’ll click “Next: Additional Info” to move onto Step 3. If we had more than one resource to add to this dataset, we would choose the “Save and add another” option. Simply clicking "Save" would end the Dataset creation process and save the dataset, for now, with no additional metadata. Step 3: Adding Metadata to a Dataset -************************** +************************************ We now come to a third form which allows us to add additional metadata to the dataset. All these fields are optional, but provide valuable information about your dataset to both human visitors to the website and machines discovering your dataset through one of :doc:`DKAN's public APIs <../../apis/index>`. @@ -77,7 +77,7 @@ Configuration Adding or Removing Allowed Resource File Types ********************************************** -Any type of file can be uploaded to Resources (though only CSV files can be imported to the :doc:`Datastore <../datastore/index>`. +Any type of file can be uploaded to Resources (though only CSV files can be imported to the :doc:`Datastore <../datastore>`. File types are controlled at "/admin/structure/types/manage/resource/fields/field_upload" diff --git a/dkan/docs/components/datastore.rst b/dkan/docs/components/datastore.rst index 596fbacf5..a20a4ec3b 100644 --- a/dkan/docs/components/datastore.rst +++ b/dkan/docs/components/datastore.rst @@ -28,6 +28,13 @@ Click the "Manage Datastore" button at the top of the screen. On the "Manage Dat Your data is now ready to use via the API! Click the "Data API" button at the top of the resource screen for specific instructions. +TAB delimiter support +--------------------- + +DKAN supports TAB delimiters for csv files and other file extensions that commonly use TABs as delimiters. The autodetect format function is available for this file types (the format detected will be TSV) and the recline previews will work. + +The TAB delimiter support has been introduced to the datastore import functionality, so if your resource contains a csv file separated by TABs and you visit the "Manage Datastore" tab, you'll have an option in the 'Delimiter' dropdown to select TAB. Once you select that option and press the 'Import' button, your resource will be imported and should be shown as expected in the resource preview. + Processing Options ------------------- diff --git a/dkan/docs/components/harvest.rst b/dkan/docs/components/harvest.rst index a007f7ded..682288c17 100644 --- a/dkan/docs/components/harvest.rst +++ b/dkan/docs/components/harvest.rst @@ -1,5 +1,5 @@ DKAN Harvest -============== +============ DKAN Harvest is a module that provides a common harvesting framework for DKAN. It supports custom extensions and adds `drush `_ @@ -16,10 +16,10 @@ DKAN Harvest is built on top of the widely-used follows a two-step process to import datasets: 1. Process a source URI and save resulting data locally to disk as JSON -2. Perform migrations into DKAN with the locally cached JSON files, using mappings provided by the `DKAN Migrate Base `_ module. +2. Perform migrations into DKAN with the locally cached JSON files, using mappings provided by the `DKAN Migrate Base module `_ . Harvest Sources ----------------- +--------------- Harvest Sources are nodes that store the source's URI and some additional configuration. Users with the administrator or site manager role will be able to create and manage harvest sources. @@ -27,7 +27,7 @@ configuration. Users with the administrator or site manager role will be able to Create a new harvest source *************************** -1. Go to ``node/add/harvest-source`` or Content > Add content > Harvest Source, and fill out the form. +Go to ``node/add/harvest-source`` or Content > Add content > Harvest Source, and fill out the form. :Title: Administrative title for the source. :Description: Administrative description or notes about the source. @@ -43,7 +43,7 @@ The form includes four multi-value fields to help you fine tune the results of y Project Open Data (as well as most metadata APIs) includes many fields that are not simple key-value pairs. If you need to access or modify nested array values you can use this dot syntax to specify the path: `key.nested_key.0.other_nested_key`. For example, the Publisher field in Project Open Data is expressed like this: -.. code-block:: json +.. code-block:: JavaScript "publisher": { "@type": "org:Organization", @@ -55,17 +55,26 @@ To access the name property for filtering or overriding, you can set `publisher. .. figure:: ../images/harvest-filters.png -2. Click **Save**, the datasets from the source will be cached, and you will see a preview of what will be imported. This preview page shows a list of dataset titles and identifiers now in the harvest cache, allowing you to perform a basic check on your source configuration. If it does not look right, click the **Edit** tab to make adjustments. +Harvest sources also include a :ref:`Topics ` field. Chose one or more topics to apply them to *every* dataset harvested from that source. -3. Click **Harvest Now**. The datasets that were cached will now be imported into your site. +Now click **Save**. The datasets from the source will be cached, and you will see a preview of what will be imported. This preview page shows a list of dataset titles and identifiers now in the harvest cache, allowing you to perform a basic check on your source configuration. If it does not look right, click the **Edit** tab to make adjustments. + +Click **Harvest Now**. The datasets that were cached will now be imported into your site. .. figure:: ../images/harvest-search.png Harvest Source nodes are viewable by the public and provide some basic metadata to the user. +.. note:: + Some behaviors of the Topics field on *harvest sources* to be aware of: + + - Changing the Topic on the source and re-harvesting will not update the Topic on harvested datasets if nothing else has changed. The Harvester will only re-import a dataset if it detects changes from the source. + - If you manually add additional topics to a harvested dataset, and there *is* a change at the source, the next time the dataset is harvested your topics will be overwritten. + Managing Harvest Sources -************************** -From the admin menu, navigate to DKAN > DKAN Harvest Dashboard to view harvest sources. The DKAN Harvest Dashboard provides site managers a quick overview of harvest sources, when they were last updated, number of datasets, and status of the source. The dashboard also allows site managers to perform manual harvest operations: +************************ + +From the admin menu, navigate to DKAN > DKAN Harvest Dashboard to view *harvest sources*. The DKAN Harvest Dashboard provides site managers a quick overview of *harvest sources*, when they were last updated, number of *datasets*, and status of the source. The dashboard also allows site managers to perform manual harvest operations: :Harvest (cache and migrate): This will cache the source data locally and migrate that source data into your site content. :Cache source(s): This will fetch the source data, apply the source configuration (filters, excludes, etc.) and cache the data locally without migrating. You may wish to do this to check for errors, or to refresh the preview. @@ -79,25 +88,27 @@ Click on the title of a harvest source from the dashboard to see the details of .. figure:: ../images/harvest-source-node.png -:View: View the harvest source node. -:Edit: Click to make changes to the configuration of the harvest source. +:View: View the *harvest source* node. +:Edit: Click to make changes to the configuration of the *harvest source*. :Preview: Click to pull the latest data from the source endpoint into the cache. :Manage Datasets: An administrative view that lets you sort and filter the datasets from this source. The most powerful function on this page is to filter by **orphan** status. When a dataset that was harvested into your system previously is no longer provided in the source, it is considered "orphaned" on your site and unpublished. From the Manage Datasets screen, you can either permanently delete or re-publish orphan datasets. -:Events: Event Log that provides historical data on all harvests run on this source. The information is managed by the core ``dkan_harvest`` via a per-harvest source ``migrate_log`` table that tracks the number of datasets created, updated, failed, orphaned, and unchanged and status. If the value for the field Status is Error then you can click on the text to see the log error and identify the problem. +:Events: Event Log that provides historical data on all harvests run on this source. The information is managed by the core ``dkan_harvest`` via a per-harvest source ``migrate_log`` table that tracks the number of *datasets* created, updated, failed, orphaned, and unchanged and status. If the value for the field Status is Error then you can click on the text to see the log error and identify the problem. :Errors: Error log that shows a list of all errors recorded during harvesting on the source. +Harvested Resources +******************* +When datasets are harvested, the resources are added as remote files, which means they are links to the original files on the remote server. If you modify the *resource* node in your DKAN site, your changes will be overwritten the next time a harvest is performed. If you add a harvested resource to the :doc:`datastore ` be sure to set up periodic importing so that the resource stays in sync with the source. For these reasons, we do not recommend that you create visualizations based on harvested resources as the visualizations could break when changes are made to the files upstream. Harvest Drush Commands ------------------------ -DKAN Harvest provides multiple drush commands to manage harvest sources and control harvest jobs. In fact, once your sources are properly configured, running harvests from Drush on a cron job or other scheduling system like `Jenkins `_ is highly reccomended. +---------------------- + +DKAN Harvest provides multiple drush commands to manage *harvest sources* and control harvest jobs. In fact, once your sources are properly configured, running harvests from Drush on a cron job or other scheduling system like `Jenkins `_ is highly reccomended. -It is recommanded to pass the ``--user=1`` drush option to -harvest operation (especially harvest migration jobs) to make sure that the -entities created have a proper user as author. +It is recommanded to pass the ``--user=1`` option to harvest drush operations (especially harvest migration jobs) to make sure that the entities created have a proper user as author. List Harvest sources available -******************************* +****************************** .. code-block:: sh @@ -177,7 +188,7 @@ checklist: Define a new Harvest Source Type ************************************** -DKAN Harvest leverages Drupal's hook system to provide a way to extend the Source types that DKAN Harvest supports. To add a new harvest source type the we return their definitions as array items via the +DKAN Harvest leverages Drupal's hook system to provide a way to extend the source types that DKAN Harvest supports. To add a new harvest source type the we return their definitions as array items via the ``hook_harvest_source_types()`` hook. .. code-block:: php @@ -228,7 +239,7 @@ Cache callbacks This callback takes care of downloading/filtering/altering the data from the source end-point to the local file directory provided by the -HarvestSource::getCacheDir() method. The recommended folder structure for +``HarvestSource::getCacheDir()`` method. The recommended folder structure for cached data is to have one dataset per uniqely named file. The actual migration is then performed on the cached data, not on the remote source itself. @@ -249,9 +260,9 @@ is then performed on the cached data, not on the remote source itself. The harvest cache function needs to support the modifications to the source -available from the harvest source via the Filter, Excludes, Overrides and Default +available from the *harvest source* via the Filter, Excludes, Overrides and Default fields. Each of these configurations is available -from the HarvestSource object via the ``HarvestSource::filters``, +from the ``HarvestSource`` object via the ``HarvestSource::filters``, ``HarvestSource::excludes``, ``HarvestSource::overrides``, ``HarvestSource::defaults`` methods. @@ -267,7 +278,7 @@ module. DKAN Harvest will support only migration classes extended from during the harvest cache step to create the DKAN `dataset` and associated nodes. -Implementing a Harvest Source Type Migration class is the matter of checking +Implementing a Harvest Source Type migration class is the matter of checking couple of boxes: * Wire the cached files on the ``HarvestMigration::__construct()`` method. @@ -276,12 +287,12 @@ couple of boxes: custom fields on the ``HarvestMigration::prepareRow()`` and the ``HarvestMigration::prepare()``. -Working on the Migration Class for Harvest Source Type should be straitforward, -but a good knowladge on how `migrate works `_ is a big help. +Working on the migration class for Harvest Source Type should be straightforward, +but a good knowladge of how `Migrate module works `_ is a big help. ``HarvestMigration::__construct()`` ************************************** -Setting the `HarvestMigrateSourceList` is the only logic required during the +Setting the ```HarvestMigrateSourceList`` is the only logic required during the construction of the extended `HarvestMigration`. During the harvest migration we can't reliably determin and parse the type of cache file (JSON, XML, etc..) so we still need to provide this information to the Migration class via the @@ -349,7 +360,7 @@ Example code snippet: Harvest and `DKAN Workflow `_ support ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -By default, DKAN Harvest will make sure that the harvested dataset node will be +By default, DKAN Harvest will make sure that the harvested *dataset* node will be set to the ``published`` moderation state if the DKAN Workflow module is enabled on the DKAN site. This can be changed at the fields mapping level by overriding the ``workbench_moderation_state_new`` field. diff --git a/dkan/docs/components/search.rst b/dkan/docs/components/search.rst index a069a45ae..9e1272ae1 100644 --- a/dkan/docs/components/search.rst +++ b/dkan/docs/components/search.rst @@ -1,28 +1,28 @@ Search -======= +====== DKAN offers a faceted search similar to CKAN. This functionality is provided by the `Search API `_ and `Search API DB `_ modules. DKAN can easily be updated to use Apache Solr to power the search using the `Search API Solr `_ module. Search API ------------- +---------- The `Search API `_ module provides a framework for easily creating searches on any entity known to Drupal, using any kind of search engine. It incorporates facet support and the ability to use the Views module for displaying search results. Apache Solr ------------- +----------- `Search API Solr Search `_ provides a Solr backend for the Search API module, and delivers enterprise class, high performance search functionality. Apache Solr runs as a separate service from the web server and requires extra resources to integrate into your website. This can increase the price for hosting. Recommended for high traffic sites. **Requirements:** -- `Search API `_ module -- `Search API Solr Search `_ module -- An `Apache Solr `_ server. +- `Search API module `_ +- `Search API Solr Search module `_ +- An `Apache Solr server `_ For further details see the `Search API Solr's handbook documentation `_. DB vs Solr Search -^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^ Solr: * PRO: Increased performance and scalability for complex queries. * PRO: Reduce database size. @@ -37,7 +37,7 @@ DB: Switching to Solr -^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^ To switch from the native database to Solr simply: * Create or purchase a Solr instance diff --git a/dkan/docs/components/theme.rst b/dkan/docs/components/theme.rst index c1befb8fc..fac19fa74 100644 --- a/dkan/docs/components/theme.rst +++ b/dkan/docs/components/theme.rst @@ -152,4 +152,4 @@ dkan-topics This font is used for the Content Type and :doc:`Topics ` icons, see `Streamline Icons `_ -If you would like to use your own icon font for Topics, use the :doc:`steps outlined here `. +If you would like to use your own icon font for Topics, use the :ref:`steps outlined here `. diff --git a/dkan/docs/components/topics.rst b/dkan/docs/components/topics.rst index 549b61979..31cdd69d2 100644 --- a/dkan/docs/components/topics.rst +++ b/dkan/docs/components/topics.rst @@ -1,3 +1,5 @@ +.. _topics: + DKAN Topics =========== @@ -30,7 +32,7 @@ Editing topic terms ------------------------------------ 1. From the Administration menu, navigate to ``Site Configuration > Taxonomy > Topics`` -2. You will see a list of current topic terms, click the 'edit' link under Operations that corresponds to the term you would like to edit. +2. You will see a list of current topic terms, click the 'edit' link under Operations that corresponds to the term you would like to edit. 3. Make changes and click "Save". Removing Topics from the main menu @@ -41,6 +43,8 @@ Removing Topics from the main menu 3. Uncheck the box under "Enabled" for Topics 4. Click "Save configuration" +.. _`adding_new_icons`: + Adding new icons ------------------------------------ The font used for Topics can only be changed if there are **NO** default icon values in use, only one icon font can be used at a time. diff --git a/dkan/docs/components/visualizations/datapreviews.rst b/dkan/docs/components/visualizations/datapreviews.rst index 699217358..91dd78f3d 100644 --- a/dkan/docs/components/visualizations/datapreviews.rst +++ b/dkan/docs/components/visualizations/datapreviews.rst @@ -6,12 +6,16 @@ DKAN allows users to have a preview of their data when uploaded to or linked to This functionality is provided via the `Recline module `_, which is not part of the core DKAN repository but is a basic dependency of it (and will be included when building the distribution via ``drush make``). Recline.js -------------- +---------- DKAN, like CKAN, offers an integration with the `Recline `_ Javascript library. Recline allows site visitors to preview tabular data visually. The preview works for CSV and XLS [*]_ files that are uploaded to the DKAN site or hosted remotely and linked to, as well as for data stored in DKAN's local SQL-based :doc:`datastore <../datastore>`. +**Record limit:** The previews will display up to 100 records by default. You can use the pager to preview additional results based on the range given. If you want to preview more than 100 records at a time, adjust the max range value to the desired range. + +.. figure:: ../../images/pager.png + Grid View -************* +********* All tabular data can be rendered as spreadsheet-style rows and columns: .. figure:: ../../images/csv-preview.png @@ -21,13 +25,13 @@ All tabular data can be rendered as spreadsheet-style rows and columns: .. figure:: ../../images/xls-format.png Map View -************* +******** Visitors can preview data that contains either coordinates or GeoJSON on a `Leaflet.js `_ -based map: .. image:: ../../images/map-preview.png Graph View -************* +********** If enabled, visitors can chose one column of your data as an X-axis, one or more as Y-axis data, and preview your data as a bar, point or line graph. .. image:: ../../images/graph-preview.png @@ -38,20 +42,20 @@ Files can only be previewed if they are well formatted and small enough to rende If files are too large to preview within 1 second you will get the following message *"File was too large or unavailable for preview."* -Files that are too large to preview in the browser can be previewed by :doc:`adding them to the datastore <../datastore/index>`. Once a file is in the datastore the preview is only asking for the first 25 rows of the data. Thus large datasets can be previewed. +Files that are too large to preview in the browser can be previewed by :doc:`adding them to the datastore <../datastore>`. Once a file is in the datastore the preview is only asking for the first 25 rows of the data. Thus large datasets can be previewed. Additional Preview Types ----------------------------- -DKAN provides preview formats for several additional file types beyond what is supported by Recline.js, these include: JSON, geojson, XML, ArcGIS REST, WMS, images, PDF, and ZIP files. These additional preview formatters are defined in a forked version of `Recline `_ +------------------------ +DKAN provides preview formats for several additional file types beyond what is supported by Recline.js, these include: JSON, geojson, XML, ArcGIS REST, WMS, images, PDF, and ZIP files. These additional preview formatters are defined in a `forked version of Recline `_ Zip files -**************** +********* DKAN offers the ability to preview the files and folders locked in ZIP files. DKAN will display a list of contents for ZIP files uploaded as resources on datasets. .. image:: ../../images/zip-preview.png Image files -**************** +*********** Image files (JPG, PNG or GIF) uploaded as resources will be displayed directly on the resource page. .. image:: ../../images/image-preview.png @@ -65,13 +69,13 @@ DKAN can use Leaflet to display a preview of a `WMS server `_ or a `valid css color name `_ -:Transition Time: Time in ms it takes for graph to animate. +~~~~~~~~~~~~~~~~~~~~~~ +:Color: Set the color the chart is drawn in. Use either a `HEX color code `_ or a `valid css color name `_ Separate multiple colors with commas. :Goal: Overlay a goal or target line on the chart. :Margin: Enter value of margin in the order: *top, right, bottom, left* :Show Title: Display the title you entered on step 1. :Show Controls: Whether to show extra controls or not. Extra controls include things like making multiBar charts stacked or side by side. -:Show Legend: Display a legend for the chart. -:Group By X Field: For multiple series values Y will show values grouped by X +:Show Legend: Display a legend for the chart. :Show Tooltips: Shows data and label on hover. -:Reduce Ticks: Reduces the number of axis values displayed. +:Group By X Field: If there are two or more rows that have the same value in the column assigned to the x-axis field, those rows will be combined and display as a single data point. This is only relevant for combining numerical data. +:Fewer X-axis Labels: Reduces the number of labels displayed along the x-axis. + +Save the chart +**************** +Remember to click **Finish** to save your configuration changes. Recline ***************** diff --git a/dkan/docs/components/visualizations/visualization_entity/choropleth.rst b/dkan/docs/components/visualizations/visualization_entity/choropleth.rst index a57c04557..3ea059d5f 100644 --- a/dkan/docs/components/visualizations/visualization_entity/choropleth.rst +++ b/dkan/docs/components/visualizations/visualization_entity/choropleth.rst @@ -1,5 +1,5 @@ Choropleth -=========== +========== .. warning:: Under Development. Do not use on production. @@ -66,4 +66,5 @@ Create Visualization .. image:: images/choropleth-step-07.png + Click **Save** & Enjoy! + .. image:: images/choropleth-step-08.png diff --git a/dkan/docs/components/visualizations/visualization_entity/images/chart-configuration.png b/dkan/docs/components/visualizations/visualization_entity/images/chart-configuration.png new file mode 100644 index 000000000..1d8e45bc3 Binary files /dev/null and b/dkan/docs/components/visualizations/visualization_entity/images/chart-configuration.png differ diff --git a/dkan/docs/components/visualizations/visualization_entity/images/chart-define-variables.png b/dkan/docs/components/visualizations/visualization_entity/images/chart-define-variables.png new file mode 100644 index 000000000..9ec8c53d5 Binary files /dev/null and b/dkan/docs/components/visualizations/visualization_entity/images/chart-define-variables.png differ diff --git a/dkan/docs/components/visualizations/visualization_entity/images/chart-filter-editor.png b/dkan/docs/components/visualizations/visualization_entity/images/chart-filter-editor.png index 62fc7002c..6694966f1 100644 Binary files a/dkan/docs/components/visualizations/visualization_entity/images/chart-filter-editor.png and b/dkan/docs/components/visualizations/visualization_entity/images/chart-filter-editor.png differ diff --git a/dkan/docs/components/visualizations/visualization_entity/images/chart-pager.png b/dkan/docs/components/visualizations/visualization_entity/images/chart-pager.png new file mode 100644 index 000000000..f987098cb Binary files /dev/null and b/dkan/docs/components/visualizations/visualization_entity/images/chart-pager.png differ diff --git a/dkan/docs/components/visualizations/visualization_entity/images/chart-query-editor.png b/dkan/docs/components/visualizations/visualization_entity/images/chart-query-editor.png index 51bdffba8..af062024c 100644 Binary files a/dkan/docs/components/visualizations/visualization_entity/images/chart-query-editor.png and b/dkan/docs/components/visualizations/visualization_entity/images/chart-query-editor.png differ diff --git a/dkan/docs/components/visualizations/visualization_entity/images/chart-step-1.png b/dkan/docs/components/visualizations/visualization_entity/images/chart-step-1.png deleted file mode 100644 index 07811b105..000000000 Binary files a/dkan/docs/components/visualizations/visualization_entity/images/chart-step-1.png and /dev/null differ diff --git a/dkan/docs/components/visualizations/visualization_entity/images/chart-step-1n.png b/dkan/docs/components/visualizations/visualization_entity/images/chart-step-1n.png new file mode 100644 index 000000000..f8f820d23 Binary files /dev/null and b/dkan/docs/components/visualizations/visualization_entity/images/chart-step-1n.png differ diff --git a/dkan/docs/components/visualizations/visualization_entity/images/chart-step-2.png b/dkan/docs/components/visualizations/visualization_entity/images/chart-step-2.png deleted file mode 100644 index 425a75e14..000000000 Binary files a/dkan/docs/components/visualizations/visualization_entity/images/chart-step-2.png and /dev/null differ diff --git a/dkan/docs/components/workflow.rst b/dkan/docs/components/workflow.rst index 7ef67e1f2..509c8e15f 100644 --- a/dkan/docs/components/workflow.rst +++ b/dkan/docs/components/workflow.rst @@ -141,6 +141,8 @@ text area. .. image:: ../images/workflow/workflow_node_edit.png +.. _`workflow-roles`: + Workflow Roles --------------------------- DKAN workflow permissions provides 3 Drupal roles: diff --git a/dkan/docs/development/license.rst b/dkan/docs/development/license.rst index 0cfcae25d..6491724e3 100644 --- a/dkan/docs/development/license.rst +++ b/dkan/docs/development/license.rst @@ -46,6 +46,6 @@ Additional notes about the behavior of both hooks References to the code ---------------------- -+ Hooks are invoked `here `_ -+ Field formatter implementation for the license field is in `here `_ ++ Hooks are invoked in `dkan_dataset_content_types.license.field.inc `_ ++ Field formatter implementation for the license field is in `dkan_dataset_content_types.module `_ diff --git a/dkan/docs/development/modules.rst b/dkan/docs/development/modules.rst index 09c79eeb2..41e80c4e6 100644 --- a/dkan/docs/development/modules.rst +++ b/dkan/docs/development/modules.rst @@ -1,5 +1,5 @@ Community Contributions ----------------------- +----------------------- What follows is a list of modules from the community that extend DKAN's functionality. Many are developed by the DKAN team themselves but are still in diff --git a/dkan/docs/images/dataset_metadata_additional_info.png b/dkan/docs/images/dataset_metadata_additional_info.png new file mode 100644 index 000000000..d30a057af Binary files /dev/null and b/dkan/docs/images/dataset_metadata_additional_info.png differ diff --git a/dkan/docs/images/harvest_dashboard.png b/dkan/docs/images/harvest_dashboard.png new file mode 100644 index 000000000..e991f88fa Binary files /dev/null and b/dkan/docs/images/harvest_dashboard.png differ diff --git a/dkan/docs/images/harvest_source_event_log.png b/dkan/docs/images/harvest_source_event_log.png new file mode 100644 index 000000000..049599307 Binary files /dev/null and b/dkan/docs/images/harvest_source_event_log.png differ diff --git a/dkan/docs/images/pager.png b/dkan/docs/images/pager.png new file mode 100644 index 000000000..1e7145825 Binary files /dev/null and b/dkan/docs/images/pager.png differ diff --git a/dkan/docs/images/site_manager_playbook/DKAN_APIs/dataset_api_output_formatted.png b/dkan/docs/images/site_manager_playbook/DKAN_APIs/dataset_api_output_formatted.png new file mode 100644 index 000000000..d683f4064 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/DKAN_APIs/dataset_api_output_formatted.png differ diff --git a/dkan/docs/images/site_manager_playbook/DKAN_APIs/dataset_api_output_unformatted.png b/dkan/docs/images/site_manager_playbook/DKAN_APIs/dataset_api_output_unformatted.png new file mode 100644 index 000000000..b6f8b779d Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/DKAN_APIs/dataset_api_output_unformatted.png differ diff --git a/dkan/docs/images/site_manager_playbook/DKAN_APIs/datastore_api_output_formatted.png b/dkan/docs/images/site_manager_playbook/DKAN_APIs/datastore_api_output_formatted.png new file mode 100644 index 000000000..d683f4064 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/DKAN_APIs/datastore_api_output_formatted.png differ diff --git a/dkan/docs/images/site_manager_playbook/DKAN_APIs/datastore_api_output_unformatted.png b/dkan/docs/images/site_manager_playbook/DKAN_APIs/datastore_api_output_unformatted.png new file mode 100644 index 000000000..a7a092506 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/DKAN_APIs/datastore_api_output_unformatted.png differ diff --git a/dkan/docs/images/site_manager_playbook/DKAN_APIs/datastore_tab_view.png b/dkan/docs/images/site_manager_playbook/DKAN_APIs/datastore_tab_view.png new file mode 100644 index 000000000..c4b7f7947 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/DKAN_APIs/datastore_tab_view.png differ diff --git a/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_03.gif b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_03.gif new file mode 100644 index 000000000..b398243f3 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_03.gif differ diff --git a/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_04.png b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_04.png new file mode 100644 index 000000000..0fbc180f8 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_04.png differ diff --git a/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_05.png b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_05.png new file mode 100644 index 000000000..78ccebded Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_05.png differ diff --git a/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_06.png b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_06.png new file mode 100644 index 000000000..728c5bf41 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_06.png differ diff --git a/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_08.png b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_08.png new file mode 100644 index 000000000..95c3fd917 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_08.png differ diff --git a/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_09.gif b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_09.gif new file mode 100644 index 000000000..42b5afcda Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/account_access_and_setup/account_access_and_setup_image_09.gif differ diff --git a/dkan/docs/images/site_manager_playbook/adding_a_user/adding_a_user_01.png b/dkan/docs/images/site_manager_playbook/adding_a_user/adding_a_user_01.png new file mode 100644 index 000000000..ae95b6cfb Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_a_user/adding_a_user_01.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_a_user/adding_a_user_02.png b/dkan/docs/images/site_manager_playbook/adding_a_user/adding_a_user_02.png new file mode 100644 index 000000000..5807e30e7 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_a_user/adding_a_user_02.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/Dashboards_Summary_13.png b/dkan/docs/images/site_manager_playbook/adding_new_content/Dashboards_Summary_13.png new file mode 100644 index 000000000..72d20cc57 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/Dashboards_Summary_13.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/Data_Stories_Summary_13.png b/dkan/docs/images/site_manager_playbook/adding_new_content/Data_Stories_Summary_13.png new file mode 100644 index 000000000..e53e424f8 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/Data_Stories_Summary_13.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_01.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_01.png new file mode 100644 index 000000000..38849f137 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_01.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_02.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_02.png new file mode 100644 index 000000000..ca2fd42b6 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_02.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_03.gif b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_03.gif new file mode 100644 index 000000000..16921535e Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_03.gif differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_04.gif b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_04.gif new file mode 100644 index 000000000..41702873c Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_04.gif differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_05.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_05.png new file mode 100644 index 000000000..096ae9167 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_05.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_06.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_06.png new file mode 100644 index 000000000..bbfb6be1a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_06.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_07.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_07.png new file mode 100644 index 000000000..119c54bd9 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_07.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_08.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_08.png new file mode 100644 index 000000000..5458cea1a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_08.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_09.gif b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_09.gif new file mode 100644 index 000000000..41702873c Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_09.gif differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_10.gif b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_10.gif new file mode 100644 index 000000000..a597b5c8d Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_10.gif differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_11.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_11.png new file mode 100644 index 000000000..4f60e3f95 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_11.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_12.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_12.png new file mode 100644 index 000000000..bf8dba705 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_12.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_13.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_13.png new file mode 100644 index 000000000..e16828c62 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_13.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_14.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_14.png new file mode 100644 index 000000000..f33b8e4a5 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_14.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_15.gif b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_15.gif new file mode 100644 index 000000000..2f3c9da65 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_15.gif differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_16.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_16.png new file mode 100644 index 000000000..ebbc5d14a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_16.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_17.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_17.png new file mode 100644 index 000000000..c31d8beaf Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_17.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_18.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_18.png new file mode 100644 index 000000000..aa662f63e Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_18.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_19.gif b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_19.gif new file mode 100644 index 000000000..0078ec96f Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_19.gif differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_20.gif b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_20.gif new file mode 100644 index 000000000..bb9949e54 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_20.gif differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_21.gif b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_21.gif new file mode 100644 index 000000000..ed281767a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_21.gif differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_22.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_22.png new file mode 100644 index 000000000..3c51c6f79 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_22.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_23.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_23.png new file mode 100644 index 000000000..dd87889c3 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_23.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_25.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_25.png new file mode 100644 index 000000000..f75081acf Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_25.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_26.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_26.png new file mode 100644 index 000000000..f31277d4b Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_26.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_27.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_27.png new file mode 100644 index 000000000..3330d631e Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_27.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_28.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_28.png new file mode 100644 index 000000000..decd2b850 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_28.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_29.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_29.png new file mode 100644 index 000000000..e9d8dcb29 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_29.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_30.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_30.png new file mode 100644 index 000000000..e6ca6b4d1 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_30.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_31.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_31.png new file mode 100644 index 000000000..bbfb6be1a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_31.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_32.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_32.png new file mode 100644 index 000000000..954257936 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_32.png differ diff --git a/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_33.png b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_33.png new file mode 100644 index 000000000..ebb63b220 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/adding_new_content/adding_new_content_33.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_01.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_01.png new file mode 100644 index 000000000..55319ad2b Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_01.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_02.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_02.png new file mode 100644 index 000000000..b81577bea Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_02.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_03.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_03.png new file mode 100644 index 000000000..8af54b6f4 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_03.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_04.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_04.png new file mode 100644 index 000000000..04333a758 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_04.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_05.gif b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_05.gif new file mode 100644 index 000000000..552b436c0 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_05.gif differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_06.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_06.png new file mode 100644 index 000000000..5c78d78ce Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_06.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_07.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_07.png new file mode 100644 index 000000000..28bfed519 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_07.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_08.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_08.png new file mode 100644 index 000000000..3ae2e9550 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_08.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_09.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_09.png new file mode 100644 index 000000000..285b38327 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_09.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_10.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_10.png new file mode 100644 index 000000000..bd175a49c Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_10.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_11.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_11.png new file mode 100644 index 000000000..cb2a83082 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_11.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_12.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_12.png new file mode 100644 index 000000000..66080acaa Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_12.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_13.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_13.png new file mode 100644 index 000000000..5995c93e9 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_13.png differ diff --git a/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_14.png b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_14.png new file mode 100644 index 000000000..5e824917a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/admin_menu/admin_menu_14.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_01.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_01.png new file mode 100644 index 000000000..b64e6159b Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_01.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_02.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_02.png new file mode 100644 index 000000000..45f839038 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_02.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_03.gif b/dkan/docs/images/site_manager_playbook/appearance/appearance_03.gif new file mode 100644 index 000000000..ea768d1b9 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_03.gif differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_04.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_04.png new file mode 100644 index 000000000..3b8071308 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_04.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_05.gif b/dkan/docs/images/site_manager_playbook/appearance/appearance_05.gif new file mode 100644 index 000000000..9c62d30d3 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_05.gif differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_06.gif b/dkan/docs/images/site_manager_playbook/appearance/appearance_06.gif new file mode 100644 index 000000000..7686e4ba0 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_06.gif differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_07.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_07.png new file mode 100644 index 000000000..4e0f8637a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_07.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_08.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_08.png new file mode 100644 index 000000000..467a41cd1 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_08.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_09.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_09.png new file mode 100644 index 000000000..c97be67a9 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_09.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_10.gif b/dkan/docs/images/site_manager_playbook/appearance/appearance_10.gif new file mode 100644 index 000000000..e3fb20521 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_10.gif differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_11.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_11.png new file mode 100644 index 000000000..cd8344303 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_11.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_12.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_12.png new file mode 100644 index 000000000..6de9cb5c6 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_12.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_13.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_13.png new file mode 100644 index 000000000..203284cf3 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_13.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_14.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_14.png new file mode 100644 index 000000000..97f82a167 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_14.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_15.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_15.png new file mode 100644 index 000000000..7829e26ca Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_15.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/appearance_16.png b/dkan/docs/images/site_manager_playbook/appearance/appearance_16.png new file mode 100644 index 000000000..705ed5eba Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/appearance_16.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/colorizer_dropdown.png b/dkan/docs/images/site_manager_playbook/appearance/colorizer_dropdown.png new file mode 100644 index 000000000..bce81d7a0 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/colorizer_dropdown.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/colorizer_in_action.png b/dkan/docs/images/site_manager_playbook/appearance/colorizer_in_action.png new file mode 100644 index 000000000..7ac3eb384 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/colorizer_in_action.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/global_settings.png b/dkan/docs/images/site_manager_playbook/appearance/global_settings.png new file mode 100644 index 000000000..7d2ba739b Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/global_settings.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/nuboot_theme.png b/dkan/docs/images/site_manager_playbook/appearance/nuboot_theme.png new file mode 100644 index 000000000..e38e110bc Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/nuboot_theme.png differ diff --git a/dkan/docs/images/site_manager_playbook/appearance/theme_settings_link.png b/dkan/docs/images/site_manager_playbook/appearance/theme_settings_link.png new file mode 100644 index 000000000..ab9fd81a3 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/appearance/theme_settings_link.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_and_content/dataset_page.png b/dkan/docs/images/site_manager_playbook/data_and_content/dataset_page.png new file mode 100644 index 000000000..975fbf18b Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_and_content/dataset_page.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_and_content/groups_list.png b/dkan/docs/images/site_manager_playbook/data_and_content/groups_list.png new file mode 100644 index 000000000..3d1bc4113 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_and_content/groups_list.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_and_content/multiple_pie_charts.png b/dkan/docs/images/site_manager_playbook/data_and_content/multiple_pie_charts.png new file mode 100644 index 000000000..ac21e84d9 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_and_content/multiple_pie_charts.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_and_content/old_bar_chart.png b/dkan/docs/images/site_manager_playbook/data_and_content/old_bar_chart.png new file mode 100644 index 000000000..a2e689f5f Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_and_content/old_bar_chart.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_and_content/page_layout_options.png b/dkan/docs/images/site_manager_playbook/data_and_content/page_layout_options.png new file mode 100644 index 000000000..bc2e45448 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_and_content/page_layout_options.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_and_content/resources_list_on_dataset_page.png b/dkan/docs/images/site_manager_playbook/data_and_content/resources_list_on_dataset_page.png new file mode 100644 index 000000000..7205e35fe Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_and_content/resources_list_on_dataset_page.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_and_content/stories_page.png b/dkan/docs/images/site_manager_playbook/data_and_content/stories_page.png new file mode 100644 index 000000000..fc987fc27 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_and_content/stories_page.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_management/datastore_actions.png b/dkan/docs/images/site_manager_playbook/data_management/datastore_actions.png new file mode 100644 index 000000000..a1e37257e Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_management/datastore_actions.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_management/datastore_fast_import_option.png b/dkan/docs/images/site_manager_playbook/data_management/datastore_fast_import_option.png new file mode 100644 index 000000000..2081a1cfc Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_management/datastore_fast_import_option.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_management/datastore_import_animation.gif b/dkan/docs/images/site_manager_playbook/data_management/datastore_import_animation.gif new file mode 100644 index 000000000..0e1bd396b Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_management/datastore_import_animation.gif differ diff --git a/dkan/docs/images/site_manager_playbook/data_management/datastore_import_options.png b/dkan/docs/images/site_manager_playbook/data_management/datastore_import_options.png new file mode 100644 index 000000000..d3ef23014 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_management/datastore_import_options.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_management/manage_datastore_page.png b/dkan/docs/images/site_manager_playbook/data_management/manage_datastore_page.png new file mode 100644 index 000000000..f24877c69 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_management/manage_datastore_page.png differ diff --git a/dkan/docs/images/site_manager_playbook/data_management/resource_page_with_datastore_message.png b/dkan/docs/images/site_manager_playbook/data_management/resource_page_with_datastore_message.png new file mode 100644 index 000000000..632b2a134 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/data_management/resource_page_with_datastore_message.png differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_01.png b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_01.png new file mode 100644 index 000000000..270235afd Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_01.png differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_02.png b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_02.png new file mode 100644 index 000000000..add552756 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_02.png differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_03.gif b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_03.gif new file mode 100644 index 000000000..f15f70537 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_03.gif differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_04.png b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_04.png new file mode 100644 index 000000000..abfc86078 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_04.png differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_05.png b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_05.png new file mode 100644 index 000000000..0b6ade6de Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_05.png differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_06.gif b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_06.gif new file mode 100644 index 000000000..22abc3b2f Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_06.gif differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_07.png b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_07.png new file mode 100644 index 000000000..14fbd1ede Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_07.png differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_08.png b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_08.png new file mode 100644 index 000000000..af326aa43 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_08.png differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_09.gif b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_09.gif new file mode 100644 index 000000000..42b128f30 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_09.gif differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_10.gif b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_10.gif new file mode 100644 index 000000000..7ece7d48a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_10.gif differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_11.png b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_11.png new file mode 100644 index 000000000..11871a340 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_11.png differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_12.gif b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_12.gif new file mode 100644 index 000000000..611da6406 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_12.gif differ diff --git a/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_13.png b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_13.png new file mode 100644 index 000000000..4b9efbae6 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/group_roles_and_permissions/group_roles_perms_13.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/content_admin_menu.png b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_admin_menu.png new file mode 100644 index 000000000..1cef5060e Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_admin_menu.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/content_admin_page.png b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_admin_page.png new file mode 100644 index 000000000..f802e23fd Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_admin_page.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revision_information.png b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revision_information.png new file mode 100644 index 000000000..cc7d4d3b3 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revision_information.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revision_information_animation.gif b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revision_information_animation.gif new file mode 100644 index 000000000..18bee351b Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revision_information_animation.gif differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revisions_options.png b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revisions_options.png new file mode 100644 index 000000000..ceb208bcf Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revisions_options.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revisions_tab.png b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revisions_tab.png new file mode 100644 index 000000000..73f59d957 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_revisions_tab.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/content_status_dropdown.png b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_status_dropdown.png new file mode 100644 index 000000000..36e7d66c3 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_status_dropdown.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/content_type_dropdown.png b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_type_dropdown.png new file mode 100644 index 000000000..98f3cb7ec Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/content_type_dropdown.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/dataset_changes_view.png b/dkan/docs/images/site_manager_playbook/managing_existing_content/dataset_changes_view.png new file mode 100644 index 000000000..072c7ac7d Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/dataset_changes_view.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/dataset_changes_view_with_additional_edits.png b/dkan/docs/images/site_manager_playbook/managing_existing_content/dataset_changes_view_with_additional_edits.png new file mode 100644 index 000000000..cd18f432d Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/dataset_changes_view_with_additional_edits.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/edit_dataset_animation.gif b/dkan/docs/images/site_manager_playbook/managing_existing_content/edit_dataset_animation.gif new file mode 100644 index 000000000..59c35083e Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/edit_dataset_animation.gif differ diff --git a/dkan/docs/images/site_manager_playbook/managing_existing_content/editing_bulk_content_animation.gif b/dkan/docs/images/site_manager_playbook/managing_existing_content/editing_bulk_content_animation.gif new file mode 100644 index 000000000..552b436c0 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_existing_content/editing_bulk_content_animation.gif differ diff --git a/dkan/docs/images/site_manager_playbook/managing_users/managing_users_01.png b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_01.png new file mode 100644 index 000000000..00594a288 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_01.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_users/managing_users_02.png b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_02.png new file mode 100644 index 000000000..e823a10f2 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_02.png differ diff --git a/dkan/docs/images/site_manager_playbook/managing_users/managing_users_03.gif b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_03.gif new file mode 100644 index 000000000..319f52894 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_03.gif differ diff --git a/dkan/docs/images/site_manager_playbook/managing_users/managing_users_04.gif b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_04.gif new file mode 100644 index 000000000..475d485a6 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_04.gif differ diff --git a/dkan/docs/images/site_manager_playbook/managing_users/managing_users_05.gif b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_05.gif new file mode 100644 index 000000000..98081d35d Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_05.gif differ diff --git a/dkan/docs/images/site_manager_playbook/managing_users/managing_users_06.png b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_06.png new file mode 100644 index 000000000..f4a1474cd Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/managing_users/managing_users_06.png differ diff --git a/dkan/docs/images/site_manager_playbook/open_data_workflow_guide/Data_Moderate_Content_13.png b/dkan/docs/images/site_manager_playbook/open_data_workflow_guide/Data_Moderate_Content_13.png new file mode 100644 index 000000000..6283eff6e Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/open_data_workflow_guide/Data_Moderate_Content_13.png differ diff --git a/dkan/docs/images/site_manager_playbook/open_data_workflow_guide/Data_Workbench_13.png b/dkan/docs/images/site_manager_playbook/open_data_workflow_guide/Data_Workbench_13.png new file mode 100644 index 000000000..18b58384d Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/open_data_workflow_guide/Data_Workbench_13.png differ diff --git a/dkan/docs/images/site_manager_playbook/open_data_workflow_guide/Data_Workbench_Moderation_13.png b/dkan/docs/images/site_manager_playbook/open_data_workflow_guide/Data_Workbench_Moderation_13.png new file mode 100644 index 000000000..b4c4e635e Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/open_data_workflow_guide/Data_Workbench_Moderation_13.png differ diff --git a/dkan/docs/images/site_manager_playbook/people/people_01.png b/dkan/docs/images/site_manager_playbook/people/people_01.png new file mode 100644 index 000000000..a7c3806ad Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/people/people_01.png differ diff --git a/dkan/docs/images/site_manager_playbook/people/people_02.png b/dkan/docs/images/site_manager_playbook/people/people_02.png new file mode 100644 index 000000000..e6a12a836 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/people/people_02.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/added_topic.png b/dkan/docs/images/site_manager_playbook/structure/added_topic.png new file mode 100644 index 000000000..fbaa0e3d6 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/added_topic.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/default_topics_list.png b/dkan/docs/images/site_manager_playbook/structure/default_topics_list.png new file mode 100644 index 000000000..8bef8231b Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/default_topics_list.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/delete_tag_animation.gif b/dkan/docs/images/site_manager_playbook/structure/delete_tag_animation.gif new file mode 100644 index 000000000..902a3f519 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/delete_tag_animation.gif differ diff --git a/dkan/docs/images/site_manager_playbook/structure/edit_font_options.png b/dkan/docs/images/site_manager_playbook/structure/edit_font_options.png new file mode 100644 index 000000000..50d78abde Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/edit_font_options.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/edit_url_alias_animation.gif b/dkan/docs/images/site_manager_playbook/structure/edit_url_alias_animation.gif new file mode 100644 index 000000000..c2a1938c7 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/edit_url_alias_animation.gif differ diff --git a/dkan/docs/images/site_manager_playbook/structure/font_icon_options.png b/dkan/docs/images/site_manager_playbook/structure/font_icon_options.png new file mode 100644 index 000000000..ee8802114 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/font_icon_options.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/font_icon_select_options.png b/dkan/docs/images/site_manager_playbook/structure/font_icon_select_options.png new file mode 100644 index 000000000..2b42256fb Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/font_icon_select_options.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/format_list.png b/dkan/docs/images/site_manager_playbook/structure/format_list.png new file mode 100644 index 000000000..c77e88061 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/format_list.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/global_blacklist_selection.png b/dkan/docs/images/site_manager_playbook/structure/global_blacklist_selection.png new file mode 100644 index 000000000..6abd8e0f0 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/global_blacklist_selection.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/highlighted_topics.png b/dkan/docs/images/site_manager_playbook/structure/highlighted_topics.png new file mode 100644 index 000000000..e3d496e29 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/highlighted_topics.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/image_icon_options.png b/dkan/docs/images/site_manager_playbook/structure/image_icon_options.png new file mode 100644 index 000000000..c2af37064 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/image_icon_options.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/ordered_topic_display.png b/dkan/docs/images/site_manager_playbook/structure/ordered_topic_display.png new file mode 100644 index 000000000..ef4f4fabc Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/ordered_topic_display.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/ordered_topic_list.png b/dkan/docs/images/site_manager_playbook/structure/ordered_topic_list.png new file mode 100644 index 000000000..ace466f2a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/ordered_topic_list.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/structure_03.png b/dkan/docs/images/site_manager_playbook/structure/structure_03.png new file mode 100644 index 000000000..8bef8231b Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/structure_03.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/structure_19.png b/dkan/docs/images/site_manager_playbook/structure/structure_19.png new file mode 100644 index 000000000..17fcabc6a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/structure_19.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/tags_field.png b/dkan/docs/images/site_manager_playbook/structure/tags_field.png new file mode 100644 index 000000000..2f87044f1 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/tags_field.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/tags_list.png b/dkan/docs/images/site_manager_playbook/structure/tags_list.png new file mode 100644 index 000000000..e752b2184 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/tags_list.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/topic_options_animation.gif b/dkan/docs/images/site_manager_playbook/structure/topic_options_animation.gif new file mode 100644 index 000000000..09bd668d1 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/topic_options_animation.gif differ diff --git a/dkan/docs/images/site_manager_playbook/structure/topics_admin_menu.png b/dkan/docs/images/site_manager_playbook/structure/topics_admin_menu.png new file mode 100644 index 000000000..885107066 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/topics_admin_menu.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/upload_font_library.png b/dkan/docs/images/site_manager_playbook/structure/upload_font_library.png new file mode 100644 index 000000000..b355d2821 Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/upload_font_library.png differ diff --git a/dkan/docs/images/site_manager_playbook/structure/url_aliases_list.png b/dkan/docs/images/site_manager_playbook/structure/url_aliases_list.png new file mode 100644 index 000000000..09369e22a Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/structure/url_aliases_list.png differ diff --git a/dkan/docs/images/site_manager_playbook/workflow/moderate.png b/dkan/docs/images/site_manager_playbook/workflow/moderate.png new file mode 100644 index 000000000..6283eff6e Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/workflow/moderate.png differ diff --git a/dkan/docs/images/site_manager_playbook/workflow/my_drafts.png b/dkan/docs/images/site_manager_playbook/workflow/my_drafts.png new file mode 100644 index 000000000..b4c4e635e Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/workflow/my_drafts.png differ diff --git a/dkan/docs/images/site_manager_playbook/workflow/my_workbench.png b/dkan/docs/images/site_manager_playbook/workflow/my_workbench.png new file mode 100644 index 000000000..18b58384d Binary files /dev/null and b/dkan/docs/images/site_manager_playbook/workflow/my_workbench.png differ diff --git a/dkan/docs/images/site_manager_playbook/workflow/temp.txt b/dkan/docs/images/site_manager_playbook/workflow/temp.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/dkan/docs/images/site_manager_playbook/workflow/temp.txt @@ -0,0 +1 @@ + diff --git a/dkan/docs/introduction/about.md b/dkan/docs/introduction/about.md index 6576b7a8b..52abdcbfd 100644 --- a/dkan/docs/introduction/about.md +++ b/dkan/docs/introduction/about.md @@ -57,3 +57,60 @@ When referring to **`$variables`**, **`function_names()`** and **`classNames`** ``` **`This text`** will be code-styled and bold ``` + +## Building this documentation + +If you contribute significantly to this documentation, at some point you will want to be able to build them locally to preview your formatting and other markup. This will require some degree of comfort with command-line tools but is otherwise fairly straightforward. + +### Sphinx + +`Sphinx `_ is the Python application that generates the HTML from the documentation markup. + +To work on sphinx documentation locally, install the Sphinx Python tools. This requires having the `easy_install` tool in your environment. + +Install pip (the python package manager): + +```bash +$ sudo easy_install pip +``` + +Then install sphinx + +```bash +$ sudo pip install sphinx +``` + +Install the dependencies for this project. Make sure you are in the `/docs` directory: + +```bash +$ cd docs +$ sudo pip install -r requirements.txt +``` + +Now you should be able to build the Sphinx site by typing + +```bash +$ make html +``` + +The site will build in `_build/html` + +### Auto-build server + +If you install the `sphinx-autobuild package` with pip, you can run a server that will build automatically when it senses a file change, and refresh your browser. Run + +```bash +$ sudo pip install sphinx-autobuild +``` + +...then, from the /docs directory, run: + +```bash +$ sphinx-autobuild ./ _build/html +``` + +The autobuild tool sometimes does not pick up changes to indexes very well. If you see issues with the sidebar table of contents, stop the server, delete the `/_build` directory and then re-start the server: + +```bash +$ rm -rf _build && sphinx-autobuild ./ _build/html +``` diff --git a/dkan/docs/introduction/get-dkan.md b/dkan/docs/introduction/get-dkan.md index 9c3dcd7eb..beb3f62ef 100644 --- a/dkan/docs/introduction/get-dkan.md +++ b/dkan/docs/introduction/get-dkan.md @@ -44,6 +44,16 @@ Choose to make a new site from scratch, and to use the DKAN distribution: Pantheon will then build your new based site on the latest DKAN release. You will go through a normal Drupal install process, explained in detail in the [installation instructions](../installation.md). +#### Using Terminus + +Pantheon provides a command-line tool called [Terminus](https://pantheon.io/docs/terminus/) for interacting with all aspects of site management on their platform. Once you have [installed Terminus](https://pantheon.io/docs/terminus/install/), you can spin up a new instance of DKAN with the command: + +``` +$ terminus site:create dkan-example-site "DKAN Example Site" d7370d7e-46fb-4b10-b79f-942b5abf51de +``` + +Replace "DKAN Example Site" with the name of your new DKAN site. The last argument, `d7370d7e-46fb-4b10-b79f-942b5abf51de`, is Pantheon's internal ID for the DKAN upstream. After the command completes, you will see your new site on your dashboard. + #### Managing updates Pantheon uses a modified version of Drupal Pressflow, which is [publicly available on GitHub](https://github.com/pantheon-systems/drops-7). Whenever a new version of the DKAN distribution is released, the changes are merged into a version of DKAN special-built for Pantheon, [also available on GitHub](https://github.com/NuCivic/dkan-drops-7). diff --git a/dkan/docs/introduction/index.rst b/dkan/docs/introduction/index.rst index 3f297fe8c..d0b2a66ed 100644 --- a/dkan/docs/introduction/index.rst +++ b/dkan/docs/introduction/index.rst @@ -8,6 +8,7 @@ DKAN is a Drupal-based open data tool with a full suite of cataloging, publishin about catalog-basics + catalog-features dkan-ckan get-dkan installation diff --git a/dkan/docs/styles.md b/dkan/docs/styles.md deleted file mode 100644 index 4c72dbbcc..000000000 --- a/dkan/docs/styles.md +++ /dev/null @@ -1,59 +0,0 @@ -# About this documentation - -What follows is a style guide for the DKAN documentation. Use it both to follow the conventions used throughout the site, and for your own contributions. DKAN's docs are written in a combination of [Markdown](https://daringfireball.net/projects/markdown) (specifiically, [CommonMark](http://commonmark.org/)) and [ReStructuredText (RST)](http://www.sphinx-doc.org/en/stable/rest.html), and built with [Sphynx](http://www.sphinx-doc.org/en/stable/index.html). The docs live in the `/docs` folder of the [DKAN Project](https://github.com/NuCivic/dkan); to suggest modifications, submit a pull request as you would for any suggested code change. - -## File types - -Index files should always be in RST, to render correctly in the sidebar when built. Additional files can be in markdown or RST format depending on your preference. Currently, most DKAN documentation is in Markdown, mainly for historical reasons. - -In some cases, `README.md` files are pulled into the docs site from elsewhere in the repository. This is accomplished with symbolic links in the docs folder. - -## Images - -Screenshots should be taken at standard desktop resolution (no retina!) and avoid showing any browser chrome. If necessary they may contain arrows and annotations in red with sans-serif typeface. - -## Text conventions - -### Modules - -Module names are written in Title Case with no additional styling. Quotes can be used if needed for clarity -- for instance, it might be confusing to talk about how the "Data" module affects data on the site without quote marks. When possible, a module name is linked to its home page (on Drupal.org or Github) on its first mention in a page. - -### Entities and bundles - -A specific content type or other entity bundle is written in italics, as in referring to a `dataset` node or a `chloropleth` visualization. Entity types, like "node," require no additional styling. - -### Files - -Filenames are written as inline code as in this example: `thisfile.txt` will do the trick. - -### Terminal commands - -Terminal commands should be expressed in a full code block, with each line starting with$: - -```bash -$ first -i "run" this-command -$ ../then.this --one -``` - -### Code blocks - -Code blocks are also expressed as... code blocks: - -```php -/** - * Adds declared endpoint to list. - * - * This and hook_open_data_schema_map_load() are necessary so that modules can - * declare more than one endpoint. - */ -function hook_open_data_schema_map_endpoints_alter(&$records) { - $records[] = 'my_machine_name'; -} -``` - -### Code objects -When referring to **`$variables`**, **`function_names()`** and **`classNames`** inline, use bold inline code style. This can be achieved in markdown like this: - -``` -**`This text`** will be code-styled and bold -``` \ No newline at end of file diff --git a/dkan/drupal-org.make b/dkan/drupal-org.make index 767d8652c..259f040e5 100644 --- a/dkan/drupal-org.make +++ b/dkan/drupal-org.make @@ -1,18 +1,21 @@ ---- api: '2' core: 7.x includes: -- https://raw.githubusercontent.com/NuCivic/visualization_entity/7.x-1.2/visualization_entity.make -- https://raw.githubusercontent.com/NuCivic/open_data_schema_map/1.13.6/open_data_schema_map.make -- https://raw.githubusercontent.com/NuCivic/leaflet_draw_widget/5a5f8faf664aeca02371f6692307580d9fab9116/leaflet_widget.make -- https://raw.githubusercontent.com/NuCivic/recline/1.13.6/recline.make + - "https://raw.githubusercontent.com/NuCivic/visualization_entity/7.x-1.x/visualization_entity.make" + - "https://raw.githubusercontent.com/NuCivic/open_data_schema_map/7.x-1.x/open_data_schema_map.make" + - "https://raw.githubusercontent.com/NuCivic/leaflet_draw_widget/master/leaflet_widget.make" + - "https://raw.githubusercontent.com/NuCivic/recline/7.x-1.x/recline.make" projects: admin_menu: - version: 3.0-rc5 + version: '3.0-rc5' admin_menu_source: version: '1.1' patch: - 2441283: https://www.drupal.org/files/issues/allow_ordering_of_the-2441283-5.patch + 2441283: 'https://www.drupal.org/files/issues/allow_ordering_of_the-2441283-5.patch' + admin_views: + version: '1.6' + patch: + 1780004: 'https://www.drupal.org/files/issues/admin_views-duplicate_system_path-1780004-54.patch' adminrole: version: '1.1' autocomplete_deluxe: @@ -57,7 +60,7 @@ projects: date: version: '2.10' defaultconfig: - version: 1.0-alpha11 + version: '1.0-alpha11' devel: version: '1.5' diff: @@ -112,8 +115,8 @@ projects: feeds_flatstore_processor: download: type: git - url: https://github.com/NuCivic/feeds_flatstore_processor.git - revision: 82b2a05bd133dbf870bdf09f1c0a45711f1432e3 + url: 'https://github.com/NuCivic/feeds_flatstore_processor.git' + branch: master field_group: version: '1.5' patch: @@ -183,8 +186,8 @@ projects: leaflet_draw_widget: download: type: git - url: https://github.com/NuCivic/leaflet_draw_widget.git - revision: 5a5f8faf664aeca02371f6692307580d9fab9116 + url: 'https://github.com/NuCivic/leaflet_draw_widget.git' + branch: 'master' libraries: version: '2.3' link: @@ -244,7 +247,7 @@ projects: download: type: git url: https://github.com/NuCivic/open_data_schema_map.git - tag: 7.x-1.13.7 + branch: 7.x-1.x panelizer: version: '3.4' panels: @@ -273,8 +276,8 @@ projects: recline: download: type: git - url: https://github.com/NuCivic/recline.git - tag: 7.x-1.13.7 + url: 'https://github.com/NuCivic/recline.git' + branch: 7.x-1.x ref_field: download: type: git @@ -286,7 +289,7 @@ projects: download: type: git url: https://github.com/NuCivic/remote_stream_wrapper.git - revision: 20311eee8f0ba87cbb7e48788b176c34e0313a78 + branch: 7.x-1.x role_export: version: '1.0' rules: @@ -307,6 +310,8 @@ projects: version: '1.22' search_api_db: version: '1.6' + patch: + 2855634: https://www.drupal.org/files/issues/2855634-23--fix_update_7107_for_different_db.patch select_or_other: version: '2.22' services: @@ -322,8 +327,8 @@ projects: taxonomy_fixtures: download: type: git - url: https://github.com/NuCivic/taxonomy_fixtures.git - revision: b2f092c963f4a24afe1e6443eb9ff01c959079ed + url: 'https://github.com/NuCivic/taxonomy_fixtures.git' + branch: 7.x-1.x token: version: '1.7' uuid: @@ -343,7 +348,7 @@ projects: download: type: git url: https://github.com/NuCivic/visualization_entity.git - tag: 7.x-1.2 + branch: 7.x-1.x type: module workbench: version: '1.2' diff --git a/dkan/libraries/chroma/docs/index.html b/dkan/libraries/chroma/docs/index.html index e2a1285b3..6f9a720d7 100644 --- a/dkan/libraries/chroma/docs/index.html +++ b/dkan/libraries/chroma/docs/index.html @@ -31,7 +31,7 @@

(color)

chroma('hotpink')
 

If there's no matching named color chroma.js checks for a hexadecimal string. It ignores case, the # sign is optional, and the shorter three letter format is recognized as well. So any of these are valid hexadecimal representations: #ff3399, FF3399, #f39, etc.

-
chroma('#ff3399'); 
+
chroma('#ff3399');
 chroma('F39');
 

In addition to hex strings, hexadecimal numbers (in fact, just any number between 0 and 16777215), will be recognized, too.

@@ -139,7 +139,7 @@

(color1, color2)

chroma.distance

(color1, color2, mode='lab')

-

Computes the eucledian distance between two colors in a given color space (default is Lab).

+

Computes the Euclidean distance between two colors in a given color space (default is Lab).

chroma.distance('#fff', '#ff0', 'rgb');
 chroma.distance('#fff', '#f0f', 'rgb');
 chroma.distance('#fff', '#ff0');
@@ -147,7 +147,7 @@ 

(color1, color2, mode='lab')

chroma.deltaE

(reference, sample, L=1, C=1)

-

Computes color difference as developed by the Colour Measurement Committee of the Society of Dyers and Colourists (CMC) in 1984. The implementation is adapted from Bruce Lindbloom. The parameters L and C are weighting factors for lightness and chromacity.

+

Computes color difference as developed by the Colour Measurement Committee of the Society of Dyers and Colourists (CMC) in 1984. The implementation is adapted from Bruce Lindbloom. The parameters L and C are weighting factors for lightness and chromaticity.

chroma.deltaE('#ededee', '#edeeed');
 chroma.deltaE('#ececee', '#eceeec');
 chroma.deltaE('#e9e9ee', '#e9eee9');
@@ -200,9 +200,9 @@ 

(value=1)

color.saturate

(value=1)

-

Changes the saturation of a color by manipulating the Lch chromacity.

-
chroma('slategray').saturate(); 
-chroma('slategray').saturate(2); 
+

Changes the saturation of a color by manipulating the Lch chromaticity.

+
chroma('slategray').saturate();
+chroma('slategray').saturate(2);
 chroma('slategray').saturate(3);
 

color.desaturate

@@ -217,7 +217,7 @@

(channel, value)

Changes a single channel and returns the result a new chroma object.

// change hue to 0 deg (=red)
 chroma('skyblue').set('hsl.h', 0);
-// set chromacity to 30
+// set chromaticity to 30
 chroma('hotpink').set('lch.c', 30);
 

Relative changes work, too:

@@ -500,7 +500,7 @@

cubehelix.scale

.colors(5);
- + @@ -510,9 +510,9 @@

cubehelix.scale

$('code.lang-js').each(function() { - + var code = this; - + var cm = CodeMirror(function(elt) { code.parentNode.replaceChild(elt, code); }, { @@ -559,13 +559,13 @@

cubehelix.scale

function resLong(d) { if (typeof d == 'boolean') { return ''+(d ? 'true' : 'false')+''; - + } else if (typeof d == 'string') { // string color, e.g. hex value return '"'+d+'"'; } else if (typeof d == 'object' && d._rgb) { // chroma.js object - return ''+d.hex()+''; + return ''+d.hex()+''; } else if ($.isNumeric(d)) { return ''+round(d,3)+''; } else if ($.isFunction(d)) { @@ -589,14 +589,14 @@

cubehelix.scale

return '\''+chroma(d).hex()+'\''; } else if (typeof d == 'object' && d._rgb) { // chroma.js object - return '\''+d.hex()+'\''; + return '\''+d.hex()+'\''; } else if ($.isNumeric(d)) { return ''+round(d,2)+''; } else if (isNaN(d)) { return 'NaN'; } } - + function round(d, p) { var n = Math.pow(10, p); return Math.round(d*n) / n; @@ -612,7 +612,7 @@

cubehelix.scale

span.attr('style', ''); return; } - + try { var col = chroma(val), l = col.luminance(); @@ -620,7 +620,7 @@

cubehelix.scale

'background-color:'+col.hex(), 'color:'+(l <0.5 ? 'white' : 'black'), 'opacity:'+col.alpha() - ].join(';')); + ].join(';')); } catch (e) { //console.log(e); span.attr('style', ''); @@ -634,7 +634,7 @@

cubehelix.scale

var span = $(this), slider = $('
').addClass('slider'), input = $('').appendTo(slider); - + span.off('mouseenter').on('mouseenter', function() { var v = +span.text(), d = Math.pow(10, Math.max(1, Math.log10(v))), diff --git a/dkan/libraries/chroma/docs/src/index.md b/dkan/libraries/chroma/docs/src/index.md index 964167226..637005766 100644 --- a/dkan/libraries/chroma/docs/src/index.md +++ b/dkan/libraries/chroma/docs/src/index.md @@ -34,23 +34,23 @@ chroma.js has a lot more to offer, but that's the gist of it. ### chroma #### (*color*) -The first step is to get your color into chroma.js. That's what the generic constructor ``chroma()`` does. The function is trying to guess the color format for you. For instances, it will recognized any named color from the W3CX11 specification: +The first step is to get your color into chroma.js. That's what the generic constructor ``chroma()`` does. The function is trying to guess the color format for you. For instances, it will recognized any named color from the W3CX11 specification: ```js -chroma('hotpink') +chroma('hotpink') ``` If there's no matching named color chroma.js checks for a **hexadecimal string**. It ignores case, the `#` sign is optional, and the shorter three letter format is recognized as well. So any of these are valid hexadecimal representations: `#ff3399`, `FF3399`, `#f39`, etc. ```js -chroma('#ff3399'); +chroma('#ff3399'); chroma('F39'); ``` In addition to hex strings, **hexadecimal numbers** (in fact, just any number between `0` and `16777215`), will be recognized, too. ```js -chroma(0xff3399) +chroma(0xff3399) ``` If you pass the RGB channels individually, too. Each parameter must be within `0..255`. You can pass the numbers as individual arguments or as array. @@ -126,7 +126,7 @@ chroma(0.6, 0, 0.8, 'gl'); ### chroma.temperature #### (K) -Returns a color from the [color temperature](http://www.zombieprototypes.com/?p=210) scale. Based on [Neil Bartlett's implementation](https://github.com/neilbartlett/color-temperature). +Returns a color from the [color temperature](http://www.zombieprototypes.com/?p=210) scale. Based on [Neil Bartlett's implementation](https://github.com/neilbartlett/color-temperature). ```js chroma.temperature(2000); // candle light @@ -218,7 +218,7 @@ chroma.contrast('pink', 'purple'); ### chroma.distance #### (color1, color2, mode='lab') -Computes the [eucledian distance](https://en.wikipedia.org/wiki/Euclidean_distance#Three_dimensions) between two colors in a given color space (default is `Lab`). +Computes the [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance#Three_dimensions) between two colors in a given color space (default is `Lab`). ```js chroma.distance('#fff', '#ff0', 'rgb'); @@ -230,7 +230,7 @@ chroma.distance('#fff', '#f0f'); ### chroma.deltaE #### (reference, sample, L=1, C=1) -Computes [color difference](https://en.wikipedia.org/wiki/Color_difference#CMC_l:c_.281984.29) as developed by the Colour Measurement Committee of the Society of Dyers and Colourists (CMC) in 1984. The implementation is adapted from [Bruce Lindbloom](https://web.archive.org/web/20160306044036/http://www.brucelindbloom.com/javascript/ColorDiff.js). The parameters L and C are weighting factors for lightness and chromacity. +Computes [color difference](https://en.wikipedia.org/wiki/Color_difference#CMC_l:c_.281984.29) as developed by the Colour Measurement Committee of the Society of Dyers and Colourists (CMC) in 1984. The implementation is adapted from [Bruce Lindbloom](https://web.archive.org/web/20160306044036/http://www.brucelindbloom.com/javascript/ColorDiff.js). The parameters L and C are weighting factors for lightness and chromaticity. ```js chroma.deltaE('#ededee', '#edeeed'); @@ -252,7 +252,7 @@ chroma.brewer.OrRd ### chroma.limits #### (data, mode, n) -A helper function that computes class breaks for you, based on data. It supports the modes _equidistant_ (e), _quantile_ (q), _logarithmic_ (l), and _k-means_ (k). Let's take a few numbers as sample data. +A helper function that computes class breaks for you, based on data. It supports the modes _equidistant_ (e), _quantile_ (q), _logarithmic_ (l), and _k-means_ (k). Let's take a few numbers as sample data. ```js var data = [2.0,3.5,3.6,3.8,3.8,4.1,4.3,4.4, @@ -266,13 +266,13 @@ var data = [2.0,3.5,3.6,3.8,3.8,4.1,4.3,4.4, chroma.limits(data, 'e', 4); ``` -In the **quantile** mode, the input domain is divided by quantile ranges. +In the **quantile** mode, the input domain is divided by quantile ranges. ```js chroma.limits(data, 'q', 4); ``` -**logarithmic** breaks are equidistant breaks but on a logarithmic scale. +**logarithmic** breaks are equidistant breaks but on a logarithmic scale. ```js chroma.limits(data, 'l', 4); @@ -299,7 +299,7 @@ chroma('rgba(255,0,0,0.35)').alpha(); ### color.darken #### (value=1) -Once loaded, chroma.js can change colors. One way we already saw above, you can change the lightness. +Once loaded, chroma.js can change colors. One way we already saw above, you can change the lightness. ```js chroma('hotpink').darken(); @@ -321,12 +321,12 @@ chroma('hotpink').brighten(3); ### color.saturate #### (value=1) -Changes the saturation of a color by manipulating the Lch chromacity. +Changes the saturation of a color by manipulating the Lch chromaticity. ```js -chroma('slategray').saturate(); -chroma('slategray').saturate(2); -chroma('slategray').saturate(3); +chroma('slategray').saturate(); +chroma('slategray').saturate(2); +chroma('slategray').saturate(3); ``` ### color.desaturate @@ -349,7 +349,7 @@ Changes a single channel and returns the result a new `chroma` object. ```js // change hue to 0 deg (=red) chroma('skyblue').set('hsl.h', 0); -// set chromacity to 30 +// set chromaticity to 30 chroma('hotpink').set('lch.c', 30); ``` @@ -373,7 +373,7 @@ chroma('orangered').get('hsl.l'); chroma('orangered').get('rgb.g'); ``` -### color.luminance +### color.luminance #### ([lum, mode='rgb']) If called without arguments color.luminance returns the relative brightness, according to the [WCAG definition](http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef). Normalized to `0` for darkest black and `1` for lightest white. @@ -679,7 +679,7 @@ chroma.scale('OrRd').classes(5); chroma.scale('OrRd').classes(8); ``` -You can also define custom class breaks by passing them as array: +You can also define custom class breaks by passing them as array: ```js chroma.scale('OrRd').classes([0,0.3,0.55,0.85,1]); diff --git a/dkan/libraries/chroma/readme.md b/dkan/libraries/chroma/readme.md index e72a15ef4..5bea96e3a 100644 --- a/dkan/libraries/chroma/readme.md +++ b/dkan/libraries/chroma/readme.md @@ -40,7 +40,7 @@ chroma.scale(['lightyellow', 'navy']).domain([1, 100000], 7, 'log'); ### Like it? -Why not dive into the [interactive documentation](http://gka.github.io/chroma.js/) (there's a [static version](https://github.com/gka/chroma.js/blob/v1.3.1/docs/src/index.md), too). You can download [chroma.min.js](https://raw.github.com/gka/chroma.js/master/chroma.min.js) or use the [hosted version on cdnjs.com](https://cdnjs.com/libraries/chroma-js). +Why not dive into the [interactive documentation](http://gka.github.io/chroma.js/) (there's a [static version](https://github.com/gka/chroma.js/blob/master/docs/src/index.md), too). You can download [chroma.min.js](https://raw.github.com/gka/chroma.js/master/chroma.min.js) or use the [hosted version on cdnjs.com](https://cdnjs.com/libraries/chroma-js). You can use it in node.js, too! @@ -50,7 +50,7 @@ Or you can use it in SASS using [chromatic-sass](https://github.com/bugsnag/chro ### Build instructions -To compile the coffee-script source files you have to run (might have to ``npm install` first) +To compile the coffee-script source files you have to run (might have to `npm install` first) grunt diff --git a/dkan/libraries/chroma/src/io/distance.coffee b/dkan/libraries/chroma/src/io/distance.coffee index 6d7ae9fa3..5b69b170f 100644 --- a/dkan/libraries/chroma/src/io/distance.coffee +++ b/dkan/libraries/chroma/src/io/distance.coffee @@ -1,4 +1,4 @@ -# simple eucledian distance +# simple Euclidean distance chroma.distance = (a, b, mode='lab') -> # Delta E (CIE 1976) # see http://www.brucelindbloom.com/index.html?Equations.html diff --git a/dkan/libraries/reclineViewNvd3/dist/recline.view.nvd3.controls.min.js b/dkan/libraries/reclineViewNvd3/dist/recline.view.nvd3.controls.min.js index 0a038fbf2..4190ad2d1 100644 --- a/dkan/libraries/reclineViewNvd3/dist/recline.view.nvd3.controls.min.js +++ b/dkan/libraries/reclineViewNvd3/dist/recline.view.nvd3.controls.min.js @@ -1,2 +1,2 @@ /*! recline.view.nvd3 v0.3.0 */ -this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";var c=100;b.BaseControl=Backbone.View.extend({templateTop:'
',templateXFormat:'
X Axis
{{errors.xTicks}}
',templateYFormat:'
Y Axis
{{errors.yTicks}}
',templateY1Format:'
Y-1 Axis
{{errors.y1Ticks}}
',templateY2Format:'
Y-2 Axis
{{errors.y2Ticks}}
',templateGoal:'
',templateGeneral:'
General
',composeTemplate:function(){var a="";return a+=this.templateTop,a+=this.templateGeneral,a+=this.templateXFormat,a+=this.templateYFormat,a+=this.customOptions?this.customOptions:""},initialize:function(a){_.extend(this,a)},events:{'change input[type="checkbox"]':"update","change select":"update",'blur input[type="text"]':"update",'keydown input[type="text"]':"update",'keydown input[type="number"]':"update",'change input[type="number"]':"update","submit #control-chart":"update"},render:function(){var c,d,e=this,f=_.arrayToOptions(_.getFields(e.state.get("model")));f.unshift({name:"default",label:"Default",selected:!1}),e.state.set("sortFields",_.applyOption(f,[e.state.get("sort")]));var g=e.state.get("options")||{};g.margin=g.margin||{top:30,right:20,bottom:50,left:60},e.state.set("options",g,{silent:!0}),a("#base-controls").html(Mustache.render(e.composeTemplate(),e.state.toJSON())),a("#goal-controls").html(Mustache.render(e.templateGoal,e.state.toJSON())),e.$(".chosen-select").chosen({width:"95%"}),e.state.get("xFormat")&&e.state.get("xFormat").format&&(c=e.state.get("xFormat"),e.$('#control-chart-x-format option[value="'+c.format+'"][data-type="'+c.type+'"]').attr("selected","selected")),e.state.get("yFormat")&&e.state.get("yFormat").format&&(d=e.state.get("yFormat"),e.$('#control-chart-y-format option[value="'+d.format+'"][data-type="'+d.type+'"]').attr("selected","selected")),a("#control-chart-color").on("blur",function(a){e.update(a)}),a("#control-chart-color-picker").spectrum({change:function(b){a("#control-chart-color").val(function(a,c){return c?c+", "+b.toHexString():b.toHexString()}),a("input#control-chart-color").trigger("blur")}}),e.renderQueryEditor&&(this.queryEditor=new b.QueryEditor({el:".recline-nvd3-query-editor",model:this.model.queryState,state:this.state}),this.queryEditor.render()),e.renderFilterEditor&&(this.filterEditor=new b.FilterEditor({el:".recline-nvd3-filter-editor",model:this.model,state:this.state})),a('[data-toggle="popover"]').popover({placement:"auto right"})},update:function(a){var b=this,c={};if(a){if(b.$(a.target).closest(".chosen-container").length)return;if("keydown"===a.type&&13!==a.keyCode)return}if(b.validate()){var d=b.state.toJSON(),e=b.getUIState();c=_.merge({},d,e),c.options.color=e.options.color,b.state.set(c)}b.render()},getUIState:function(){var a,b=this,c=parseInt(b.$("#control-chart-label-x-rotation").val()),d={group:b.$("#control-chart-group").is(":checked"),chartHeight:b.$("#control-chart-height").val(),xFormat:{type:b.$("#control-chart-x-format option:selected").data("type"),format:b.$("#control-chart-x-format option:selected").val()},yFormat:{type:b.$("#control-chart-y-format option:selected").data("type"),format:b.$("#control-chart-y-format option:selected").val()},y1Format:{type:b.$("#control-chart-y1-format option:selected").data("type"),format:b.$("#control-chart-y1-format option:selected").val()},y2Format:{type:b.$("#control-chart-y2-format option:selected").data("type"),format:b.$("#control-chart-y2-format option:selected").val()},sort:b.$("#control-chart-sort").val(),showTitle:b.$("#control-chart-show-title").is(":checked"),xValues:[b.$("#control-chart-x-values-from").val(),b.$("#control-chart-x-values-to").val()],xValuesFrom:b.$("#control-chart-x-values-from").val(),xValuesTo:b.$("#control-chart-x-values-to").val(),xValuesStep:parseInt(b.$("#control-chart-x-values-step").val()||1),yValues:[b.$("#control-chart-y-values-from").val(),b.$("#control-chart-y-values-to").val()],yValuesFrom:b.$("#control-chart-y-values-from").val(),yValuesTo:b.$("#control-chart-y-values-to").val(),yValuesStep:parseInt(b.$("#control-chart-y-values-step").val()||1),y1Values:[b.$("#control-chart-y1-values-from").val(),b.$("#control-chart-y1-values-to").val()],y1ValuesFrom:b.$("#control-chart-y1-values-from").val(),y1ValuesTo:b.$("#control-chart-y1-values-to").val(),y1ValuesStep:parseInt(b.$("#control-chart-y1-values-step").val()||1),y2Values:[b.$("#control-chart-y2-values-from").val(),b.$("#control-chart-y2-values-to").val()],y2ValuesFrom:b.$("#control-chart-y2-values-from").val(),y2ValuesTo:b.$("#control-chart-y2-values-to").val(),y2ValuesStep:parseInt(b.$("#control-chart-y2-values-step").val()||1),lpbBarChartField:b.$("#control-lpb-barchart-field").val()};d.options=d.options||{},d.options.xAxis=d.options.xAxis||{},d.options.yAxis=d.options.yAxis||{},d.options.y1Axis=d.options.y1Axis||{},d.options.y2Axis=d.options.y2Axis||{},d.options.tooltips=b.$("#control-chart-show-tooltips").is(":checked"),d.options.showControls=b.$("#control-chart-show-controls").is(":checked"),d.options.showLegend=b.$("#control-chart-show-legend").is(":checked"),d.options.reduceXTicks=b.$("#control-chart-reduce-ticks").is(":checked"),d.options.xAxis.rotateLabels=isNaN(c)?0:c,a=_.invoke(b.$("#control-chart-color").val().split(","),"trim"),d.options.xAxis.axisLabel=b.$("#control-chart-x-axis-label").val(),d.options.xAxis.axisLabelDistance=parseInt(b.$("#control-chart-x-axis-label-distance").val())||0,d.options.yAxis.axisLabel=b.$("#control-chart-y-axis-label").val(),d.options.yAxis.axisLabelDistance=parseInt(b.$("#control-chart-y-axis-label-distance").val())||0,d.options.y1Axis.axisLabel=b.$("#control-chart-y1-axis-label").val(),d.options.y1Axis.axisLabelDistance=parseInt(b.$("#control-chart-y1-axis-label-distance").val())||0,d.options.y2Axis.axisLabel=b.$("#control-chart-y2-axis-label").val(),d.options.y2Axis.axisLabelDistance=parseInt(b.$("#control-chart-y2-axis-label-distance").val())||0,b.$("#control-chart-color").val()?d.options.color=a:delete d.options.color;var e={top:parseInt(b.$("#control-chart-margin-top").val()),right:parseInt(b.$("#control-chart-margin-right").val()),bottom:parseInt(b.$("#control-chart-margin-bottom").val()),left:parseInt(b.$("#control-chart-margin-left").val())},f={value:parseFloat(b.$("#control-chart-goal-value").val())||"",color:b.$("#control-chart-goal-color").val(),outside:b.$("#control-chart-goal-outside").is(":checked"),label:b.$("#control-chart-goal-label").is(":checked")};return _.each(_.keys(e),function(a){e[a]=isNaN(e[a])?0:e[a]}),d.goal=f,d.options.margin=e,d},validate:function(){var a=this,b=a.state.toJSON(),d=a.getUIState(),e="The number of ticks should be lower than "+c,f=!0;return a.processTicks(d.xValuesFrom,d.xValuesTo,d.xValuesStep)||(b.errors.xTicks=e,f=!1),a.processTicks(d.yValuesFrom,d.yValuesTo,d.yValuesStep)||(b.errors.yTicks=e,f=!1),a.processTicks(d.y1ValuesFrom,d.y1ValuesTo,d.y1ValuesStep)||(b.errors.y1Ticks=e,f=!1),a.processTicks(d.y2ValuesFrom,d.y2ValuesTo,d.y2ValuesStep)||(b.errors.y2Ticks=e,f=!1),f&&(b.errors={}),a.state.set(b),f},processTicks:function(a,b,d){if(a&&b){if((b-a)/d>c)return!1}return!0}}),b.QueryEditor=Backbone.View.extend({template:'
',events:{"click button":"onFormSubmit","change input":"onFormSubmit"},initialize:function(){_.bindAll(this,"render"),this.listenTo(this.model,"change",this.render),this.render()},onFormSubmit:function(a){a.preventDefault();var b=this.$el.find(".search-query").val();this.model.set({q:b})},render:function(){var a=this.model.toJSON(),b=Mustache.render(this.template,a);this.$el.html(b)}}),b.FilterEditor=Backbone.View.extend({template:'
{{#filters}} {{{filterRender}}} {{/filters}} {{#filters.length}} {{/filters.length}}
',filterTemplates:{term:'
',range:'
',geo_distance:'
{{field}} {{type}} ×
'},events:{"click .js-remove-filter":"onRemoveFilter","click .js-add-filter":"onAddFilterShow","click .js-edit button":"onTermFiltersUpdate","click #add-filter-btn":"onAddFilter"},initialize:function(a){_.bindAll(this,"render"),this.listenTo(this.model.fields,"all",this.render),this.listenTo(this.model.queryState,"change change:filters:new-blank",this.render),_.extend(this,a),this.render()},render:function(){var b=this,c=a.extend(!0,{},this.model.queryState.toJSON());c.filters=_.map(c.filters,function(a,b){return a.id=b,a}),c.fields=this.model.fields.toJSON(),c.filterRender=function(){return Mustache.render(b.filterTemplates[this.type],this)};var d=Mustache.render(this.template,c);this.$el.html(d)},onAddFilterShow:function(b){b.preventDefault(),a(b.target).hide(),this.$el.find(".js-add").show()},onAddFilter:function(b){b.preventDefault();var c=a(b.target).closest(".form-stacked");c.hide();var d=c.find("select.filterType").val(),e=c.find("select.fields").val();this.model.queryState.addFilter({type:d,field:e})},onRemoveFilter:function(b){b.preventDefault();var c=a(b.target),d=c.attr("data-filter-id");this.model.queryState.removeFilter(d)},onTermFiltersUpdate:function(b){var c=this;b.preventDefault();var d=c.model.queryState.get("filters"),e=a(b.target).closest(".form-stacked");_.each(e.find("input"),function(b){var c=a(b),e=c.attr("data-filter-type"),f=parseInt(c.attr("data-filter-id"),10),g=c.attr("name"),h=c.val();switch(e){case"term":d[f].term=h;break;case"range":d[f][g]=h;break;case"geo_distance":"distance"===g?d[f].distance=parseFloat(h):d[f].point[g]=parseFloat(h)}}),c.model.queryState.set({filters:d,from:0}),c.model.queryState.trigger("change")}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.cumulativeLineChartControls=recline.View.nvd3.BaseControl.extend({customOptions:"",events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events)}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.discreteBarChartControls=recline.View.nvd3.BaseControl.extend({customOptions:'
Extra
',events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{'change input[type="checkbox"]':"update"})},getUIState:function(){var a=this,b=recline.View.nvd3.BaseControl.prototype.getUIState.call(this);return b=_.merge({},b,{options:{}}),b.options.showValues=a.$("#control-chart-show-values").is(":checked"),b.options.staggerLabels=a.$("#control-chart-stagger-labels").is(":checked"),b}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.lineChartControls=recline.View.nvd3.BaseControl.extend({customOptions:'
Extra
',events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{'change input[type="checkbox"]':"update"})},getUIState:function(){var a=this,b=recline.View.nvd3.BaseControl.prototype.getUIState.call(this);return b=_.merge({},b,{options:{}}),b.options.datapoints=a.$("#control-chart-datapoints").is(":checked"),b}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.linePlusBarChartControls=recline.View.nvd3.BaseControl.extend({customOptions:"",linePlusBarXSelect:function(){var a='
Bar Chart Series

Select which series should be represented as a bar chart

"},composeTemplate:function(){var a="";return a+=this.templateTop,a+=this.templateGeneral,a+=this.templateXFormat,a+=this.templateY1Format,a+=this.templateY2Format,a+=this.linePlusBarXSelect(),a+=this.customOptions?this.customOptions:""},events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{'change input[type="checkbox"]':"update"})},getUIState:function(){var a=this,b=recline.View.nvd3.BaseControl.prototype.getUIState.call(this);return b=_.merge({},b,{options:{}}),b.options.showValues=a.$("#control-chart-show-values").is(":checked"),b.options.staggerLabels=a.$("#control-chart-stagger-labels").is(":checked"),b}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.lineWithFocusChartControls=recline.View.nvd3.BaseControl.extend({customOptions:"",events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{})}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.multiBarChartControls=recline.View.nvd3.BaseControl.extend({customOptions:'
Extra
',events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{'change input[type="checkbox"]':"update"})},getUIState:function(){var a=this,b=recline.View.nvd3.BaseControl.prototype.getUIState.call(this);return b=_.merge({},b,{options:{}}),b.options.staggerLabels=a.$("#control-chart-stagger-labels").is(":checked"),b.options.stacked=a.$("#control-chart-stacked").is(":checked"),b}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.multiBarHorizontalChartControls=recline.View.nvd3.BaseControl.extend({templateGoal:'
',customOptions:"",events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{})}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.pieChartControls=recline.View.nvd3.BaseControl.extend({customOptions:'
Extra
',events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{'change input[type="checkbox"]':"update"})},getUIState:function(){var a=this,b=recline.View.nvd3.BaseControl.prototype.getUIState.call(this);return b=_.merge({},b,{options:{}}),b.options.donut=a.$("#control-chart-donut").is(":checked"),b}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.scatterChartControls=recline.View.nvd3.BaseControl.extend({customOptions:"",events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events)}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.stackedAreaChartControls=recline.View.nvd3.BaseControl.extend({customOptions:"",events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events)}})}(jQuery,recline.View.nvd3); \ No newline at end of file +this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";var c=100;b.BaseControl=Backbone.View.extend({templateTop:'
',templateXFormat:'
X Axis
{{errors.xTicks}}
',templateYFormat:'
Y Axis
{{errors.yTicks}}
',templateY1Format:'
Y-1 Axis
{{errors.y1Ticks}}
',templateY2Format:'
Y-2 Axis
{{errors.y2Ticks}}
',templateGoal:'
',templateGeneral:'
General
',composeTemplate:function(){var a="";return a+=this.templateTop,a+=this.templateGeneral,a+=this.templateXFormat,a+=this.templateYFormat,a+=this.customOptions?this.customOptions:""},initialize:function(a){_.extend(this,a)},events:{'change input[type="checkbox"]':"update","change select":"update",'blur input[type="text"]':"update",'keydown input[type="text"]':"update",'keydown input[type="number"]':"update",'change input[type="number"]':"update","submit #control-chart":"update"},render:function(){var c,d,e=this,f=_.arrayToOptions(_.getFields(e.state.get("model")));f.unshift({name:"default",label:"Default",selected:!1}),e.state.set("sortFields",_.applyOption(f,[e.state.get("sort")]));var g=e.state.get("options")||{};g.margin=g.margin||{top:0,right:20,bottom:50,left:60},e.state.set("options",g,{silent:!0}),a("#base-controls").html(Mustache.render(e.composeTemplate(),e.state.toJSON())),a("#goal-controls").html(Mustache.render(e.templateGoal,e.state.toJSON())),e.$(".chosen-select").chosen({width:"95%"}),e.state.get("xFormat")&&e.state.get("xFormat").format&&(c=e.state.get("xFormat"),e.$('#control-chart-x-format option[value="'+c.format+'"][data-type="'+c.type+'"]').attr("selected","selected")),e.state.get("yFormat")&&e.state.get("yFormat").format&&(d=e.state.get("yFormat"),e.$('#control-chart-y-format option[value="'+d.format+'"][data-type="'+d.type+'"]').attr("selected","selected")),a("#control-chart-color").on("blur",function(a){e.update(a)}),a("#control-chart-color-picker").spectrum({change:function(b){a("#control-chart-color").val(function(a,c){return c?c+", "+b.toHexString():b.toHexString()}),a("input#control-chart-color").trigger("blur")}}),e.renderQueryEditor&&(this.queryEditor=new b.QueryEditor({el:".recline-nvd3-query-editor",model:this.model.queryState,state:this.state}),this.queryEditor.render()),e.renderFilterEditor&&(this.filterEditor=new b.FilterEditor({el:".recline-nvd3-filter-editor",model:this.model,state:this.state})),a('[data-toggle="popover"]').popover({placement:"auto right"})},update:function(a){var b=this,c={};if(a){if(b.$(a.target).closest(".chosen-container").length)return;if("keydown"===a.type&&13!==a.keyCode)return}if(b.validate()){var d=b.state.toJSON(),e=b.getUIState();c=_.merge({},d,e),c.options.color=e.options.color,b.state.set(c)}b.render()},getUIState:function(){var a,b=this,c=parseInt(b.$("#control-chart-label-x-rotation").val()),d={group:b.$("#control-chart-group").is(":checked"),chartHeight:b.$("#control-chart-height").val(),xFormat:{type:b.$("#control-chart-x-format option:selected").data("type"),format:b.$("#control-chart-x-format option:selected").val()},yFormat:{type:b.$("#control-chart-y-format option:selected").data("type"),format:b.$("#control-chart-y-format option:selected").val()},y1Format:{type:b.$("#control-chart-y1-format option:selected").data("type"),format:b.$("#control-chart-y1-format option:selected").val()},y2Format:{type:b.$("#control-chart-y2-format option:selected").data("type"),format:b.$("#control-chart-y2-format option:selected").val()},sort:b.$("#control-chart-sort").val(),showTitle:b.$("#control-chart-show-title").is(":checked"),xValues:[b.$("#control-chart-x-values-from").val(),b.$("#control-chart-x-values-to").val()],xValuesFrom:b.$("#control-chart-x-values-from").val(),xValuesTo:b.$("#control-chart-x-values-to").val(),xValuesStep:parseInt(b.$("#control-chart-x-values-step").val()||1),yValues:[b.$("#control-chart-y-values-from").val(),b.$("#control-chart-y-values-to").val()],yValuesFrom:b.$("#control-chart-y-values-from").val(),yValuesTo:b.$("#control-chart-y-values-to").val(),yValuesStep:parseInt(b.$("#control-chart-y-values-step").val()||1),y1Values:[b.$("#control-chart-y1-values-from").val(),b.$("#control-chart-y1-values-to").val()],y1ValuesFrom:b.$("#control-chart-y1-values-from").val(),y1ValuesTo:b.$("#control-chart-y1-values-to").val(),y1ValuesStep:parseInt(b.$("#control-chart-y1-values-step").val()||1),y2Values:[b.$("#control-chart-y2-values-from").val(),b.$("#control-chart-y2-values-to").val()],y2ValuesFrom:b.$("#control-chart-y2-values-from").val(),y2ValuesTo:b.$("#control-chart-y2-values-to").val(),y2ValuesStep:parseInt(b.$("#control-chart-y2-values-step").val()||1),lpbBarChartField:b.$("#control-lpb-barchart-field").val()};d.options=d.options||{},d.options.xAxis=d.options.xAxis||{},d.options.yAxis=d.options.yAxis||{},d.options.y1Axis=d.options.y1Axis||{},d.options.y2Axis=d.options.y2Axis||{},d.options.tooltips=b.$("#control-chart-show-tooltips").is(":checked"),d.options.showControls=b.$("#control-chart-show-controls").is(":checked"),d.options.showLegend=b.$("#control-chart-show-legend").is(":checked"),d.options.reduceXTicks=b.$("#control-chart-reduce-ticks").is(":checked"),d.options.xAxis.rotateLabels=isNaN(c)?0:c,a=_.invoke(b.$("#control-chart-color").val().split(","),"trim"),d.options.xAxis.axisLabel=b.$("#control-chart-x-axis-label").val(),d.options.xAxis.axisLabelDistance=parseInt(b.$("#control-chart-x-axis-label-distance").val())||0,d.options.yAxis.axisLabel=b.$("#control-chart-y-axis-label").val(),d.options.yAxis.axisLabelDistance=parseInt(b.$("#control-chart-y-axis-label-distance").val())||0,d.options.y1Axis.axisLabel=b.$("#control-chart-y1-axis-label").val(),d.options.y1Axis.axisLabelDistance=parseInt(b.$("#control-chart-y1-axis-label-distance").val())||0,d.options.y2Axis.axisLabel=b.$("#control-chart-y2-axis-label").val(),d.options.y2Axis.axisLabelDistance=parseInt(b.$("#control-chart-y2-axis-label-distance").val())||0,b.$("#control-chart-color").val()?d.options.color=a:delete d.options.color;var e={top:parseInt(b.$("#control-chart-margin-top").val()),right:parseInt(b.$("#control-chart-margin-right").val()),bottom:parseInt(b.$("#control-chart-margin-bottom").val()),left:parseInt(b.$("#control-chart-margin-left").val())},f={value:parseFloat(b.$("#control-chart-goal-value").val())||"",color:b.$("#control-chart-goal-color").val(),outside:b.$("#control-chart-goal-outside").is(":checked"),label:b.$("#control-chart-goal-label").is(":checked")};return _.each(_.keys(e),function(a){e[a]=isNaN(e[a])?0:e[a]}),d.goal=f,d.options.margin=e,d},validate:function(){var a=this,b=a.state.toJSON(),d=a.getUIState(),e="The number of ticks should be lower than "+c,f=!0;return a.processTicks(d.xValuesFrom,d.xValuesTo,d.xValuesStep)||(b.errors.xTicks=e,f=!1),a.processTicks(d.yValuesFrom,d.yValuesTo,d.yValuesStep)||(b.errors.yTicks=e,f=!1),a.processTicks(d.y1ValuesFrom,d.y1ValuesTo,d.y1ValuesStep)||(b.errors.y1Ticks=e,f=!1),a.processTicks(d.y2ValuesFrom,d.y2ValuesTo,d.y2ValuesStep)||(b.errors.y2Ticks=e,f=!1),f&&(b.errors={}),a.state.set(b),f},processTicks:function(a,b,d){if(a&&b){if((b-a)/d>c)return!1}return!0}}),b.QueryEditor=Backbone.View.extend({template:'
',events:{"click button":"onFormSubmit","change input":"onFormSubmit"},initialize:function(){_.bindAll(this,"render"),this.listenTo(this.model,"change",this.render),this.render()},onFormSubmit:function(a){a.preventDefault();var b=this.$el.find(".search-query").val();this.model.set({q:b})},render:function(){var a=this.model.toJSON(),b=Mustache.render(this.template,a);this.$el.html(b)}}),b.FilterEditor=Backbone.View.extend({template:'
{{#filters}} {{{filterRender}}} {{/filters}} {{#filters.length}} {{/filters.length}}
',filterTemplates:{term:'
',range:'
',geo_distance:'
{{field}} {{type}} ×
'},events:{"click .js-remove-filter":"onRemoveFilter","click .js-add-filter":"onAddFilterShow","click .js-edit button":"onTermFiltersUpdate","click #add-filter-btn":"onAddFilter"},initialize:function(a){_.bindAll(this,"render"),this.listenTo(this.model.fields,"all",this.render),this.listenTo(this.model.queryState,"change change:filters:new-blank",this.render),_.extend(this,a),this.render()},render:function(){var b=this,c=a.extend(!0,{},this.model.queryState.toJSON());c.filters=_.map(c.filters,function(a,b){return a.id=b,a}),c.fields=this.model.fields.toJSON(),c.filterRender=function(){return Mustache.render(b.filterTemplates[this.type],this)};var d=Mustache.render(this.template,c);this.$el.html(d)},onAddFilterShow:function(b){b.preventDefault(),a(b.target).hide(),this.$el.find(".js-add").show()},onAddFilter:function(b){b.preventDefault();var c=a(b.target).closest(".form-stacked");c.hide();var d=c.find("select.filterType").val(),e=c.find("select.fields").val();this.model.queryState.addFilter({type:d,field:e})},onRemoveFilter:function(b){b.preventDefault();var c=a(b.target),d=c.attr("data-filter-id");this.model.queryState.removeFilter(d)},onTermFiltersUpdate:function(b){var c=this;b.preventDefault();var d=c.model.queryState.get("filters"),e=a(b.target).closest(".form-stacked");_.each(e.find("input"),function(b){var c=a(b),e=c.attr("data-filter-type"),f=parseInt(c.attr("data-filter-id"),10),g=c.attr("name"),h=c.val();switch(e){case"term":d[f].term=h;break;case"range":d[f][g]=h;break;case"geo_distance":"distance"===g?d[f].distance=parseFloat(h):d[f].point[g]=parseFloat(h)}}),c.model.queryState.set({filters:d,from:0}),c.model.queryState.trigger("change")}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.cumulativeLineChartControls=recline.View.nvd3.BaseControl.extend({customOptions:"",events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events)}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.discreteBarChartControls=recline.View.nvd3.BaseControl.extend({customOptions:'
Extra
',events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{'change input[type="checkbox"]':"update"})},getUIState:function(){var a=this,b=recline.View.nvd3.BaseControl.prototype.getUIState.call(this);return b=_.merge({},b,{options:{}}),b.options.showValues=a.$("#control-chart-show-values").is(":checked"),b.options.staggerLabels=a.$("#control-chart-stagger-labels").is(":checked"),b}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.lineChartControls=recline.View.nvd3.BaseControl.extend({customOptions:'
Extra
',events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{'change input[type="checkbox"]':"update"})},getUIState:function(){var a=this,b=recline.View.nvd3.BaseControl.prototype.getUIState.call(this);return b=_.merge({},b,{options:{}}),b.options.datapoints=a.$("#control-chart-datapoints").is(":checked"),b}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.linePlusBarChartControls=recline.View.nvd3.BaseControl.extend({customOptions:"",linePlusBarXSelect:function(){var a='
Bar Chart Series

Select which series should be represented as a bar chart

"},composeTemplate:function(){var a="";return a+=this.templateTop,a+=this.templateGeneral,a+=this.templateXFormat,a+=this.templateY1Format,a+=this.templateY2Format,a+=this.linePlusBarXSelect(),a+=this.customOptions?this.customOptions:""},events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{'change input[type="checkbox"]':"update"})},getUIState:function(){var a=this,b=recline.View.nvd3.BaseControl.prototype.getUIState.call(this);return b=_.merge({},b,{options:{}}),b.options.showValues=a.$("#control-chart-show-values").is(":checked"),b.options.staggerLabels=a.$("#control-chart-stagger-labels").is(":checked"),b}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.lineWithFocusChartControls=recline.View.nvd3.BaseControl.extend({customOptions:"",events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{})}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.multiBarChartControls=recline.View.nvd3.BaseControl.extend({customOptions:'
Extra
',events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{'change input[type="checkbox"]':"update"})},getUIState:function(){var a=this,b=recline.View.nvd3.BaseControl.prototype.getUIState.call(this);return b=_.merge({},b,{options:{}}),b.options.staggerLabels=a.$("#control-chart-stagger-labels").is(":checked"),b.options.stacked=a.$("#control-chart-stacked").is(":checked"),b}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.multiBarHorizontalChartControls=recline.View.nvd3.BaseControl.extend({templateGoal:'
',customOptions:"",events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{})}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.pieChartControls=recline.View.nvd3.BaseControl.extend({customOptions:'
Extra
',events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events,{'change input[type="checkbox"]':"update"})},getUIState:function(){var a=this,b=recline.View.nvd3.BaseControl.prototype.getUIState.call(this);return b=_.merge({},b,{options:{}}),b.options.donut=a.$("#control-chart-donut").is(":checked"),b}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.scatterChartControls=recline.View.nvd3.BaseControl.extend({customOptions:"",events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events)}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.stackedAreaChartControls=recline.View.nvd3.BaseControl.extend({customOptions:"",events:function(){return _.extend({},recline.View.nvd3.BaseControl.prototype.events)}})}(jQuery,recline.View.nvd3); \ No newline at end of file diff --git a/dkan/libraries/reclineViewNvd3/dist/recline.view.nvd3.min.js b/dkan/libraries/reclineViewNvd3/dist/recline.view.nvd3.min.js index 631a4efb8..b9a15e292 100644 --- a/dkan/libraries/reclineViewNvd3/dist/recline.view.nvd3.min.js +++ b/dkan/libraries/reclineViewNvd3/dist/recline.view.nvd3.min.js @@ -1,2 +1,2 @@ /*! recline.view.nvd3 v0.3.0 */ -this.recline=this.recline||{},this.recline.View=this.recline.View||{},this.recline.View.nvd3=this.recline.View.nvd3||{};var globalchart,chartAxes=["x","y","y1","y2"];!function(a,b){"use strict";function c(a){return(a=a||"")+(1e16*Math.random()).toFixed(0)}b.Base=Backbone.View.extend({template:'
{{data}}
',CLEANUP_CHARS:"%$¥€",initialize:function(b){var d=this;d.$el=a(d.el),d.options=_.defaults(b||{},d.options);var e=_.merge({width:640,height:480,group:!1},d.getDefaults(),d.options.state.toJSON());d.graphType=d.graphType||"multiBarChart",d.uuid=c("nvd3chart_"),d.state=d.options.state,d.model=d.options.model,d.state.set(e),d.chartMap=d3.map(),d.listenTo(d.model.records,"add remove reset change",d.lightUpdate.bind(d)),globalchart=d},getLayoutParams:function(){var a=this;return{columnClass:"col-md-12",width:a.state.get("width")||a.$el.innerWidth()||640,height:a.state.get("height")||480}},render:function(){var a,b,c,d=this;d.listenToOnce(d.state,"change",d.render.bind(d)),c=d.getLayoutParams(),a=d.model.toTemplateJSON(),a.viewId=d.uuid,_.extend(a,c),b=Mustache.render(d.template,a),d.$el.html(b),d.$graph=d.$el.find(".panel."+a.viewId),d.trigger("chart:endDrawing");var e=d.needForceX(d.model.records,d.graphType);return d.state.set("computeXLabels",e,{silent:!0}),d.state.set("group",d.model.records.length>1e3||d.state.get("group",{silent:!0})),d.series=d.createSeries(d.model.records),nv.addGraph(function(){return d.chart=d.createGraph(d.graphType),d.alterChart&&d.alterChart(d.chart),chartAxes.forEach(function(a){if(d.chart[a+"Axis"]){var b=d.state.get(a+"Format")||{type:"String",format:""},c=d.getFormatter(b.type,b.format,a);d.calcTickValues(a,d.chart[a+"Axis"],d.state.get(a+"Values"),d.state.get(a+"ValuesStep")),d.chart[a+"Axis"].tickFormat(c)}}),d3.select("#"+d.uuid+" svg").datum(d.series).transition().duration(d.state.get("transitionTime")||500).call(d.chart),d.renderGoals(),"discreteBarChart"===d.graphType&&d.state.get("options")&&d.state.get("options").reduceXTicks&&d.reduceXTicks(),"function"==typeof d.chart.tooltips?d.chart.tooltips(d.state.get("options").tooltips):d.chart.tooltip.enabled(d.state.get("options").tooltips),nv.utils.windowResize(d.updateChart.bind(d)),d.chart}),d},calcTickValues:function(a,b,c,d){var e,f=this,g=["multiBarChart","discreteBarChart","linePlusBarChart"];d=d||1,this.isOldRangeType(c)&&(c=this.convertRange(c)),c&&f.rangesValid(c)&&(c[0]=parseInt(c[0]),c[1]=parseInt(c[1]),e=d3.range(c[0],c[1],d),"linePlusBarChart"===f.graphType&&"y1"===a?f.chart.bars.yDomain([c[0],c[1]],d):"linePlusBarChart"===f.graphType&&"y2"===a?f.chart.lines.yDomain([c[0],c[1]],d):_.inArray(g,f.graphType)&&"y"!==a?f.chart[a+"Domain"](d3.range(c[0],c[1],d)):f.chart[a+"Domain"]([c[0],c[1]])),b.tickValues(e)},isOldRangeType:function(a){return a&&-1!==a.indexOf("-")},convertRange:function(a){for(var b=a.replace(" ","").split("-"),c=0;c=parseInt(a[1])&&(b=!1),b},lightUpdate:function(){var a=this;a.chart&&(a.series=a.createSeries(a.model.records),a.setOptions(a.chart,a.state.get("options")),setTimeout(function(){d3.select("#"+a.uuid+" svg").datum(a.series).transition().duration(500).call(a.chart)},0))},canRenderGoal:function(a){return!d3.select("svg").empty()&&d3.select("svg .goal").empty()&&a&&a.value&&!isNaN(a.value)&&this.chart.yAxis},renderGoals:function(){var a=this,b=a.state.get("goal");nv.dispatch.on("render_end",null),this.canRenderGoal(b)&&nv.dispatch.on("render_end",function(){var c,d,e=a.chart.yAxis.scale(),f=a.chart.margin(),g=e(b.value)+f.top,h=f.left,i=d3.select("svg").size()?parseInt(d3.select("svg").style("width"))-10:0,j=d3.select("svg").append("g");b.label&&(b.outside?(c=h-50,d=g+3):(c=h+5,d=g-6),j.append("text").text("TARGET").attr("x",c).attr("y",d).attr("fill",b.color||"red").style("font-size","10px").style("font-weight","bold").style("font-style","italic")),j.append("line").attr("class","goal").attr("x1",h).attr("y1",g).attr("x2",i).attr("y2",g).attr("stroke-width",1).attr("stroke",b.color||"red").style("stroke-dasharray","3, 3")})},updateChart:function(){var a=this;d3.select("#"+a.uuid+" svg").transition().duration(a.state.get("transitionTime")||500).call(a.chart)},reduceXTicks:function(){var a=this,b=a.getLayoutParams(a.state.get("mode"));d3.select(".nv-x.nv-axis > g").selectAll("g").filter(function(c,d){return d%Math.ceil(a.model.records.length/(b.width/100))!=0}).selectAll("text, line").style("opacity",0)},createSeries:function(a){var b,c,d=this;return d.state.get("xfield")&&d.getSeries()?(a=a.toJSON(),b=_.compose(_.inferType,_.iteratee(d.state.get("xfield"))),c=d.state.get("xDataType")&&"Auto"!==d.state.get("xDataType")?d.state.get("xDataType"):b(_.last(a)||[]),_.map(d.getSeries(),function(b){var e={};e.key=b;var f=d.state.get("group")?_.reportBy(a,d.state.get("xfield"),d.state.get("seriesFields")):a;return f=_.sortBy(f,d.getSort(d.state.get("sort"))),f=_.reduce(f,function(a,c){var e=d.cleanupY(d.y(c,b));return e||0===e||"stackedAreaChart"===d.graphType?a.push(c):d.state.get("options").stacked&&(c[b]=0,a.push(c)),a},[]),e.values=_.map(f,function(a,e){var f=d.cleanupY(d.y(a,b));return f=d.state.get("yDataType")&&"Number"===d.state.get("yDataType")?numeral(f).value():_.cast(f,_.inferType(f)),d.state.get("computeXLabels")?(d.chartMap.set(e,d.x(a,d.state.get("xfield"))),{y:f,x:e,label:d.x(a,d.state.get("xfield"))}):{y:f,x:_.cast(d.x(a,d.state.get("xfield")),c)}}),e})):[]},cleanupY:function(a){var b=this;return"string"==typeof a?a.replace(new RegExp("["+b.CLEANUP_CHARS+"]"),""):a},getSort:function(a){return a&&"default"!==a?a:_.identity},needForceX:function(a,b){var c=this,d=c.state.get("xfield");return a=a.toJSON(),_.some(a,function(a){return"String"===_.inferType(a[d])})&&"discreteBarChart"!==b&&"multiBarChart"!==b},getFormatter:function(a,b,c){var d=this;return c=c||"x",d.state.get("computeXLabels")&&"x"===c?d.chartMap.get.bind(d.chartMap):{String:_.identity,Date:_.compose(d3.time.format(b||"%x"),_.instantiate(Date)),Number:d3.format(b||".02f"),Percentage:d3.format(b||".02f"),PercentageInt:function(a){return d3.format(b||".02f")(a)+"%"}}[a]},setOptions:function(a,b){var c=this;for(var d in b){var e=b[d];"margin"===d&&a.margin(e),a&&_.isObject(e)&&!_.isArray(e)?c.setOptions(a[d],e):a&&_.isFunction(a[d])&&a[d](e)}},createGraph:function(a){var b=this,c=nv.models[a]();return b.setOptions(c,b.state.get("options")),c},getDefaults:function(){return{}},getState:function(){return this.state.attributes},getSeries:function(){return this.state.get("seriesFields")},x:function(a,b){return a[b]},y:function(a,b){return a[b]},destroy:function(){this.stopListening()},alterChart:function(){}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.cumulativeLineChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="cumulativeLineChart",recline.View.nvd3.Base.prototype.initialize.call(b,a)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){return{useInteractiveGuideline:!0,tooltips:!0}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.discreteBarChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="discreteBarChart",recline.View.nvd3.Base.prototype.initialize.call(b,a)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){return{computeXLabels:!1,options:{tooltips:!0}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.lineChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="lineChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!0)},render:function(){var b=this;recline.View.nvd3.Base.prototype.render.call(b,{}),b.state.get("options").datapoints&&a(".recline-graph").addClass("recline-show-datapoints")},getDefaults:function(){var a=this;return{options:{useInteractiveGuideline:!1,tooltips:!0,xAxis:{tickFormat:function(b){return a.chartMap?a.chartMap.get(b):b}}}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.linePlusBarChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="linePlusBarChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!0)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},alterChart:function(b){var c=this;b.x(function(a,b){return b}).y(function(a,b){return a.y}),b.options({focusEnable:!1});var d=0,e=c.state.get("lpbBarChartField")||a("#control-lpb-barchart-field").val();c.series.forEach(function(a,b){a.originalKey&&(a.key=a.originalKey,delete a.originalKey),delete a.bar,a.key!==e&&a.originalKey!==e||(d=b)}),c.series[d].bar=!0},getDefaults:function(){return{options:{tooltips:!0,showLegend:!0}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.lineWithFocusChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="lineWithFocusChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!0)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){var a=this;return{options:{tooltips:!0,xAxis:{tickFormat:function(b){return a.chartMap?a.chartMap.get(b):b}}}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.multiBarChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="multiBarChart",recline.View.nvd3.Base.prototype.initialize.call(b,a)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{}),nv.dispatch.on("render_end",function(){d3.selectAll(".nv-controlsWrap .nv-legend .nv-series").on("click",function(b){var c="Stacked"===b.key;a.state.get("options").stacked=c,a.lightUpdate(),a.chart.stacked(c)})})},getDefaults:function(){return{computeXLabels:!1,options:{reduceXTicks:!0,tooltips:!0}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.multiBarHorizontalChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="multiBarHorizontalChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!1)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){return{options:{tooltips:!0,reduceXTicks:!1}}},renderGoals:function(){var a=this,b=a.state.get("goal");nv.dispatch.on("render_end",null),this.canRenderGoal(b)&&nv.dispatch.on("render_end",function(){var c,d,e=a.chart.yAxis.scale(),f=a.chart.margin(),g=e(b.value)+f.left,h=f.top,i=jQuery("g").get(0).getBBox().height,j=d3.select("svg").append("g");b.label&&(c=g+5,d=h+5,j.append("text").text(b.title||"TARGET").attr("x",c).attr("y",d).attr("fill",b.color||"red").style("font-size","10px").style("font-weight","bold").style("font-style","italic")),j.append("line").attr("class","goal").attr("y1",h).attr("x1",g).attr("y2",i-5).attr("x2",g).attr("stroke-width",1).attr("stroke",b.color||"red").style("stroke-dasharray","3, 3")})}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.pieChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="pieChart",recline.View.nvd3.Base.prototype.initialize.call(b,a)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},alterChart:function(a){this.series.length>10&&a.showLegend(!1)},createSeries:function(a){var b=this;a=a.toJSON();var c=_.first(b.state.get("seriesFields"));return a=b.state.get("group")?_.reportBy(a,b.state.get("xfield"),b.state.get("seriesFields")):a,_.map(a,function(a){return{y:b.cleanupY(b.y(a,c)),x:b.x(a,b.state.get("xfield"))}})},getDefaults:function(){return{options:{showLabels:!0,labelType:"percent",tooltips:!0}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.scatterChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="scatterChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!0)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){var a=this;return{options:{showDistX:!0,showDistY:!0,onlyCircles:!1,xAxis:{tickFormat:function(b){return a.chartMap?a.chartMap.get(b):b}}}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.stackedAreaChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="stackedAreaChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!0)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){return{options:{useInteractiveGuideline:!0,tooltips:!0,xAxis:{tickFormat:function(a){return d3.time.format("%Y")(new Date(a))}}}}}})}(jQuery,recline.View.nvd3),jQuery(function(){"use strict";_.mixin({getFields:function(a){var b=[];try{b=_.pluck(a.fields.toJSON(),"id")}catch(a){console.error("Error retrieving dataset fields")}return b},applyOption:function(a,b){return _.map(a,function(a){return a.selected=!!_.inArray(b,a.value),a})},arrayToOptions:function(a){return _.map(a,function(a){return{name:a,value:a,selected:!1}})}})}); \ No newline at end of file +this.recline=this.recline||{},this.recline.View=this.recline.View||{},this.recline.View.nvd3=this.recline.View.nvd3||{};var globalchart,chartAxes=["x","y","y1","y2"];!function(a,b){"use strict";function c(a){return(a=a||"")+(1e16*Math.random()).toFixed(0)}b.Base=Backbone.View.extend({template:'
{{data}}
',CLEANUP_CHARS:"%$¥€",initialize:function(b){var d=this;d.$el=a(d.el),d.options=_.defaults(b||{},d.options);var e=_.merge({width:640,group:!1},d.getDefaults(),d.options.state.toJSON());d.graphType=d.graphType||"multiBarChart",d.uuid=c("nvd3chart_"),d.state=d.options.state,d.model=d.options.model,d.state.set(e),d.chartMap=d3.map(),d.listenTo(d.model.records,"add remove reset change",d.lightUpdate.bind(d)),globalchart=d},getLayoutParams:function(){var a=this;return{columnClass:"col-md-12",width:a.state.get("width")||a.$el.innerWidth()||640,height:a.state.get("chartHeight")||480}},render:function(){var a,b,c,d=this;d.listenToOnce(d.state,"change",d.render.bind(d)),c=d.getLayoutParams(),a=d.model.toTemplateJSON(),a.viewId=d.uuid,_.extend(a,c),b=Mustache.render(d.template,a),d.$el.html(b),d.$graph=d.$el.find(".panel."+a.viewId),d.trigger("chart:endDrawing");var e=d.needForceX(d.model.records,d.graphType);return d.state.set("computeXLabels",e,{silent:!0}),d.state.set("group",d.model.records.length>1e3||d.state.get("group",{silent:!0})),d.series=d.createSeries(d.model.records),nv.addGraph(function(){return d.chart=d.createGraph(d.graphType),d.alterChart&&d.alterChart(d.chart),chartAxes.forEach(function(a){if(d.chart[a+"Axis"]){var b=d.state.get(a+"Format")||{type:"String",format:""},c=d.getFormatter(b.type,b.format,a);d.calcTickValues(a,d.chart[a+"Axis"],d.state.get(a+"Values"),d.state.get(a+"ValuesStep")),d.chart[a+"Axis"].tickFormat(c)}}),d3.select("#"+d.uuid+" svg").datum(d.series).transition().duration(d.state.get("transitionTime")||500).call(d.chart),d.renderGoals(),"discreteBarChart"===d.graphType&&d.state.get("options")&&d.state.get("options").reduceXTicks&&d.reduceXTicks(),"function"==typeof d.chart.tooltips?d.chart.tooltips(d.state.get("options").tooltips):d.chart.tooltip.enabled(d.state.get("options").tooltips),nv.utils.windowResize(d.updateChart.bind(d)),d.chart}),d},calcTickValues:function(a,b,c,d){var e,f=this,g=["multiBarChart","discreteBarChart","linePlusBarChart"];d=d||1,this.isOldRangeType(c)&&(c=this.convertRange(c)),c&&f.rangesValid(c)&&(c[0]=parseInt(c[0]),c[1]=parseInt(c[1]),e=d3.range(c[0],c[1],d),"linePlusBarChart"===f.graphType&&"y1"===a?f.chart.bars.yDomain([c[0],c[1]],d):"linePlusBarChart"===f.graphType&&"y2"===a?f.chart.lines.yDomain([c[0],c[1]],d):_.inArray(g,f.graphType)&&"y"!==a?f.chart[a+"Domain"](d3.range(c[0],c[1],d)):f.chart[a+"Domain"]([c[0],c[1]])),b.tickValues(e)},isOldRangeType:function(a){return a&&-1!==a.indexOf("-")},convertRange:function(a){for(var b=a.replace(" ","").split("-"),c=0;c=parseInt(a[1])&&(b=!1),b},lightUpdate:function(){var a=this;a.chart&&(a.series=a.createSeries(a.model.records),a.setOptions(a.chart,a.state.get("options")),setTimeout(function(){d3.select("#"+a.uuid+" svg").datum(a.series).transition().duration(500).call(a.chart)},0))},canRenderGoal:function(a){return!d3.select("svg").empty()&&d3.select("svg .goal").empty()&&a&&a.value&&!isNaN(a.value)&&this.chart.yAxis},renderGoals:function(){var a=this,b=a.state.get("goal");nv.dispatch.on("render_end",null),this.canRenderGoal(b)&&nv.dispatch.on("render_end",function(){var c,d,e=a.chart.yAxis.scale(),f=a.chart.margin(),g=e(b.value)+f.top,h=f.left,i=d3.select("svg").size()?parseInt(d3.select("svg").style("width"))-10:0,j=d3.select("svg").append("g");b.label&&(b.outside?(c=h-50,d=g+3):(c=h+5,d=g-6),j.append("text").text("TARGET").attr("x",c).attr("y",d).attr("fill",b.color||"red").style("font-size","10px").style("font-weight","bold").style("font-style","italic")),j.append("line").attr("class","goal").attr("x1",h).attr("y1",g).attr("x2",i).attr("y2",g).attr("stroke-width",1).attr("stroke",b.color||"red").style("stroke-dasharray","3, 3")})},updateChart:function(){var a=this;d3.select("#"+a.uuid+" svg").transition().duration(a.state.get("transitionTime")||500).call(a.chart)},reduceXTicks:function(){var a=this,b=a.getLayoutParams(a.state.get("mode"));d3.select(".nv-x.nv-axis > g").selectAll("g").filter(function(c,d){return d%Math.ceil(a.model.records.length/(b.width/100))!=0}).selectAll("text, line").style("opacity",0)},createSeries:function(a){var b,c,d=this;return d.state.get("xfield")&&d.getSeries()?(a=a.toJSON(),b=_.compose(_.inferType,_.iteratee(d.state.get("xfield"))),c=d.state.get("xDataType")&&"Auto"!==d.state.get("xDataType")?d.state.get("xDataType"):b(_.last(a)||[]),_.map(d.getSeries(),function(b){var e={};e.key=b;var f=d.state.get("group")?_.reportBy(a,d.state.get("xfield"),d.state.get("seriesFields")):a;return f=_.sortBy(f,d.getSort(d.state.get("sort"))),f=_.reduce(f,function(a,c){var e=d.cleanupY(d.y(c,b));return e||0===e||"stackedAreaChart"===d.graphType?a.push(c):d.state.get("options").stacked&&(c[b]=0,a.push(c)),a},[]),e.values=_.map(f,function(a,e){var f=d.cleanupY(d.y(a,b));return f=d.state.get("yDataType")&&"Number"===d.state.get("yDataType")?numeral(f).value():_.cast(f,_.inferType(f)),d.state.get("computeXLabels")?(d.chartMap.set(e,d.x(a,d.state.get("xfield"))),{y:f,x:e,label:d.x(a,d.state.get("xfield"))}):{y:f,x:_.cast(d.x(a,d.state.get("xfield")),c)}}),e})):[]},cleanupY:function(a){var b=this;return"string"==typeof a?a.replace(new RegExp("["+b.CLEANUP_CHARS+"]"),""):a},getSort:function(a){return a&&"default"!==a?a:_.identity},needForceX:function(a,b){var c=this,d=c.state.get("xfield");return a=a.toJSON(),_.some(a,function(a){return"String"===_.inferType(a[d])})&&"discreteBarChart"!==b&&"multiBarChart"!==b},getFormatter:function(a,b,c){var d=this;return c=c||"x",d.state.get("computeXLabels")&&"x"===c?d.chartMap.get.bind(d.chartMap):{String:_.identity,Date:_.compose(d3.time.format(b||"%x"),_.instantiate(Date)),Number:d3.format(b||".02f"),Percentage:function(a){return d3.format(b||".02f")(100*a)+"%"},PercentageA:function(a){return d3.format(b||".02f")(a)+"%"}}[a]},setOptions:function(a,b){var c=this;for(var d in b){var e=b[d];"margin"===d&&(e.top=0,a.margin(e)),a&&_.isObject(e)&&!_.isArray(e)?c.setOptions(a[d],e):a&&_.isFunction(a[d])&&a[d](e)}},createGraph:function(a){var b=this,c=nv.models[a]();return b.setOptions(c,b.state.get("options")),c},getDefaults:function(){return{}},getState:function(){return this.state.attributes},getSeries:function(){return this.state.get("seriesFields")},x:function(a,b){return a[b]},y:function(a,b){return a[b]},destroy:function(){this.stopListening()},alterChart:function(){}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.cumulativeLineChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="cumulativeLineChart",recline.View.nvd3.Base.prototype.initialize.call(b,a)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){return{useInteractiveGuideline:!0,tooltips:!0}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.discreteBarChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="discreteBarChart",recline.View.nvd3.Base.prototype.initialize.call(b,a)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){return{computeXLabels:!1,options:{tooltips:!0}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.lineChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="lineChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!0)},render:function(){var b=this;recline.View.nvd3.Base.prototype.render.call(b,{}),b.state.get("options").datapoints&&a(".recline-graph").addClass("recline-show-datapoints")},getDefaults:function(){var a=this;return{options:{useInteractiveGuideline:!1,tooltips:!0,xAxis:{tickFormat:function(b){return a.chartMap?a.chartMap.get(b):b}}}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.linePlusBarChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="linePlusBarChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!0)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},alterChart:function(b){var c=this;b.x(function(a,b){return b}).y(function(a,b){return a.y}),b.options({focusEnable:!1});var d=0,e=c.state.get("lpbBarChartField")||a("#control-lpb-barchart-field").val();c.series.forEach(function(a,b){a.originalKey&&(a.key=a.originalKey,delete a.originalKey),delete a.bar,a.key!==e&&a.originalKey!==e||(d=b)}),c.series[d].bar=!0},getDefaults:function(){return{options:{tooltips:!0,showLegend:!0}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.lineWithFocusChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="lineWithFocusChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!0)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){var a=this;return{options:{tooltips:!0,xAxis:{tickFormat:function(b){return a.chartMap?a.chartMap.get(b):b}}}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.multiBarChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="multiBarChart",recline.View.nvd3.Base.prototype.initialize.call(b,a)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{}),nv.dispatch.on("render_end",function(){d3.selectAll(".nv-controlsWrap .nv-legend .nv-series").on("click",function(b){var c="Stacked"===b.key;a.state.get("options").stacked=c,a.lightUpdate(),a.chart.stacked(c)})})},getDefaults:function(){return{computeXLabels:!1,options:{reduceXTicks:!0,tooltips:!0}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.multiBarHorizontalChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="multiBarHorizontalChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!1)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){return{options:{tooltips:!0,reduceXTicks:!1}}},renderGoals:function(){var a=this,b=a.state.get("goal");nv.dispatch.on("render_end",null),this.canRenderGoal(b)&&nv.dispatch.on("render_end",function(){var c,d,e=a.chart.yAxis.scale(),f=a.chart.margin(),g=e(b.value)+f.left,h=f.top,i=jQuery("g").get(0).getBBox().height,j=d3.select("svg").append("g");b.label&&(c=g+5,d=h+5,j.append("text").text(b.title||"TARGET").attr("x",c).attr("y",d).attr("fill",b.color||"red").style("font-size","10px").style("font-weight","bold").style("font-style","italic")),j.append("line").attr("class","goal").attr("y1",h).attr("x1",g).attr("y2",i-5).attr("x2",g).attr("stroke-width",1).attr("stroke",b.color||"red").style("stroke-dasharray","3, 3")})}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.pieChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="pieChart",recline.View.nvd3.Base.prototype.initialize.call(b,a)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},alterChart:function(a){this.series.length>10&&a.showLegend(!1)},createSeries:function(a){var b=this;a=a.toJSON();var c=_.first(b.state.get("seriesFields"));return a=b.state.get("group")?_.reportBy(a,b.state.get("xfield"),b.state.get("seriesFields")):a,_.map(a,function(a){return{y:b.cleanupY(b.y(a,c)),x:b.x(a,b.state.get("xfield"))}})},getDefaults:function(){return{options:{showLabels:!0,labelType:"percent",tooltips:!0}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.scatterChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="scatterChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!0)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){var a=this;return{options:{showDistX:!0,showDistY:!0,onlyCircles:!1,xAxis:{tickFormat:function(b){return a.chartMap?a.chartMap.get(b):b}}}}}})}(jQuery,recline.View.nvd3),this.recline=this.recline||{},this.recline.View=this.recline.View||{},function(a,b){"use strict";b.stackedAreaChart=recline.View.nvd3.Base.extend({initialize:function(a){var b=this;b.graphType="stackedAreaChart",recline.View.nvd3.Base.prototype.initialize.call(b,a),b.state.set("computeXLabels",!0)},render:function(){var a=this;recline.View.nvd3.Base.prototype.render.call(a,{})},getDefaults:function(){return{options:{useInteractiveGuideline:!0,tooltips:!0,xAxis:{tickFormat:function(a){return d3.time.format("%Y")(new Date(a))}}}}}})}(jQuery,recline.View.nvd3),jQuery(function(){"use strict";_.mixin({getFields:function(a){var b=[];try{b=_.pluck(a.fields.toJSON(),"id")}catch(a){console.error("Error retrieving dataset fields")}return b},applyOption:function(a,b){return _.map(a,function(a){return a.selected=!!_.inArray(b,a.value),a})},arrayToOptions:function(a){return _.map(a,function(a){return{name:a,value:a,selected:!1}})}})}); \ No newline at end of file diff --git a/dkan/libraries/reclineViewNvd3/src/controls/recline.view.nvd3.baseControl.js b/dkan/libraries/reclineViewNvd3/src/controls/recline.view.nvd3.baseControl.js index 12bdde306..8b1fce454 100644 --- a/dkan/libraries/reclineViewNvd3/src/controls/recline.view.nvd3.baseControl.js +++ b/dkan/libraries/reclineViewNvd3/src/controls/recline.view.nvd3.baseControl.js @@ -124,8 +124,8 @@ my.BaseControl = Backbone.View.extend({ '' + '' + '' + - '' + - '' + + '' + + '' + '' + '' + '' + @@ -387,7 +387,7 @@ my.BaseControl = Backbone.View.extend({ '' + '
' + '
' + - '' + + '' + '
' + '
' + '' + @@ -494,7 +494,7 @@ my.BaseControl = Backbone.View.extend({ self.state.set('sortFields', _.applyOption(sortFields, [self.state.get('sort')])); var options = self.state.get('options') || {}; - options.margin = options.margin || {top: 30, right: 20, bottom: 50, left: 60}; + options.margin = options.margin || {top: 0, right: 20, bottom: 50, left: 60}; self.state.set('options', options, {silent : true}); $('#base-controls').html(Mustache.render(self.composeTemplate(), self.state.toJSON())); $('#goal-controls').html(Mustache.render(self.templateGoal, self.state.toJSON())); @@ -603,7 +603,7 @@ my.BaseControl = Backbone.View.extend({ showTitle: self.$('#control-chart-show-title').is(':checked'), xValues: [self.$('#control-chart-x-values-from').val(), self.$('#control-chart-x-values-to').val()], xValuesFrom: self.$('#control-chart-x-values-from').val(), - xValuesTo: self.$('#control-chart-x-values-to').val(), + xValuesTo: self.$('#control-chart-x-values-to').val(), xValuesStep: parseInt(self.$('#control-chart-x-values-step').val() || 1), yValues: [self.$('#control-chart-y-values-from').val(), self.$('#control-chart-y-values-to').val()], yValuesFrom: self.$('#control-chart-y-values-from').val(), @@ -690,20 +690,20 @@ my.BaseControl = Backbone.View.extend({ // Process tick settings in Y1 axis. var valid_y1 = self.processTicks(newSettings.y1ValuesFrom, newSettings.y1ValuesTo, newSettings.y1ValuesStep); if (!valid_y1) { - currentSettings.errors.y1Ticks = error; + currentSettings.errors.y1Ticks = error; isValid = false; } // Process tick settings in Y2 axis. var valid_y2 = self.processTicks(newSettings.y2ValuesFrom, newSettings.y2ValuesTo, newSettings.y2ValuesStep); if (!valid_y2) { - currentSettings.errors.y2Ticks = error; + currentSettings.errors.y2Ticks = error; isValid = false; } if (isValid) { // Clear all errors if any. - currentSettings.errors = {}; + currentSettings.errors = {}; } // Update state. @@ -717,11 +717,11 @@ my.BaseControl = Backbone.View.extend({ if (fromValue && toValue) { // Calculate the number of ticks. var ticks = (toValue - fromValue) / stepValue; - // If the number of ticks is higher than ALLOWED_TICKS value + // If the number of ticks is higher than ALLOWED_TICKS value // then return FALSE. if (ticks > ALLOWED_TICKS) { return false; - } + } } return true; diff --git a/dkan/libraries/reclineViewNvd3/src/recline.view.nvd3.base.js b/dkan/libraries/reclineViewNvd3/src/recline.view.nvd3.base.js index feeea9df9..e53ff84b0 100644 --- a/dkan/libraries/reclineViewNvd3/src/recline.view.nvd3.base.js +++ b/dkan/libraries/reclineViewNvd3/src/recline.view.nvd3.base.js @@ -1,5 +1,6 @@ /*jshint multistr:true */ /*jshint -W030 */ + this.recline = this.recline || {}; this.recline.View = this.recline.View || {}; this.recline.View.nvd3 = this.recline.View.nvd3 || {}; @@ -23,7 +24,7 @@ var chartAxes = ['x','y','y1','y2']; '
' + '
' + '' + + 'style="height:{{height}}px;width: 100%;">' + '' + '
' + '
' + @@ -38,7 +39,6 @@ var chartAxes = ['x','y','y1','y2']; var stateData = _.merge({ width: 640, - height: 480, group: false }, self.getDefaults(), @@ -58,7 +58,7 @@ var chartAxes = ['x','y','y1','y2']; var layout = { columnClass: 'col-md-12', width: self.state.get('width') || self.$el.innerWidth() || DEFAULT_CHART_WIDTH, - height: self.state.get('height') || DEFAULT_CHART_HEIGHT + height: self.state.get('chartHeight') || DEFAULT_CHART_HEIGHT }; return layout; }, @@ -322,6 +322,7 @@ var chartAxes = ['x','y','y1','y2']; data.values = _.map(rc, function(record, index){ // Cleanup 'y' value removing special characters. var y = self.cleanupY(self.y(record, serie)); + // Get specified type for 'y' values. if(self.state.get('yDataType') && self.state.get('yDataType') === 'Number'){ // If 'Number' then parse it. @@ -375,16 +376,19 @@ var chartAxes = ['x','y','y1','y2']; 'String': _.identity, 'Date': _.compose(d3.time.format(format || '%x'),_.instantiate(Date)), 'Number': d3.format(format || '.02f'), - 'Percentage': d3.format(format || '.02f'), - 'PercentageInt': function (n) { return d3.format(format || '.02f')(n) + '%'; }, + 'Percentage': function (n) { return d3.format(format || '.02f')(n*100) + '%'; }, + 'PercentageA': function (n) { return d3.format(format || '.02f')(n) + '%'; }, }; return formatter[type]; }, - setOptions: function (chart, options) { + setOptions: function(chart, options) { var self = this; for(var optionName in options){ var optionValue = options[optionName]; if(optionName === 'margin'){ + // Force zero since auto-legend adjustment fails with other values. + // REF novus/nvd3#515 + optionValue.top = 0; chart.margin(optionValue); } if(chart && _.isObject(optionValue) && !_.isArray(optionValue)){ diff --git a/dkan/libraries/symfonyserializer/CHANGELOG.md b/dkan/libraries/symfonyserializer/CHANGELOG.md index 45abbc1b1..f8839b0eb 100644 --- a/dkan/libraries/symfonyserializer/CHANGELOG.md +++ b/dkan/libraries/symfonyserializer/CHANGELOG.md @@ -17,6 +17,7 @@ CHANGELOG * added `AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT` context option to disable throwing an `UnexpectedValueException` on a type mismatch + * added support for serializing `DateInterval` objects 3.3.0 ----- diff --git a/dkan/libraries/symfonyserializer/Encoder/ChainDecoder.php b/dkan/libraries/symfonyserializer/Encoder/ChainDecoder.php index 930c41955..c44510f60 100644 --- a/dkan/libraries/symfonyserializer/Encoder/ChainDecoder.php +++ b/dkan/libraries/symfonyserializer/Encoder/ChainDecoder.php @@ -62,7 +62,7 @@ public function supportsDecoding($format, array $context = array()) * * @return DecoderInterface * - * @throws RuntimeException If no decoder is found. + * @throws RuntimeException if no decoder is found */ private function getDecoder($format, array $context) { diff --git a/dkan/libraries/symfonyserializer/Encoder/XmlEncoder.php b/dkan/libraries/symfonyserializer/Encoder/XmlEncoder.php index f8e2ea594..43a893e83 100644 --- a/dkan/libraries/symfonyserializer/Encoder/XmlEncoder.php +++ b/dkan/libraries/symfonyserializer/Encoder/XmlEncoder.php @@ -103,10 +103,10 @@ public function decode($data, $format, array $context = array()) $rootNode = null; foreach ($dom->childNodes as $child) { - if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { + if (XML_DOCUMENT_TYPE_NODE === $child->nodeType) { throw new UnexpectedValueException('Document types are not allowed.'); } - if (!$rootNode && $child->nodeType !== XML_PI_NODE) { + if (!$rootNode && XML_PI_NODE !== $child->nodeType) { $rootNode = $child; } } @@ -349,7 +349,7 @@ private function parseXmlValue(\DOMNode $node, array $context = array()) $value = array(); foreach ($node->childNodes as $subnode) { - if ($subnode->nodeType === XML_PI_NODE) { + if (XML_PI_NODE === $subnode->nodeType) { continue; } @@ -398,7 +398,7 @@ private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null) $data = $this->serializer->normalize($data, $this->format, $this->context); } $parentNode->setAttribute($attributeName, $data); - } elseif ($key === '#') { + } elseif ('#' === $key) { $append = $this->selectNodeType($parentNode, $data); } elseif (is_array($data) && false === is_numeric($key)) { // Is this array fully numeric keys? diff --git a/dkan/libraries/symfonyserializer/Normalizer/AbstractNormalizer.php b/dkan/libraries/symfonyserializer/Normalizer/AbstractNormalizer.php index 47f789ac5..d27ea89b1 100644 --- a/dkan/libraries/symfonyserializer/Normalizer/AbstractNormalizer.php +++ b/dkan/libraries/symfonyserializer/Normalizer/AbstractNormalizer.php @@ -327,7 +327,7 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref $paramName = $constructorParameter->name; $key = $this->nameConverter ? $this->nameConverter->normalize($paramName) : $paramName; - $allowed = $allowedAttributes === false || in_array($paramName, $allowedAttributes); + $allowed = false === $allowedAttributes || in_array($paramName, $allowedAttributes); $ignored = !$this->isAllowedAttribute($class, $paramName, $format, $context); if ($constructorParameter->isVariadic()) { if ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) { diff --git a/dkan/libraries/symfonyserializer/Normalizer/AbstractObjectNormalizer.php b/dkan/libraries/symfonyserializer/Normalizer/AbstractObjectNormalizer.php index 43bba6119..5a49cfec9 100644 --- a/dkan/libraries/symfonyserializer/Normalizer/AbstractObjectNormalizer.php +++ b/dkan/libraries/symfonyserializer/Normalizer/AbstractObjectNormalizer.php @@ -187,7 +187,7 @@ public function denormalize($data, $class, $format = null, array $context = arra $attribute = $this->nameConverter->denormalize($attribute); } - if (($allowedAttributes !== false && !in_array($attribute, $allowedAttributes)) || !$this->isAllowedAttribute($class, $attribute, $format, $context)) { + if ((false !== $allowedAttributes && !in_array($attribute, $allowedAttributes)) || !$this->isAllowedAttribute($class, $attribute, $format, $context)) { if (isset($context[self::ALLOW_EXTRA_ATTRIBUTES]) && !$context[self::ALLOW_EXTRA_ATTRIBUTES]) { $extraAttributes[] = $attribute; } diff --git a/dkan/libraries/symfonyserializer/Normalizer/ArrayDenormalizer.php b/dkan/libraries/symfonyserializer/Normalizer/ArrayDenormalizer.php index 4f79f4f50..55fb84ed8 100644 --- a/dkan/libraries/symfonyserializer/Normalizer/ArrayDenormalizer.php +++ b/dkan/libraries/symfonyserializer/Normalizer/ArrayDenormalizer.php @@ -36,13 +36,13 @@ class ArrayDenormalizer implements ContextAwareDenormalizerInterface, Serializer */ public function denormalize($data, $class, $format = null, array $context = array()) { - if ($this->serializer === null) { + if (null === $this->serializer) { throw new BadMethodCallException('Please set a serializer before calling denormalize()!'); } if (!is_array($data)) { throw new InvalidArgumentException('Data expected to be an array, '.gettype($data).' given.'); } - if (substr($class, -2) !== '[]') { + if ('[]' !== substr($class, -2)) { throw new InvalidArgumentException('Unsupported class: '.$class); } @@ -66,7 +66,7 @@ public function denormalize($data, $class, $format = null, array $context = arra */ public function supportsDenormalization($data, $type, $format = null, array $context = array()) { - return substr($type, -2) === '[]' + return '[]' === substr($type, -2) && $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format, $context); } diff --git a/dkan/libraries/symfonyserializer/Normalizer/DateIntervalNormalizer.php b/dkan/libraries/symfonyserializer/Normalizer/DateIntervalNormalizer.php new file mode 100644 index 000000000..3628cd670 --- /dev/null +++ b/dkan/libraries/symfonyserializer/Normalizer/DateIntervalNormalizer.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +use Symfony\Component\Serializer\Exception\InvalidArgumentException; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; + +/** + * Normalizes an instance of {@see \DateInterval} to an interval string. + * Denormalizes an interval string to an instance of {@see \DateInterval}. + * + * @author Jérôme Parmentier + */ +class DateIntervalNormalizer implements NormalizerInterface, DenormalizerInterface +{ + const FORMAT_KEY = 'dateinterval_format'; + + /** + * @var string + */ + private $format; + + /** + * @param string $format + */ + public function __construct($format = 'P%yY%mM%dDT%hH%iM%sS') + { + $this->format = $format; + } + + /** + * {@inheritdoc} + * + * @throws InvalidArgumentException + */ + public function normalize($object, $format = null, array $context = array()) + { + if (!$object instanceof \DateInterval) { + throw new InvalidArgumentException('The object must be an instance of "\DateInterval".'); + } + + $dateIntervalFormat = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : $this->format; + + return $object->format($dateIntervalFormat); + } + + /** + * {@inheritdoc} + */ + public function supportsNormalization($data, $format = null) + { + return $data instanceof \DateInterval; + } + + /** + * {@inheritdoc} + * + * @throws InvalidArgumentException + * @throws UnexpectedValueException + */ + public function denormalize($data, $class, $format = null, array $context = array()) + { + if (!is_string($data)) { + throw new InvalidArgumentException(sprintf('Data expected to be a string, %s given.', gettype($data))); + } + + if (!$this->isISO8601($data)) { + throw new UnexpectedValueException('Expected a valid ISO 8601 interval string.'); + } + + $dateIntervalFormat = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : $this->format; + + $valuePattern = '/^'.preg_replace('/%([yYmMdDhHiIsSwW])(\w)/', '(?P<$1>\d+)$2', $dateIntervalFormat).'$/'; + if (!preg_match($valuePattern, $data)) { + throw new UnexpectedValueException(sprintf('Value "%s" contains intervals not accepted by format "%s".', $data, $dateIntervalFormat)); + } + + try { + return new \DateInterval($data); + } catch (\Exception $e) { + throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function supportsDenormalization($data, $type, $format = null) + { + return \DateInterval::class === $type; + } + + private function isISO8601($string) + { + return preg_match('/^P(?=\w*(?:\d|%\w))(?:\d+Y|%[yY]Y)?(?:\d+M|%[mM]M)?(?:(?:\d+D|%[dD]D)|(?:\d+W|%[wW]W))?(?:T(?:\d+H|[hH]H)?(?:\d+M|[iI]M)?(?:\d+S|[sS]S)?)?$/', $string); + } +} diff --git a/dkan/libraries/symfonyserializer/Normalizer/NormalizableInterface.php b/dkan/libraries/symfonyserializer/Normalizer/NormalizableInterface.php index e19fe5ce5..48fb8b482 100644 --- a/dkan/libraries/symfonyserializer/Normalizer/NormalizableInterface.php +++ b/dkan/libraries/symfonyserializer/Normalizer/NormalizableInterface.php @@ -27,11 +27,11 @@ interface NormalizableInterface * It is important to understand that the normalize() call should normalize * recursively all child objects of the implementor. * - * @param NormalizerInterface $normalizer The normalizer is given so that you - * can use it to normalize objects contained within this object. - * @param string|null $format The format is optionally given to be able to normalize differently - * based on different output formats. - * @param array $context Options for normalizing this object + * @param NormalizerInterface $normalizer the normalizer is given so that you + * can use it to normalize objects contained within this object + * @param string|null $format the format is optionally given to be able to normalize differently + * based on different output formats + * @param array $context options for normalizing this object * * @return array|scalar */ diff --git a/dkan/libraries/symfonyserializer/Normalizer/ObjectNormalizer.php b/dkan/libraries/symfonyserializer/Normalizer/ObjectNormalizer.php index 00a0a693a..87fdfca11 100644 --- a/dkan/libraries/symfonyserializer/Normalizer/ObjectNormalizer.php +++ b/dkan/libraries/symfonyserializer/Normalizer/ObjectNormalizer.php @@ -49,7 +49,7 @@ protected function extractAttributes($object, $format = null, array $context = a $reflClass = new \ReflectionClass($object); foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) { if ( - $reflMethod->getNumberOfRequiredParameters() !== 0 || + 0 !== $reflMethod->getNumberOfRequiredParameters() || $reflMethod->isStatic() || $reflMethod->isConstructor() || $reflMethod->isDestructor() @@ -67,7 +67,7 @@ protected function extractAttributes($object, $format = null, array $context = a if (!$reflClass->hasProperty($attributeName)) { $attributeName = lcfirst($attributeName); } - } elseif (strpos($name, 'is') === 0) { + } elseif (0 === strpos($name, 'is')) { // issers $attributeName = substr($name, 2); diff --git a/dkan/libraries/symfonyserializer/Tests/Fixtures/ScalarDummy.php b/dkan/libraries/symfonyserializer/Tests/Fixtures/ScalarDummy.php index e9db23882..598e76fda 100644 --- a/dkan/libraries/symfonyserializer/Tests/Fixtures/ScalarDummy.php +++ b/dkan/libraries/symfonyserializer/Tests/Fixtures/ScalarDummy.php @@ -23,12 +23,12 @@ class ScalarDummy implements NormalizableInterface, DenormalizableInterface public function normalize(NormalizerInterface $normalizer, $format = null, array $context = array()) { - return $format === 'xml' ? $this->xmlFoo : $this->foo; + return 'xml' === $format ? $this->xmlFoo : $this->foo; } public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array()) { - if ($format === 'xml') { + if ('xml' === $format) { $this->xmlFoo = $data; } else { $this->foo = $data; diff --git a/dkan/libraries/symfonyserializer/Tests/Normalizer/DateIntervalNormalizerTest.php b/dkan/libraries/symfonyserializer/Tests/Normalizer/DateIntervalNormalizerTest.php new file mode 100644 index 000000000..f6dc6c247 --- /dev/null +++ b/dkan/libraries/symfonyserializer/Tests/Normalizer/DateIntervalNormalizerTest.php @@ -0,0 +1,137 @@ + + */ +class DateIntervalNormalizerTest extends TestCase +{ + /** + * @var DateIntervalNormalizer + */ + private $normalizer; + + protected function setUp() + { + $this->normalizer = new DateIntervalNormalizer(); + } + + public function dataProviderISO() + { + $data = array( + array('P%YY%MM%DDT%HH%IM%SS', 'P00Y00M00DT00H00M00S', 'PT0S'), + array('P%yY%mM%dDT%hH%iM%sS', 'P0Y0M0DT0H0M0S', 'PT0S'), + array('P%yY%mM%dDT%hH%iM%sS', 'P10Y2M3DT16H5M6S', 'P10Y2M3DT16H5M6S'), + array('P%yY%mM%dDT%hH%iM', 'P10Y2M3DT16H5M', 'P10Y2M3DT16H5M'), + array('P%yY%mM%dDT%hH', 'P10Y2M3DT16H', 'P10Y2M3DT16H'), + array('P%yY%mM%dD', 'P10Y2M3D', 'P10Y2M3DT0H'), + ); + + return $data; + } + + public function testSupportsNormalization() + { + $this->assertTrue($this->normalizer->supportsNormalization(new \DateInterval('P00Y00M00DT00H00M00S'))); + $this->assertFalse($this->normalizer->supportsNormalization(new \stdClass())); + } + + public function testNormalize() + { + $this->assertEquals('P0Y0M0DT0H0M0S', $this->normalizer->normalize(new \DateInterval('PT0S'))); + } + + /** + * @dataProvider dataProviderISO + */ + public function testNormalizeUsingFormatPassedInContext($format, $output, $input) + { + $this->assertEquals($output, $this->normalizer->normalize(new \DateInterval($input), null, array(DateIntervalNormalizer::FORMAT_KEY => $format))); + } + + /** + * @dataProvider dataProviderISO + */ + public function testNormalizeUsingFormatPassedInConstructor($format, $output, $input) + { + $this->assertEquals($output, (new DateIntervalNormalizer($format))->normalize(new \DateInterval($input))); + } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException + * @expectedExceptionMessage The object must be an instance of "\DateInterval". + */ + public function testNormalizeInvalidObjectThrowsException() + { + $this->normalizer->normalize(new \stdClass()); + } + + public function testSupportsDenormalization() + { + $this->assertTrue($this->normalizer->supportsDenormalization('P00Y00M00DT00H00M00S', \DateInterval::class)); + $this->assertFalse($this->normalizer->supportsDenormalization('foo', 'Bar')); + } + + public function testDenormalize() + { + $this->assertDateIntervalEquals(new \DateInterval('P00Y00M00DT00H00M00S'), $this->normalizer->denormalize('P00Y00M00DT00H00M00S', \DateInterval::class)); + } + + /** + * @dataProvider dataProviderISO + */ + public function testDenormalizeUsingFormatPassedInContext($format, $input, $output) + { + $this->assertDateIntervalEquals(new \DateInterval($output), $this->normalizer->denormalize($input, \DateInterval::class, null, array(DateIntervalNormalizer::FORMAT_KEY => $format))); + } + + /** + * @dataProvider dataProviderISO + */ + public function testDenormalizeUsingFormatPassedInConstructor($format, $input, $output) + { + $this->assertDateIntervalEquals(new \DateInterval($output), (new DateIntervalNormalizer($format))->denormalize($input, \DateInterval::class)); + } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException + */ + public function testDenormalizeExpectsString() + { + $this->normalizer->denormalize(1234, \DateInterval::class); + } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException + * @expectedExceptionMessage Expected a valid ISO 8601 interval string. + */ + public function testDenormalizeNonISO8601IntervalStringThrowsException() + { + $this->normalizer->denormalize('10 years 2 months 3 days', \DateInterval::class, null); + } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException + */ + public function testDenormalizeInvalidDataThrowsException() + { + $this->normalizer->denormalize('invalid interval', \DateInterval::class); + } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException + */ + public function testDenormalizeFormatMismatchThrowsException() + { + $this->normalizer->denormalize('P00Y00M00DT00H00M00S', \DateInterval::class, null, array(DateIntervalNormalizer::FORMAT_KEY => 'P%yY%mM%dD')); + } + + private function assertDateIntervalEquals(\DateInterval $expected, \DateInterval $actual) + { + $this->assertEquals($expected->format('%RP%yY%mM%dDT%hH%iM%sS'), $actual->format('%RP%yY%mM%dDT%hH%iM%sS')); + } +} diff --git a/dkan/modules/contrib/admin_views/LICENSE.txt b/dkan/modules/contrib/admin_views/LICENSE.txt new file mode 100644 index 000000000..d159169d1 --- /dev/null +++ b/dkan/modules/contrib/admin_views/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/dkan/modules/contrib/admin_views/PATCHES.txt b/dkan/modules/contrib/admin_views/PATCHES.txt new file mode 100644 index 000000000..0b82a8969 --- /dev/null +++ b/dkan/modules/contrib/admin_views/PATCHES.txt @@ -0,0 +1,4 @@ +The following patches have been applied to this project: +- https://www.drupal.org/files/issues/admin_views-duplicate_system_path-1780004-54.patch + +This file was automatically generated by Drush Make (http://drupal.org/project/drush). diff --git a/dkan/modules/contrib/admin_views/admin_views.css b/dkan/modules/contrib/admin_views/admin_views.css new file mode 100644 index 000000000..8a94f64bd --- /dev/null +++ b/dkan/modules/contrib/admin_views/admin_views.css @@ -0,0 +1,20 @@ + +.admin-views-view .views-exposed-form .form-text { + width: 10em; +} + +.admin-views-view .views-exposed-form .description { + display: none; +} + +.admin-views-view .views-exposed-form .views-submit-button, +.admin-views-view .views-exposed-form .views-reset-button { + padding-right: 0; +} + +.admin-views-view .form-item-operation { + float: left; + margin-top: 0; + margin-bottom: 0; + margin-right: 1em; +} diff --git a/dkan/modules/contrib/admin_views/admin_views.info b/dkan/modules/contrib/admin_views/admin_views.info new file mode 100644 index 000000000..2dc00a581 --- /dev/null +++ b/dkan/modules/contrib/admin_views/admin_views.info @@ -0,0 +1,18 @@ +name = Administration views +description = Replaces all system object management pages in Drupal core with real views. +package = Administration +core = 7.x +dependencies[] = views +dependencies[] = views_bulk_operations (>=7.x-3.2) + +files[] = plugins/views_plugin_display_system.inc +files[] = plugins/views_plugin_access_menu.inc + +files[] = tests/admin_views.test + +; Information added by Drupal.org packaging script on 2016-08-02 +version = "7.x-1.6" +core = "7.x" +project = "admin_views" +datestamp = "1470165840" + diff --git a/dkan/modules/contrib/admin_views/admin_views.install b/dkan/modules/contrib/admin_views/admin_views.install new file mode 100644 index 000000000..3fdbc25b0 --- /dev/null +++ b/dkan/modules/contrib/admin_views/admin_views.install @@ -0,0 +1,16 @@ + 3, + ); +} + +/** + * Implements hook_form_FORM_ID_alter(). + */ +function admin_views_form_views_ui_edit_form_alter(&$form, &$form_state) { + array_unshift($form['actions']['save']['#validate'], '_admin_views_form_views_ui_edit_form_validate'); +} + +/** + * Custom validation function when Views UI edit form is submitted. + */ +function _admin_views_form_views_ui_edit_form_validate(&$form, &$form_state) { + if (isset($form_state['view'])) { + // Retrieve system paths on the current view. + $system_paths = admin_views_system_paths($form_state['view']); + // If system paths exist, check if any duplicates. + if (!empty($system_paths)) { + $duplicate_paths = array(); + foreach ($system_paths as $path => $path_views) { + foreach ($path_views as $path_view) { + foreach ($path_view as $view_name => $view_display) { + $system_view[$path] = array($view_name => $view_display); + if (admin_views_duplicate_path($system_view)) { + $duplicate_paths[] = $path; + } + } + } + } + // If any duplicates, display error message. + if (!empty($duplicate_paths)) { + form_set_error('', t('Paths are already in use by other system views: !path. Enter a different path, or modify, disable, or delete the conflicting views.', array( + '!path' => implode(', ', $duplicate_paths)))); + } + } + } +} + +/** + * Paths for enabled system views. + * + * @param object $view + * (optional) A view to be checked for system view displays. If not + * included, all views are checked. + * + * @return array + * An array of system paths, including view name and view display. + */ +function admin_views_system_paths($view = NULL) { + $system_paths = array(); + if ($view == NULL) { + $views = views_get_all_views(); + } + else { + $views[] = $view; + } + foreach ($views as $view) { + if ($view->disabled) { + continue; + } + foreach ($view->display as $display => $settings) { + if (isset($settings->display_plugin) && $settings->display_plugin == 'system' && isset($settings->display_options['path'])) { + $system_paths[$settings->display_options['path']][] = array($view->name => $display); + } + } + } + return $system_paths; +} + +/** + * Determine if there are duplicate views system paths. + * + * @param array $view + * Array including a system path, and the view name and display where it + * is located. + * + * @return boolean + * Duplicate path exists other than current view name/display combination. + */ +function admin_views_duplicate_path($view) { + $system_paths = admin_views_system_paths(); + $view_path = key($view); + if (!isset($system_paths[$view_path])) { + return FALSE; + } + $view_name = key($view[$view_path]); + $view_display = $view[$view_path][$view_name]; + foreach ($system_paths[$view_path] as $system_views) { + foreach ($system_views as $system_view_name => $system_view_display) { + if (!($system_view_name == $view_name && $system_view_display == $view_display)) { + return TRUE; + } + } + } + return FALSE; +} diff --git a/dkan/modules/contrib/admin_views/admin_views.views.inc b/dkan/modules/contrib/admin_views/admin_views.views.inc new file mode 100644 index 000000000..d85671e96 --- /dev/null +++ b/dkan/modules/contrib/admin_views/admin_views.views.inc @@ -0,0 +1,42 @@ + 'views', // This just tells our themes are elsewhere. + 'display' => array( + 'system' => array( + 'title' => t('System'), + 'help' => t('Display the view as replacement for an existing menu path.'), + 'path' => "$path/plugins", + 'handler' => 'views_plugin_display_system', + 'theme' => 'views_view', + 'uses hook menu' => TRUE, + 'use ajax' => TRUE, + 'use pager' => TRUE, + 'accept attachments' => TRUE, + 'admin' => t('System'), + ), + ), + 'access' => array( + 'menu' => array( + 'title' => t('Menu system path'), + 'help' => t('Access will be granted based on the original system path.'), + 'handler' => 'views_plugin_access_menu', + 'uses options' => FALSE, + 'path' => "$path/plugins", + ), + ), + ); + + return $plugins; +} diff --git a/dkan/modules/contrib/admin_views/admin_views.views_default.inc b/dkan/modules/contrib/admin_views/admin_views.views_default.inc new file mode 100644 index 000000000..f13736fe3 --- /dev/null +++ b/dkan/modules/contrib/admin_views/admin_views.views_default.inc @@ -0,0 +1,43 @@ + $file) { + // Extract the primary module dependency of the default admin view, which + // is the filename prefix delimited by a period/dot; e.g., + // 'taxonomy.foo-bar.inc', and only include it if that module is enabled. + $dependency = strtok($file->filename, '.'); + if (isset($modules[$dependency])) { + include $filepath; + if (isset($view)) { + $views[$view->name] = $view; + } + } + } + } + } + return $views; +} + diff --git a/dkan/modules/contrib/admin_views/admin_views_default/book.admin-content-book.inc b/dkan/modules/contrib/admin_views/admin_views_default/book.admin-content-book.inc new file mode 100644 index 000000000..df17b0bb5 --- /dev/null +++ b/dkan/modules/contrib/admin_views/admin_views_default/book.admin-content-book.inc @@ -0,0 +1,398 @@ +name = 'admin_views_book'; +$view->description = 'Manage your site\'s book outlines.'; +$view->tag = 'default'; +$view->base_table = 'node'; +$view->human_name = 'Administration: Books'; +$view->core = 7; +$view->api_version = '3.0'; +$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + +/* Display: Master */ +$handler = $view->new_display('default', 'Master', 'default'); +$handler->display->display_options['title'] = 'Books'; +$handler->display->display_options['use_ajax'] = TRUE; +$handler->display->display_options['use_more_always'] = FALSE; +$handler->display->display_options['access']['type'] = 'menu'; +$handler->display->display_options['cache']['type'] = 'none'; +$handler->display->display_options['query']['type'] = 'views_query'; +$handler->display->display_options['exposed_form']['type'] = 'basic'; +$handler->display->display_options['exposed_form']['options']['reset_button'] = TRUE; +$handler->display->display_options['pager']['type'] = 'full'; +$handler->display->display_options['pager']['options']['items_per_page'] = '50'; +$handler->display->display_options['pager']['options']['offset'] = '0'; +$handler->display->display_options['pager']['options']['id'] = '0'; +$handler->display->display_options['pager']['options']['quantity'] = '9'; +$handler->display->display_options['style_plugin'] = 'table'; +$handler->display->display_options['style_options']['columns'] = array( + 'views_bulk_operations' => 'views_bulk_operations', + 'title' => 'title', + 'timestamp' => 'title', + 'nid' => 'nid', + 'created' => 'created', + 'changed' => 'changed', + 'status' => 'status', + 'nothing' => 'nothing', +); +$handler->display->display_options['style_options']['default'] = 'created'; +$handler->display->display_options['style_options']['info'] = array( + 'views_bulk_operations' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'title' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => ' ', + 'empty_column' => 0, + ), + 'timestamp' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'nid' => array( + 'sortable' => 0, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'created' => array( + 'sortable' => 1, + 'default_sort_order' => 'desc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'changed' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'status' => array( + 'sortable' => 0, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'nothing' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), +); +$handler->display->display_options['style_options']['empty_table'] = TRUE; +/* No results behavior: Global: Unfiltered text */ +$handler->display->display_options['empty']['area_text_custom']['id'] = 'area_text_custom'; +$handler->display->display_options['empty']['area_text_custom']['table'] = 'views'; +$handler->display->display_options['empty']['area_text_custom']['field'] = 'area_text_custom'; +$handler->display->display_options['empty']['area_text_custom']['empty'] = TRUE; +$handler->display->display_options['empty']['area_text_custom']['content'] = 'No books available.'; +/* Relationship: Book: Top level book */ +$handler->display->display_options['relationships']['bid']['id'] = 'bid'; +$handler->display->display_options['relationships']['bid']['table'] = 'book'; +$handler->display->display_options['relationships']['bid']['field'] = 'bid'; +$handler->display->display_options['relationships']['bid']['required'] = TRUE; +/* Relationship: Content: Author */ +$handler->display->display_options['relationships']['uid']['id'] = 'uid'; +$handler->display->display_options['relationships']['uid']['table'] = 'node'; +$handler->display->display_options['relationships']['uid']['field'] = 'uid'; +/* Field: Bulk operations: Content */ +$handler->display->display_options['fields']['views_bulk_operations']['id'] = 'views_bulk_operations'; +$handler->display->display_options['fields']['views_bulk_operations']['table'] = 'node'; +$handler->display->display_options['fields']['views_bulk_operations']['field'] = 'views_bulk_operations'; +$handler->display->display_options['fields']['views_bulk_operations']['label'] = ''; +$handler->display->display_options['fields']['views_bulk_operations']['element_label_colon'] = FALSE; +$handler->display->display_options['fields']['views_bulk_operations']['vbo']['entity_load_capacity'] = '10'; +$handler->display->display_options['fields']['views_bulk_operations']['vbo']['operations'] = array( + 'action::node_assign_owner_action' => array( + 'selected' => 1, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 1, + 'label' => 'Change author', + ), + 'action::views_bulk_operations_delete_item' => array( + 'selected' => 1, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 1, + 'label' => 'Delete', + ), + 'action::system_message_action' => array( + 'selected' => 0, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + ), + 'action::views_bulk_operations_script_action' => array( + 'selected' => 0, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + ), + 'action::node_make_sticky_action' => array( + 'selected' => 0, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + ), + 'action::node_make_unsticky_action' => array( + 'selected' => 0, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + ), + 'action::views_bulk_operations_modify_action' => array( + 'selected' => 1, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 1, + 'label' => 'Modify values', + 'settings' => array( + 'show_all_tokens' => 1, + 'display_values' => array( + '_all_' => '_all_', + ), + ), + ), + 'action::views_bulk_operations_argument_selector_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'settings' => array( + 'url' => '', + ), + ), + 'action::node_promote_action' => array( + 'selected' => 0, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + ), + 'action::node_publish_action' => array( + 'selected' => 1, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 1, + 'label' => 'Publish', + ), + 'action::system_goto_action' => array( + 'selected' => 0, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + ), + 'action::node_unpromote_action' => array( + 'selected' => 0, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + ), + 'action::node_save_action' => array( + 'selected' => 0, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + ), + 'action::system_send_email_action' => array( + 'selected' => 0, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + ), + 'action::node_unpublish_action' => array( + 'selected' => 1, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 1, + 'label' => 'Unpublish', + ), + 'action::node_unpublish_by_keyword_action' => array( + 'selected' => 0, + 'use_queue' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + ), +); +$handler->display->display_options['fields']['views_bulk_operations']['vbo']['enable_select_all_pages'] = 1; +$handler->display->display_options['fields']['views_bulk_operations']['vbo']['display_type'] = '0'; +$handler->display->display_options['fields']['views_bulk_operations']['vbo']['display_result'] = 1; +$handler->display->display_options['fields']['views_bulk_operations']['vbo']['force_single'] = 0; +/* Field: Content: Nid */ +$handler->display->display_options['fields']['nid']['id'] = 'nid'; +$handler->display->display_options['fields']['nid']['table'] = 'node'; +$handler->display->display_options['fields']['nid']['field'] = 'nid'; +$handler->display->display_options['fields']['nid']['label'] = ''; +$handler->display->display_options['fields']['nid']['exclude'] = TRUE; +$handler->display->display_options['fields']['nid']['element_label_colon'] = FALSE; +/* Field: Content: Title */ +$handler->display->display_options['fields']['title']['id'] = 'title'; +$handler->display->display_options['fields']['title']['table'] = 'node'; +$handler->display->display_options['fields']['title']['field'] = 'title'; +$handler->display->display_options['fields']['title']['label'] = 'Book'; +$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE; +$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE; +/* Field: Content: Has new content */ +$handler->display->display_options['fields']['timestamp']['id'] = 'timestamp'; +$handler->display->display_options['fields']['timestamp']['table'] = 'history'; +$handler->display->display_options['fields']['timestamp']['field'] = 'timestamp'; +$handler->display->display_options['fields']['timestamp']['label'] = ''; +$handler->display->display_options['fields']['timestamp']['element_label_colon'] = FALSE; +/* Field: User: Name */ +$handler->display->display_options['fields']['name']['id'] = 'name'; +$handler->display->display_options['fields']['name']['table'] = 'users'; +$handler->display->display_options['fields']['name']['field'] = 'name'; +$handler->display->display_options['fields']['name']['relationship'] = 'uid'; +$handler->display->display_options['fields']['name']['label'] = 'Author'; +/* Field: Content: Post date */ +$handler->display->display_options['fields']['created']['id'] = 'created'; +$handler->display->display_options['fields']['created']['table'] = 'node'; +$handler->display->display_options['fields']['created']['field'] = 'created'; +$handler->display->display_options['fields']['created']['date_format'] = 'short'; +/* Field: Content: Updated date */ +$handler->display->display_options['fields']['changed']['id'] = 'changed'; +$handler->display->display_options['fields']['changed']['table'] = 'node'; +$handler->display->display_options['fields']['changed']['field'] = 'changed'; +$handler->display->display_options['fields']['changed']['date_format'] = 'time ago'; +/* Field: Content: Published */ +$handler->display->display_options['fields']['status']['id'] = 'status'; +$handler->display->display_options['fields']['status']['table'] = 'node'; +$handler->display->display_options['fields']['status']['field'] = 'status'; +$handler->display->display_options['fields']['status']['label'] = 'Status'; +$handler->display->display_options['fields']['status']['type'] = 'published-notpublished'; +$handler->display->display_options['fields']['status']['not'] = 0; +/* Field: Global: Custom text */ +$handler->display->display_options['fields']['nothing']['id'] = 'nothing'; +$handler->display->display_options['fields']['nothing']['table'] = 'views'; +$handler->display->display_options['fields']['nothing']['field'] = 'nothing'; +$handler->display->display_options['fields']['nothing']['label'] = 'Operations'; +$handler->display->display_options['fields']['nothing']['alter']['text'] = 'edit order and titles'; +$handler->display->display_options['fields']['nothing']['alter']['make_link'] = TRUE; +$handler->display->display_options['fields']['nothing']['alter']['path'] = 'admin/content/book/[nid]?destination=admin/content/book'; +$handler->display->display_options['fields']['nothing']['element_label_colon'] = FALSE; +/* Sort criterion: Content: Post date */ +$handler->display->display_options['sorts']['created']['id'] = 'created'; +$handler->display->display_options['sorts']['created']['table'] = 'node'; +$handler->display->display_options['sorts']['created']['field'] = 'created'; +$handler->display->display_options['sorts']['created']['order'] = 'DESC'; +/* Filter criterion: Content: Published */ +$handler->display->display_options['filters']['status']['id'] = 'status'; +$handler->display->display_options['filters']['status']['table'] = 'node'; +$handler->display->display_options['filters']['status']['field'] = 'status'; +$handler->display->display_options['filters']['status']['value'] = 1; +$handler->display->display_options['filters']['status']['group'] = 1; +$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE; +/* Filter criterion: Book: Depth */ +$handler->display->display_options['filters']['depth']['id'] = 'depth'; +$handler->display->display_options['filters']['depth']['table'] = 'book_menu_links'; +$handler->display->display_options['filters']['depth']['field'] = 'depth'; +$handler->display->display_options['filters']['depth']['value']['value'] = '1'; +$handler->display->display_options['filters']['depth']['group'] = 1; +/* Filter criterion: Global: Combine fields filter */ +$handler->display->display_options['filters']['combine']['id'] = 'combine'; +$handler->display->display_options['filters']['combine']['table'] = 'views'; +$handler->display->display_options['filters']['combine']['field'] = 'combine'; +$handler->display->display_options['filters']['combine']['operator'] = 'contains'; +$handler->display->display_options['filters']['combine']['group'] = 1; +$handler->display->display_options['filters']['combine']['exposed'] = TRUE; +$handler->display->display_options['filters']['combine']['expose']['operator_id'] = 'combine_op'; +$handler->display->display_options['filters']['combine']['expose']['label'] = 'Title/node ID'; +$handler->display->display_options['filters']['combine']['expose']['description'] = 'Search by the node\'s title or ID.'; +$handler->display->display_options['filters']['combine']['expose']['operator'] = 'combine_op'; +$handler->display->display_options['filters']['combine']['expose']['identifier'] = 'combine'; +$handler->display->display_options['filters']['combine']['expose']['remember'] = TRUE; +$handler->display->display_options['filters']['combine']['fields'] = array( + 'nid' => 'nid', + 'title' => 'title', +); +/* Filter criterion: User: Name */ +$handler->display->display_options['filters']['uid']['id'] = 'uid'; +$handler->display->display_options['filters']['uid']['table'] = 'users'; +$handler->display->display_options['filters']['uid']['field'] = 'uid'; +$handler->display->display_options['filters']['uid']['relationship'] = 'uid'; +$handler->display->display_options['filters']['uid']['value'] = ''; +$handler->display->display_options['filters']['uid']['group'] = 1; +$handler->display->display_options['filters']['uid']['exposed'] = TRUE; +$handler->display->display_options['filters']['uid']['expose']['operator_id'] = 'uid_op'; +$handler->display->display_options['filters']['uid']['expose']['label'] = 'Author'; +$handler->display->display_options['filters']['uid']['expose']['operator'] = 'uid_op'; +$handler->display->display_options['filters']['uid']['expose']['identifier'] = 'uid'; +/* Filter criterion: Content: Published */ +$handler->display->display_options['filters']['status_1']['id'] = 'status_1'; +$handler->display->display_options['filters']['status_1']['table'] = 'node'; +$handler->display->display_options['filters']['status_1']['field'] = 'status'; +$handler->display->display_options['filters']['status_1']['value'] = 'All'; +$handler->display->display_options['filters']['status_1']['exposed'] = TRUE; +$handler->display->display_options['filters']['status_1']['expose']['operator_id'] = ''; +$handler->display->display_options['filters']['status_1']['expose']['label'] = 'Published'; +$handler->display->display_options['filters']['status_1']['expose']['operator'] = 'status_1_op'; +$handler->display->display_options['filters']['status_1']['expose']['identifier'] = 'status_1'; +$handler->display->display_options['filters']['status_1']['expose']['remember'] = TRUE; + +/* Display: System */ +$handler = $view->new_display('system', 'System', 'system_1'); +$handler->display->display_options['defaults']['hide_admin_links'] = FALSE; +$handler->display->display_options['hide_admin_links'] = TRUE; +$handler->display->display_options['defaults']['access'] = FALSE; +$handler->display->display_options['path'] = 'admin/content/book'; +$translatables['admin_views_book'] = array( + t('Master'), + t('Books'), + t('more'), + t('Apply'), + t('Reset'), + t('Sort by'), + t('Asc'), + t('Desc'), + t('Items per page'), + t('- All -'), + t('Offset'), + t('« first'), + t('‹ previous'), + t('next ›'), + t('last »'), + t('No books available.'), + t('Book'), + t('author'), + t('- Choose an operation -'), + t('Change author'), + t('Delete'), + t('Modify values'), + t('Publish'), + t('Unpublish'), + t('Author'), + t('Post date'), + t('Updated date'), + t('Status'), + t('Operations'), + t('edit order and titles'), + t('Title/node ID'), + t('Search by the node\'s title or ID.'), + t('Published'), + t('System'), +); diff --git a/dkan/modules/contrib/admin_views/admin_views_default/comment.admin-content-comment.inc b/dkan/modules/contrib/admin_views/admin_views_default/comment.admin-content-comment.inc new file mode 100644 index 000000000..30f1ea86d --- /dev/null +++ b/dkan/modules/contrib/admin_views/admin_views_default/comment.admin-content-comment.inc @@ -0,0 +1,384 @@ +name = 'admin_views_comment'; +$view->description = 'List and edit site comments and the comment moderation queue.'; +$view->tag = 'admin'; +$view->base_table = 'comment'; +$view->human_name = 'Administration: Comments'; +$view->core = 0; +$view->api_version = '3.0'; +$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + +/* Display: Defaults */ +$handler = $view->new_display('default', 'Defaults', 'default'); +$handler->display->display_options['title'] = 'Comments'; +$handler->display->display_options['css_class'] = 'admin-views-view'; +$handler->display->display_options['use_ajax'] = TRUE; +$handler->display->display_options['use_more_always'] = FALSE; +$handler->display->display_options['access']['type'] = 'menu'; +$handler->display->display_options['cache']['type'] = 'none'; +$handler->display->display_options['query']['type'] = 'views_query'; +$handler->display->display_options['query']['options']['query_comment'] = FALSE; +$handler->display->display_options['exposed_form']['type'] = 'basic'; +$handler->display->display_options['exposed_form']['options']['reset_button'] = TRUE; +$handler->display->display_options['pager']['type'] = 'full'; +$handler->display->display_options['pager']['options']['items_per_page'] = 50; +$handler->display->display_options['style_plugin'] = 'table'; +$handler->display->display_options['style_options']['columns'] = array( + 'views_bulk_operations' => 'views_bulk_operations', + 'subject' => 'subject', + 'name' => 'name', + 'title' => 'title', + 'timestamp' => 'timestamp', + 'edit_comment' => 'edit_comment', + 'delete_comment' => 'edit_comment', +); +$handler->display->display_options['style_options']['default'] = 'timestamp'; +$handler->display->display_options['style_options']['info'] = array( + 'views_bulk_operations' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'subject' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'name' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'title' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'timestamp' => array( + 'sortable' => 1, + 'default_sort_order' => 'desc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'edit_comment' => array( + 'align' => '', + 'separator' => ' ', + 'empty_column' => 0, + ), + 'delete_comment' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), +); +$handler->display->display_options['style_options']['sticky'] = TRUE; +$handler->display->display_options['style_options']['empty_table'] = TRUE; +/* No results behavior: Global: Unfiltered text */ +$handler->display->display_options['empty']['area_text_custom']['id'] = 'area_text_custom'; +$handler->display->display_options['empty']['area_text_custom']['table'] = 'views'; +$handler->display->display_options['empty']['area_text_custom']['field'] = 'area_text_custom'; +$handler->display->display_options['empty']['area_text_custom']['empty'] = TRUE; +$handler->display->display_options['empty']['area_text_custom']['content'] = 'No comments available.'; +/* Relationship: Comment: Content */ +$handler->display->display_options['relationships']['nid']['id'] = 'nid'; +$handler->display->display_options['relationships']['nid']['table'] = 'comment'; +$handler->display->display_options['relationships']['nid']['field'] = 'nid'; +$handler->display->display_options['relationships']['nid']['label'] = 'Node'; +/* Relationship: Comment: Author */ +$handler->display->display_options['relationships']['uid']['id'] = 'uid'; +$handler->display->display_options['relationships']['uid']['table'] = 'comment'; +$handler->display->display_options['relationships']['uid']['field'] = 'uid'; +/* Field: Bulk operations: Comment */ +$handler->display->display_options['fields']['views_bulk_operations']['id'] = 'views_bulk_operations'; +$handler->display->display_options['fields']['views_bulk_operations']['table'] = 'comment'; +$handler->display->display_options['fields']['views_bulk_operations']['field'] = 'views_bulk_operations'; +$handler->display->display_options['fields']['views_bulk_operations']['label'] = ''; +$handler->display->display_options['fields']['views_bulk_operations']['element_label_colon'] = FALSE; +$handler->display->display_options['fields']['views_bulk_operations']['hide_alter_empty'] = FALSE; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['display_type'] = '0'; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['enable_select_all_pages'] = 1; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['force_single'] = 0; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['entity_load_capacity'] = '10'; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_operations'] = array( + 'action::views_bulk_operations_delete_item' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Delete', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_modify_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Change value', + 'settings' => array( + 'show_all_tokens' => 1, + 'display_values' => array( + '_all_' => '_all_', + ), + ), + 'postpone_processing' => 0, + ), + 'action::system_message_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_script_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_argument_selector_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'settings' => array( + 'url' => '', + ), + ), + 'action::comment_publish_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Publish', + 'postpone_processing' => 0, + ), + 'action::system_goto_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::comment_save_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::system_send_email_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::comment_unpublish_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Unpublish', + 'postpone_processing' => 0, + ), + 'action::comment_unpublish_by_keyword_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), +); +/* Field: Comment: Title */ +$handler->display->display_options['fields']['subject']['id'] = 'subject'; +$handler->display->display_options['fields']['subject']['table'] = 'comment'; +$handler->display->display_options['fields']['subject']['field'] = 'subject'; +/* Field: Comment: Author */ +$handler->display->display_options['fields']['name']['id'] = 'name'; +$handler->display->display_options['fields']['name']['table'] = 'comment'; +$handler->display->display_options['fields']['name']['field'] = 'name'; +/* Field: Content: Title */ +$handler->display->display_options['fields']['title']['id'] = 'title'; +$handler->display->display_options['fields']['title']['table'] = 'node'; +$handler->display->display_options['fields']['title']['field'] = 'title'; +$handler->display->display_options['fields']['title']['relationship'] = 'nid'; +$handler->display->display_options['fields']['title']['label'] = 'Posted in'; +$handler->display->display_options['fields']['title']['alter']['max_length'] = '16'; +$handler->display->display_options['fields']['title']['alter']['trim'] = TRUE; +/* Field: Comment: Updated date */ +$handler->display->display_options['fields']['timestamp']['id'] = 'timestamp'; +$handler->display->display_options['fields']['timestamp']['table'] = 'comment'; +$handler->display->display_options['fields']['timestamp']['field'] = 'changed'; +$handler->display->display_options['fields']['timestamp']['label'] = 'Updated'; +$handler->display->display_options['fields']['timestamp']['hide_alter_empty'] = FALSE; +$handler->display->display_options['fields']['timestamp']['date_format'] = 'time ago'; +/* Field: Comment: Edit link */ +$handler->display->display_options['fields']['edit_comment']['id'] = 'edit_comment'; +$handler->display->display_options['fields']['edit_comment']['table'] = 'comment'; +$handler->display->display_options['fields']['edit_comment']['field'] = 'edit_comment'; +$handler->display->display_options['fields']['edit_comment']['label'] = 'Operations'; +/* Field: Comment: Delete link */ +$handler->display->display_options['fields']['delete_comment']['id'] = 'delete_comment'; +$handler->display->display_options['fields']['delete_comment']['table'] = 'comment'; +$handler->display->display_options['fields']['delete_comment']['field'] = 'delete_comment'; +$handler->display->display_options['fields']['delete_comment']['label'] = ''; +/* Sort criterion: Comment: Updated date */ +$handler->display->display_options['sorts']['timestamp']['id'] = 'timestamp'; +$handler->display->display_options['sorts']['timestamp']['table'] = 'comment'; +$handler->display->display_options['sorts']['timestamp']['field'] = 'changed'; +$handler->display->display_options['sorts']['timestamp']['order'] = 'DESC'; +/* Filter criterion: Comment: Title */ +$handler->display->display_options['filters']['subject']['id'] = 'subject'; +$handler->display->display_options['filters']['subject']['table'] = 'comment'; +$handler->display->display_options['filters']['subject']['field'] = 'subject'; +$handler->display->display_options['filters']['subject']['operator'] = 'contains'; +$handler->display->display_options['filters']['subject']['group'] = 1; +$handler->display->display_options['filters']['subject']['exposed'] = TRUE; +$handler->display->display_options['filters']['subject']['expose']['operator_id'] = 'subject_op'; +$handler->display->display_options['filters']['subject']['expose']['label'] = 'Title'; +$handler->display->display_options['filters']['subject']['expose']['operator'] = 'subject_op'; +$handler->display->display_options['filters']['subject']['expose']['identifier'] = 'subject'; +$handler->display->display_options['filters']['subject']['expose']['remember'] = TRUE; +/* Filter criterion: User: Name */ +$handler->display->display_options['filters']['uid']['id'] = 'uid'; +$handler->display->display_options['filters']['uid']['table'] = 'users'; +$handler->display->display_options['filters']['uid']['field'] = 'uid'; +$handler->display->display_options['filters']['uid']['relationship'] = 'uid'; +$handler->display->display_options['filters']['uid']['value'] = ''; +$handler->display->display_options['filters']['uid']['group'] = 1; +$handler->display->display_options['filters']['uid']['exposed'] = TRUE; +$handler->display->display_options['filters']['uid']['expose']['operator_id'] = 'uid_op'; +$handler->display->display_options['filters']['uid']['expose']['label'] = 'Author'; +$handler->display->display_options['filters']['uid']['expose']['operator'] = 'uid_op'; +$handler->display->display_options['filters']['uid']['expose']['identifier'] = 'author'; +$handler->display->display_options['filters']['uid']['expose']['remember'] = TRUE; +/* Filter criterion: Content: Title */ +$handler->display->display_options['filters']['title']['id'] = 'title'; +$handler->display->display_options['filters']['title']['table'] = 'node'; +$handler->display->display_options['filters']['title']['field'] = 'title'; +$handler->display->display_options['filters']['title']['relationship'] = 'nid'; +$handler->display->display_options['filters']['title']['operator'] = 'contains'; +$handler->display->display_options['filters']['title']['group'] = 1; +$handler->display->display_options['filters']['title']['exposed'] = TRUE; +$handler->display->display_options['filters']['title']['expose']['operator_id'] = 'title_op'; +$handler->display->display_options['filters']['title']['expose']['label'] = 'Posted in'; +$handler->display->display_options['filters']['title']['expose']['operator'] = 'title_op'; +$handler->display->display_options['filters']['title']['expose']['identifier'] = 'nodeTitle'; +$handler->display->display_options['filters']['title']['expose']['remember'] = TRUE; +/* Filter criterion: Comment: Approved */ +$handler->display->display_options['filters']['status']['id'] = 'status'; +$handler->display->display_options['filters']['status']['table'] = 'comment'; +$handler->display->display_options['filters']['status']['field'] = 'status'; +$handler->display->display_options['filters']['status']['value'] = 'All'; +$handler->display->display_options['filters']['status']['group'] = 1; +$handler->display->display_options['filters']['status']['exposed'] = TRUE; +$handler->display->display_options['filters']['status']['expose']['operator_id'] = ''; +$handler->display->display_options['filters']['status']['expose']['label'] = 'Published'; +$handler->display->display_options['filters']['status']['expose']['identifier'] = 'status'; +$handler->display->display_options['filters']['status']['expose']['remember'] = TRUE; + +/* Display: Comments */ +$handler = $view->new_display('system', 'Comments', 'system_1'); +$handler->display->display_options['defaults']['hide_admin_links'] = FALSE; +$handler->display->display_options['hide_admin_links'] = TRUE; +$handler->display->display_options['defaults']['access'] = FALSE; +$handler->display->display_options['path'] = 'admin/content/comment'; + +/* Display: Unpublished */ +$handler = $view->new_display('system', 'Unpublished', 'system_2'); +$handler->display->display_options['defaults']['hide_admin_links'] = FALSE; +$handler->display->display_options['hide_admin_links'] = TRUE; +$handler->display->display_options['defaults']['access'] = FALSE; +$handler->display->display_options['defaults']['filter_groups'] = FALSE; +$handler->display->display_options['defaults']['filters'] = FALSE; +/* Filter criterion: Comment: Title */ +$handler->display->display_options['filters']['subject']['id'] = 'subject'; +$handler->display->display_options['filters']['subject']['table'] = 'comment'; +$handler->display->display_options['filters']['subject']['field'] = 'subject'; +$handler->display->display_options['filters']['subject']['operator'] = 'contains'; +$handler->display->display_options['filters']['subject']['group'] = 1; +$handler->display->display_options['filters']['subject']['exposed'] = TRUE; +$handler->display->display_options['filters']['subject']['expose']['operator_id'] = 'subject_op'; +$handler->display->display_options['filters']['subject']['expose']['label'] = 'Title'; +$handler->display->display_options['filters']['subject']['expose']['operator'] = 'subject_op'; +$handler->display->display_options['filters']['subject']['expose']['identifier'] = 'subject'; +/* Filter criterion: User: Name */ +$handler->display->display_options['filters']['uid']['id'] = 'uid'; +$handler->display->display_options['filters']['uid']['table'] = 'users'; +$handler->display->display_options['filters']['uid']['field'] = 'uid'; +$handler->display->display_options['filters']['uid']['relationship'] = 'uid'; +$handler->display->display_options['filters']['uid']['value'] = ''; +$handler->display->display_options['filters']['uid']['group'] = 1; +$handler->display->display_options['filters']['uid']['exposed'] = TRUE; +$handler->display->display_options['filters']['uid']['expose']['operator_id'] = 'uid_op'; +$handler->display->display_options['filters']['uid']['expose']['label'] = 'Author'; +$handler->display->display_options['filters']['uid']['expose']['operator'] = 'uid_op'; +$handler->display->display_options['filters']['uid']['expose']['identifier'] = 'author'; +$handler->display->display_options['filters']['uid']['expose']['remember'] = TRUE; +/* Filter criterion: Content: Title */ +$handler->display->display_options['filters']['title']['id'] = 'title'; +$handler->display->display_options['filters']['title']['table'] = 'node'; +$handler->display->display_options['filters']['title']['field'] = 'title'; +$handler->display->display_options['filters']['title']['relationship'] = 'nid'; +$handler->display->display_options['filters']['title']['operator'] = 'contains'; +$handler->display->display_options['filters']['title']['group'] = 1; +$handler->display->display_options['filters']['title']['exposed'] = TRUE; +$handler->display->display_options['filters']['title']['expose']['operator_id'] = 'title_op'; +$handler->display->display_options['filters']['title']['expose']['label'] = 'Posted in'; +$handler->display->display_options['filters']['title']['expose']['operator'] = 'title_op'; +$handler->display->display_options['filters']['title']['expose']['identifier'] = 'nodeTitle'; +/* Filter criterion: Comment: Approved */ +$handler->display->display_options['filters']['status']['id'] = 'status'; +$handler->display->display_options['filters']['status']['table'] = 'comment'; +$handler->display->display_options['filters']['status']['field'] = 'status'; +$handler->display->display_options['filters']['status']['value'] = '0'; +$handler->display->display_options['filters']['status']['group'] = 1; +$handler->display->display_options['filters']['status']['exposed'] = TRUE; +$handler->display->display_options['filters']['status']['expose']['operator_id'] = ''; +$handler->display->display_options['filters']['status']['expose']['label'] = 'Published'; +$handler->display->display_options['filters']['status']['expose']['identifier'] = 'status'; +$handler->display->display_options['filters']['status']['expose']['remember'] = TRUE; +$handler->display->display_options['path'] = 'admin/content/comment/approval'; +$translatables['admin_views_comment'] = array( + t('Defaults'), + t('Comments'), + t('more'), + t('Apply'), + t('Reset'), + t('Sort by'), + t('Asc'), + t('Desc'), + t('Items per page'), + t('- All -'), + t('Offset'), + t('« first'), + t('‹ previous'), + t('next ›'), + t('last »'), + t('No comments available.'), + t('Node'), + t('author'), + t('- Choose an operation -'), + t('Delete'), + t('Change value'), + t('Publish'), + t('Unpublish'), + t('Title'), + t('Author'), + t('Posted in'), + t('Updated'), + t('Operations'), + t('Published'), + t('Unpublished'), +); diff --git a/dkan/modules/contrib/admin_views/admin_views_default/node.admin-content.inc b/dkan/modules/contrib/admin_views/admin_views_default/node.admin-content.inc new file mode 100644 index 000000000..d501c1889 --- /dev/null +++ b/dkan/modules/contrib/admin_views/admin_views_default/node.admin-content.inc @@ -0,0 +1,397 @@ +name = 'admin_views_node'; +$view->description = 'Find and manage content.'; +$view->tag = 'admin'; +$view->base_table = 'node'; +$view->human_name = 'Administration: Nodes'; +$view->core = 0; +$view->api_version = '3.0'; +$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + +/* Display: Defaults */ +$handler = $view->new_display('default', 'Defaults', 'default'); +$handler->display->display_options['title'] = 'Content'; +$handler->display->display_options['css_class'] = 'admin-views-view'; +$handler->display->display_options['use_ajax'] = TRUE; +$handler->display->display_options['use_more_always'] = FALSE; +$handler->display->display_options['access']['type'] = 'menu'; +$handler->display->display_options['cache']['type'] = 'none'; +$handler->display->display_options['query']['type'] = 'views_query'; +$handler->display->display_options['query']['options']['distinct'] = TRUE; +$handler->display->display_options['query']['options']['query_comment'] = FALSE; +$handler->display->display_options['exposed_form']['type'] = 'basic'; +$handler->display->display_options['exposed_form']['options']['reset_button'] = TRUE; +$handler->display->display_options['pager']['type'] = 'full'; +$handler->display->display_options['pager']['options']['items_per_page'] = 50; +$handler->display->display_options['style_plugin'] = 'table'; +$handler->display->display_options['style_options']['columns'] = array( + 'views_bulk_operations' => 'views_bulk_operations', + 'title' => 'title', + 'timestamp' => 'title', + 'type' => 'type', + 'name' => 'name', + 'status' => 'status', + 'changed' => 'changed', + 'edit_node' => 'edit_node', + 'delete_node' => 'edit_node', +); +$handler->display->display_options['style_options']['default'] = 'changed'; +$handler->display->display_options['style_options']['info'] = array( + 'views_bulk_operations' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'title' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => ' ', + 'empty_column' => 0, + ), + 'timestamp' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'type' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'name' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'status' => array( + 'sortable' => 1, + 'default_sort_order' => 'desc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'changed' => array( + 'sortable' => 1, + 'default_sort_order' => 'desc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'edit_node' => array( + 'align' => '', + 'separator' => ' ', + 'empty_column' => 0, + ), + 'delete_node' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), +); +$handler->display->display_options['style_options']['sticky'] = TRUE; +$handler->display->display_options['style_options']['empty_table'] = TRUE; +/* No results behavior: Global: Unfiltered text */ +$handler->display->display_options['empty']['area_text_custom']['id'] = 'area_text_custom'; +$handler->display->display_options['empty']['area_text_custom']['table'] = 'views'; +$handler->display->display_options['empty']['area_text_custom']['field'] = 'area_text_custom'; +$handler->display->display_options['empty']['area_text_custom']['empty'] = TRUE; +$handler->display->display_options['empty']['area_text_custom']['content'] = 'No content available.'; +/* Relationship: Content: Author */ +$handler->display->display_options['relationships']['uid']['id'] = 'uid'; +$handler->display->display_options['relationships']['uid']['table'] = 'node'; +$handler->display->display_options['relationships']['uid']['field'] = 'uid'; +/* Relationship: Content: Taxonomy terms on node */ +$handler->display->display_options['relationships']['term_node_tid']['id'] = 'term_node_tid'; +$handler->display->display_options['relationships']['term_node_tid']['table'] = 'node'; +$handler->display->display_options['relationships']['term_node_tid']['field'] = 'term_node_tid'; +$handler->display->display_options['relationships']['term_node_tid']['vocabularies'] = array( + 'forums' => 0, + 'tags' => 0, +); +/* Field: Bulk operations: Content */ +$handler->display->display_options['fields']['views_bulk_operations']['id'] = 'views_bulk_operations'; +$handler->display->display_options['fields']['views_bulk_operations']['table'] = 'node'; +$handler->display->display_options['fields']['views_bulk_operations']['field'] = 'views_bulk_operations'; +$handler->display->display_options['fields']['views_bulk_operations']['label'] = ''; +$handler->display->display_options['fields']['views_bulk_operations']['element_label_colon'] = FALSE; +$handler->display->display_options['fields']['views_bulk_operations']['hide_alter_empty'] = FALSE; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['display_type'] = '0'; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['enable_select_all_pages'] = 1; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['force_single'] = 0; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['entity_load_capacity'] = '10'; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_operations'] = array( + 'action::node_assign_owner_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Change author', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_delete_item' => array( + 'selected' => 1, + 'skip_confirmation' => 0, + 'override_label' => 1, + 'label' => 'Delete', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_modify_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Change value', + 'settings' => array( + 'show_all_tokens' => 1, + 'display_values' => array( + '_all_' => '_all_', + ), + ), + 'postpone_processing' => 0, + ), + 'action::system_message_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_script_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::node_make_sticky_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Stick', + 'postpone_processing' => 0, + ), + 'action::node_make_unsticky_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Unstick', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_argument_selector_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'settings' => array( + 'url' => '', + ), + ), + 'action::node_promote_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Promote to front page', + 'postpone_processing' => 0, + ), + 'action::node_publish_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Publish', + 'postpone_processing' => 0, + ), + 'action::system_goto_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::node_unpromote_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Demote from front page', + 'postpone_processing' => 0, + ), + 'action::node_save_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::system_send_email_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::node_unpublish_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Unpublish', + 'postpone_processing' => 0, + ), + 'action::node_unpublish_by_keyword_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), +); +/* Field: Content: Title */ +$handler->display->display_options['fields']['title']['id'] = 'title'; +$handler->display->display_options['fields']['title']['table'] = 'node'; +$handler->display->display_options['fields']['title']['field'] = 'title'; +/* Field: Content: Has new content */ +$handler->display->display_options['fields']['timestamp']['id'] = 'timestamp'; +$handler->display->display_options['fields']['timestamp']['table'] = 'history'; +$handler->display->display_options['fields']['timestamp']['field'] = 'timestamp'; +$handler->display->display_options['fields']['timestamp']['label'] = ''; +$handler->display->display_options['fields']['timestamp']['element_label_colon'] = FALSE; +/* Field: Content: Type */ +$handler->display->display_options['fields']['type']['id'] = 'type'; +$handler->display->display_options['fields']['type']['table'] = 'node'; +$handler->display->display_options['fields']['type']['field'] = 'type'; +/* Field: User: Name */ +$handler->display->display_options['fields']['name']['id'] = 'name'; +$handler->display->display_options['fields']['name']['table'] = 'users'; +$handler->display->display_options['fields']['name']['field'] = 'name'; +$handler->display->display_options['fields']['name']['relationship'] = 'uid'; +$handler->display->display_options['fields']['name']['label'] = 'Author'; +$handler->display->display_options['fields']['name']['hide_alter_empty'] = FALSE; +/* Field: Content: Published */ +$handler->display->display_options['fields']['status']['id'] = 'status'; +$handler->display->display_options['fields']['status']['table'] = 'node'; +$handler->display->display_options['fields']['status']['field'] = 'status'; +$handler->display->display_options['fields']['status']['not'] = 0; +/* Field: Content: Updated date */ +$handler->display->display_options['fields']['changed']['id'] = 'changed'; +$handler->display->display_options['fields']['changed']['table'] = 'node'; +$handler->display->display_options['fields']['changed']['field'] = 'changed'; +$handler->display->display_options['fields']['changed']['label'] = 'Updated'; +$handler->display->display_options['fields']['changed']['date_format'] = 'short'; +/* Field: Content: Edit link */ +$handler->display->display_options['fields']['edit_node']['id'] = 'edit_node'; +$handler->display->display_options['fields']['edit_node']['table'] = 'views_entity_node'; +$handler->display->display_options['fields']['edit_node']['field'] = 'edit_node'; +$handler->display->display_options['fields']['edit_node']['label'] = 'Operations'; +/* Field: Content: Delete link */ +$handler->display->display_options['fields']['delete_node']['id'] = 'delete_node'; +$handler->display->display_options['fields']['delete_node']['table'] = 'views_entity_node'; +$handler->display->display_options['fields']['delete_node']['field'] = 'delete_node'; +$handler->display->display_options['fields']['delete_node']['label'] = ''; +/* Filter criterion: Content: Title */ +$handler->display->display_options['filters']['title']['id'] = 'title'; +$handler->display->display_options['filters']['title']['table'] = 'node'; +$handler->display->display_options['filters']['title']['field'] = 'title'; +$handler->display->display_options['filters']['title']['operator'] = 'contains'; +$handler->display->display_options['filters']['title']['exposed'] = TRUE; +$handler->display->display_options['filters']['title']['expose']['operator_id'] = 'title_op'; +$handler->display->display_options['filters']['title']['expose']['label'] = 'Title'; +$handler->display->display_options['filters']['title']['expose']['operator'] = 'title_op'; +$handler->display->display_options['filters']['title']['expose']['identifier'] = 'title'; +$handler->display->display_options['filters']['title']['expose']['remember'] = TRUE; +/* Filter criterion: Content: Type */ +$handler->display->display_options['filters']['type']['id'] = 'type'; +$handler->display->display_options['filters']['type']['table'] = 'node'; +$handler->display->display_options['filters']['type']['field'] = 'type'; +$handler->display->display_options['filters']['type']['exposed'] = TRUE; +$handler->display->display_options['filters']['type']['expose']['operator_id'] = 'type_op'; +$handler->display->display_options['filters']['type']['expose']['label'] = 'Type'; +$handler->display->display_options['filters']['type']['expose']['operator'] = 'type_op'; +$handler->display->display_options['filters']['type']['expose']['identifier'] = 'type'; +$handler->display->display_options['filters']['type']['expose']['remember'] = TRUE; +/* Filter criterion: User: Name */ +$handler->display->display_options['filters']['uid']['id'] = 'uid'; +$handler->display->display_options['filters']['uid']['table'] = 'users'; +$handler->display->display_options['filters']['uid']['field'] = 'uid'; +$handler->display->display_options['filters']['uid']['relationship'] = 'uid'; +$handler->display->display_options['filters']['uid']['value'] = ''; +$handler->display->display_options['filters']['uid']['exposed'] = TRUE; +$handler->display->display_options['filters']['uid']['expose']['operator_id'] = 'uid_op'; +$handler->display->display_options['filters']['uid']['expose']['label'] = 'Author'; +$handler->display->display_options['filters']['uid']['expose']['operator'] = 'uid_op'; +$handler->display->display_options['filters']['uid']['expose']['identifier'] = 'author'; +$handler->display->display_options['filters']['uid']['expose']['remember'] = TRUE; +/* Filter criterion: Content: Published */ +$handler->display->display_options['filters']['status']['id'] = 'status'; +$handler->display->display_options['filters']['status']['table'] = 'node'; +$handler->display->display_options['filters']['status']['field'] = 'status'; +$handler->display->display_options['filters']['status']['value'] = 'All'; +$handler->display->display_options['filters']['status']['exposed'] = TRUE; +$handler->display->display_options['filters']['status']['expose']['operator_id'] = ''; +$handler->display->display_options['filters']['status']['expose']['label'] = 'Published'; +$handler->display->display_options['filters']['status']['expose']['operator'] = 'status_op'; +$handler->display->display_options['filters']['status']['expose']['identifier'] = 'status'; +$handler->display->display_options['filters']['status']['expose']['remember'] = TRUE; +/* Filter criterion: Taxonomy term: Vocabulary */ +$handler->display->display_options['filters']['vid']['id'] = 'vid'; +$handler->display->display_options['filters']['vid']['table'] = 'taxonomy_term_data'; +$handler->display->display_options['filters']['vid']['field'] = 'vid'; +$handler->display->display_options['filters']['vid']['relationship'] = 'term_node_tid'; +$handler->display->display_options['filters']['vid']['exposed'] = TRUE; +$handler->display->display_options['filters']['vid']['expose']['operator_id'] = 'vid_op'; +$handler->display->display_options['filters']['vid']['expose']['label'] = 'Vocabulary'; +$handler->display->display_options['filters']['vid']['expose']['operator'] = 'vid_op'; +$handler->display->display_options['filters']['vid']['expose']['identifier'] = 'vid'; +$handler->display->display_options['filters']['vid']['expose']['remember'] = TRUE; + +/* Display: System */ +$handler = $view->new_display('system', 'System', 'system_1'); +$handler->display->display_options['defaults']['hide_admin_links'] = FALSE; +$handler->display->display_options['hide_admin_links'] = TRUE; +$handler->display->display_options['defaults']['access'] = FALSE; +$handler->display->display_options['path'] = 'admin/content'; +$translatables['admin_views_node'] = array( + t('Defaults'), + t('Content'), + t('more'), + t('Apply'), + t('Reset'), + t('Sort by'), + t('Asc'), + t('Desc'), + t('Items per page'), + t('- All -'), + t('Offset'), + t('« first'), + t('‹ previous'), + t('next ›'), + t('last »'), + t('No content available.'), + t('author'), + t('term'), + t('- Choose an operation -'), + t('Change author'), + t('Delete'), + t('Change value'), + t('Stick'), + t('Unstick'), + t('Promote to front page'), + t('Publish'), + t('Demote from front page'), + t('Unpublish'), + t('Title'), + t('Type'), + t('Author'), + t('Published'), + t('Updated'), + t('Operations'), + t('Vocabulary'), + t('System'), +); diff --git a/dkan/modules/contrib/admin_views/admin_views_default/taxonomy.admin-content-taxonomy.inc b/dkan/modules/contrib/admin_views/admin_views_default/taxonomy.admin-content-taxonomy.inc new file mode 100644 index 000000000..990e8381c --- /dev/null +++ b/dkan/modules/contrib/admin_views/admin_views_default/taxonomy.admin-content-taxonomy.inc @@ -0,0 +1,152 @@ +name = 'admin_views_taxonomy_term'; +$view->description = 'Manage tagging, categorization, and classification of your content.'; +$view->tag = 'admin'; +$view->base_table = 'taxonomy_term_data'; +$view->human_name = 'Administration: Taxonomy terms'; +$view->core = 0; +$view->api_version = '3.0'; +$view->disabled = TRUE; /* Edit this to true to make a default view disabled initially */ + +/* Display: Defaults */ +$handler = $view->new_display('default', 'Defaults', 'default'); +$handler->display->display_options['title'] = 'Terms'; +$handler->display->display_options['use_ajax'] = TRUE; +$handler->display->display_options['use_more_always'] = FALSE; +$handler->display->display_options['access']['type'] = 'menu'; +$handler->display->display_options['cache']['type'] = 'none'; +$handler->display->display_options['query']['type'] = 'views_query'; +$handler->display->display_options['exposed_form']['type'] = 'basic'; +$handler->display->display_options['exposed_form']['options']['reset_button'] = TRUE; +$handler->display->display_options['pager']['type'] = 'none'; +$handler->display->display_options['style_plugin'] = 'table'; +$handler->display->display_options['style_options']['columns'] = array( + 'name_1' => 'name_1', + 'name' => 'name', + 'tid' => 'tid', +); +$handler->display->display_options['style_options']['default'] = 'name'; +$handler->display->display_options['style_options']['info'] = array( + 'name_1' => array( + 'sortable' => 0, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'name' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'tid' => array( + 'sortable' => 0, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), +); +$handler->display->display_options['style_options']['sticky'] = TRUE; +/* Field: Taxonomy vocabulary: Name */ +$handler->display->display_options['fields']['name_1']['id'] = 'name_1'; +$handler->display->display_options['fields']['name_1']['table'] = 'taxonomy_vocabulary'; +$handler->display->display_options['fields']['name_1']['field'] = 'name'; +$handler->display->display_options['fields']['name_1']['label'] = ''; +$handler->display->display_options['fields']['name_1']['exclude'] = TRUE; +/* Field: Taxonomy term: Name */ +$handler->display->display_options['fields']['name']['id'] = 'name'; +$handler->display->display_options['fields']['name']['table'] = 'taxonomy_term_data'; +$handler->display->display_options['fields']['name']['field'] = 'name'; +$handler->display->display_options['fields']['name']['label'] = 'Term'; +$handler->display->display_options['fields']['name']['link_to_taxonomy'] = TRUE; +/* Field: Taxonomy term: Term ID */ +$handler->display->display_options['fields']['tid']['id'] = 'tid'; +$handler->display->display_options['fields']['tid']['table'] = 'taxonomy_term_data'; +$handler->display->display_options['fields']['tid']['field'] = 'tid'; +$handler->display->display_options['fields']['tid']['label'] = 'Operations'; +$handler->display->display_options['fields']['tid']['alter']['alter_text'] = TRUE; +$handler->display->display_options['fields']['tid']['alter']['text'] = 'edit'; +$handler->display->display_options['fields']['tid']['alter']['make_link'] = TRUE; +$handler->display->display_options['fields']['tid']['alter']['path'] = 'taxonomy/term/[tid]/edit'; +$handler->display->display_options['fields']['tid']['separator'] = ''; +/* Sort criterion: Taxonomy term: Weight */ +$handler->display->display_options['sorts']['weight']['id'] = 'weight'; +$handler->display->display_options['sorts']['weight']['table'] = 'taxonomy_term_data'; +$handler->display->display_options['sorts']['weight']['field'] = 'weight'; +/* Sort criterion: Taxonomy term: Name */ +$handler->display->display_options['sorts']['name']['id'] = 'name'; +$handler->display->display_options['sorts']['name']['table'] = 'taxonomy_term_data'; +$handler->display->display_options['sorts']['name']['field'] = 'name'; +/* Contextual filter: Taxonomy vocabulary: Machine name */ +$handler->display->display_options['arguments']['machine_name']['id'] = 'machine_name'; +$handler->display->display_options['arguments']['machine_name']['table'] = 'taxonomy_vocabulary'; +$handler->display->display_options['arguments']['machine_name']['field'] = 'machine_name'; +$handler->display->display_options['arguments']['machine_name']['title_enable'] = TRUE; +$handler->display->display_options['arguments']['machine_name']['title'] = 'Terms in %1'; +$handler->display->display_options['arguments']['machine_name']['breadcrumb_enable'] = TRUE; +$handler->display->display_options['arguments']['machine_name']['breadcrumb'] = '%1'; +$handler->display->display_options['arguments']['machine_name']['default_argument_type'] = 'fixed'; +$handler->display->display_options['arguments']['machine_name']['summary']['number_of_records'] = '0'; +$handler->display->display_options['arguments']['machine_name']['summary']['format'] = 'default_summary'; +$handler->display->display_options['arguments']['machine_name']['summary_options']['items_per_page'] = '25'; +$handler->display->display_options['arguments']['machine_name']['specify_validation'] = TRUE; +$handler->display->display_options['arguments']['machine_name']['validate']['fail'] = 'ignore'; +$handler->display->display_options['arguments']['machine_name']['limit'] = '0'; +/* Filter criterion: Taxonomy term: Vocabulary */ +$handler->display->display_options['filters']['vid']['id'] = 'vid'; +$handler->display->display_options['filters']['vid']['table'] = 'taxonomy_term_data'; +$handler->display->display_options['filters']['vid']['field'] = 'vid'; +$handler->display->display_options['filters']['vid']['group'] = '0'; +$handler->display->display_options['filters']['vid']['exposed'] = TRUE; +$handler->display->display_options['filters']['vid']['expose']['operator_id'] = 'vid_op'; +$handler->display->display_options['filters']['vid']['expose']['label'] = 'Vocabulary'; +$handler->display->display_options['filters']['vid']['expose']['operator'] = 'vid_op'; +$handler->display->display_options['filters']['vid']['expose']['identifier'] = 'vid'; +$handler->display->display_options['filters']['vid']['expose']['remember'] = TRUE; +/* Filter criterion: Taxonomy term: Name */ +$handler->display->display_options['filters']['name']['id'] = 'name'; +$handler->display->display_options['filters']['name']['table'] = 'taxonomy_term_data'; +$handler->display->display_options['filters']['name']['field'] = 'name'; +$handler->display->display_options['filters']['name']['operator'] = 'word'; +$handler->display->display_options['filters']['name']['exposed'] = TRUE; +$handler->display->display_options['filters']['name']['expose']['operator_id'] = 'name_op'; +$handler->display->display_options['filters']['name']['expose']['label'] = 'Name'; +$handler->display->display_options['filters']['name']['expose']['operator'] = 'name_op'; +$handler->display->display_options['filters']['name']['expose']['identifier'] = 'name'; +$handler->display->display_options['filters']['name']['expose']['remember'] = TRUE; + +/* Display: System */ +$handler = $view->new_display('system', 'System', 'system_1'); +$handler->display->display_options['defaults']['hide_admin_links'] = FALSE; +$handler->display->display_options['defaults']['access'] = FALSE; +$handler->display->display_options['path'] = 'admin/structure/taxonomy/%'; +$translatables['admin_views_taxonomy_term'] = array( + t('Defaults'), + t('Terms'), + t('more'), + t('Apply'), + t('Reset'), + t('Sort by'), + t('Asc'), + t('Desc'), + t('Term'), + t('Operations'), + t('edit'), + t('.'), + t('All'), + t('Terms in %1'), + t('%1'), + t('Vocabulary'), + t('Name'), + t('System'), +); diff --git a/dkan/modules/contrib/admin_views/admin_views_default/user.admin-people.inc b/dkan/modules/contrib/admin_views/admin_views_default/user.admin-people.inc new file mode 100644 index 000000000..dcef73508 --- /dev/null +++ b/dkan/modules/contrib/admin_views/admin_views_default/user.admin-people.inc @@ -0,0 +1,353 @@ +name = 'admin_views_user'; +$view->description = 'List, add, and edit users.'; +$view->tag = 'admin'; +$view->base_table = 'users'; +$view->human_name = 'Administration: Users'; +$view->core = 0; +$view->api_version = '3.0'; +$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + +/* Display: Defaults */ +$handler = $view->new_display('default', 'Defaults', 'default'); +$handler->display->display_options['title'] = 'Users'; +$handler->display->display_options['css_class'] = 'admin-views-view'; +$handler->display->display_options['use_ajax'] = TRUE; +$handler->display->display_options['use_more_always'] = FALSE; +$handler->display->display_options['access']['type'] = 'menu'; +$handler->display->display_options['cache']['type'] = 'none'; +$handler->display->display_options['query']['type'] = 'views_query'; +$handler->display->display_options['query']['options']['query_comment'] = FALSE; +$handler->display->display_options['exposed_form']['type'] = 'basic'; +$handler->display->display_options['exposed_form']['options']['reset_button'] = TRUE; +$handler->display->display_options['pager']['type'] = 'full'; +$handler->display->display_options['pager']['options']['items_per_page'] = 50; +$handler->display->display_options['style_plugin'] = 'table'; +$handler->display->display_options['style_options']['columns'] = array( + 'views_bulk_operations' => 'views_bulk_operations', + 'name' => 'name', + 'mail' => 'name', + 'status' => 'status', + 'rid' => 'rid', + 'created' => 'created', + 'access' => 'access', + 'edit_node' => 'edit_node', + 'cancel_node' => 'edit_node', +); +$handler->display->display_options['style_options']['default'] = 'access'; +$handler->display->display_options['style_options']['info'] = array( + 'views_bulk_operations' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'name' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '
', + 'empty_column' => 0, + ), + 'mail' => array( + 'sortable' => 0, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'status' => array( + 'sortable' => 1, + 'default_sort_order' => 'desc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'rid' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'created' => array( + 'sortable' => 1, + 'default_sort_order' => 'desc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'access' => array( + 'sortable' => 1, + 'default_sort_order' => 'desc', + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), + 'edit_node' => array( + 'align' => '', + 'separator' => ' ', + 'empty_column' => 0, + ), + 'cancel_node' => array( + 'align' => '', + 'separator' => '', + 'empty_column' => 0, + ), +); +$handler->display->display_options['style_options']['sticky'] = TRUE; +$handler->display->display_options['style_options']['empty_table'] = TRUE; +/* No results behavior: Global: Unfiltered text */ +$handler->display->display_options['empty']['area_text_custom']['id'] = 'area_text_custom'; +$handler->display->display_options['empty']['area_text_custom']['table'] = 'views'; +$handler->display->display_options['empty']['area_text_custom']['field'] = 'area_text_custom'; +$handler->display->display_options['empty']['area_text_custom']['empty'] = TRUE; +$handler->display->display_options['empty']['area_text_custom']['content'] = 'No users available.'; +/* Field: Bulk operations: User */ +$handler->display->display_options['fields']['views_bulk_operations']['id'] = 'views_bulk_operations'; +$handler->display->display_options['fields']['views_bulk_operations']['table'] = 'users'; +$handler->display->display_options['fields']['views_bulk_operations']['field'] = 'views_bulk_operations'; +$handler->display->display_options['fields']['views_bulk_operations']['label'] = ''; +$handler->display->display_options['fields']['views_bulk_operations']['element_label_colon'] = FALSE; +$handler->display->display_options['fields']['views_bulk_operations']['hide_alter_empty'] = FALSE; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['display_type'] = '0'; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['enable_select_all_pages'] = 1; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['force_single'] = 0; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['entity_load_capacity'] = '10'; +$handler->display->display_options['fields']['views_bulk_operations']['vbo_operations'] = array( + 'action::system_block_ip_action' => array( + 'selected' => 0, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Ban IP address of the current user', + 'postpone_processing' => 0, + ), + 'action::user_block_user_action' => array( + 'selected' => 0, + 'skip_confirmation' => 1, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_user_cancel_action' => array( + 'selected' => 1, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_delete_item' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 1, + 'label' => 'Delete', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_modify_action' => array( + 'selected' => 1, + 'skip_confirmation' => 1, + 'override_label' => 1, + 'label' => 'Change value', + 'settings' => array( + 'show_all_tokens' => 1, + 'display_values' => array( + '_all_' => '_all_', + ), + ), + 'postpone_processing' => 0, + ), + 'action::system_message_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_script_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_user_roles_action' => array( + 'selected' => 1, + 'skip_confirmation' => 0, + 'override_label' => 1, + 'label' => 'Change user roles', + 'postpone_processing' => 0, + ), + 'action::views_bulk_operations_argument_selector_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'settings' => array( + 'url' => '', + ), + ), + 'action::system_goto_action' => array( + 'selected' => 0, + 'skip_confirmation' => 0, + 'override_label' => 0, + 'label' => '', + 'postpone_processing' => 0, + ), + 'action::system_send_email_action' => array( + 'selected' => 1, + 'skip_confirmation' => 0, + 'override_label' => 1, + 'label' => 'Send e-mail', + 'postpone_processing' => 0, + ), +); +/* Field: User: Name */ +$handler->display->display_options['fields']['name']['id'] = 'name'; +$handler->display->display_options['fields']['name']['table'] = 'users'; +$handler->display->display_options['fields']['name']['field'] = 'name'; +/* Field: User: E-mail */ +$handler->display->display_options['fields']['mail']['id'] = 'mail'; +$handler->display->display_options['fields']['mail']['table'] = 'users'; +$handler->display->display_options['fields']['mail']['field'] = 'mail'; +$handler->display->display_options['fields']['mail']['label'] = ''; +$handler->display->display_options['fields']['mail']['element_label_colon'] = FALSE; +$handler->display->display_options['fields']['mail']['link_to_user'] = '0'; +/* Field: User: Active */ +$handler->display->display_options['fields']['status']['id'] = 'status'; +$handler->display->display_options['fields']['status']['table'] = 'users'; +$handler->display->display_options['fields']['status']['field'] = 'status'; +$handler->display->display_options['fields']['status']['not'] = 0; +/* Field: User: Roles */ +$handler->display->display_options['fields']['rid']['id'] = 'rid'; +$handler->display->display_options['fields']['rid']['table'] = 'users_roles'; +$handler->display->display_options['fields']['rid']['field'] = 'rid'; +$handler->display->display_options['fields']['rid']['type'] = 'ul'; +/* Field: User: Created date */ +$handler->display->display_options['fields']['created']['id'] = 'created'; +$handler->display->display_options['fields']['created']['table'] = 'users'; +$handler->display->display_options['fields']['created']['field'] = 'created'; +$handler->display->display_options['fields']['created']['label'] = 'Member for'; +$handler->display->display_options['fields']['created']['date_format'] = 'raw time ago'; +/* Field: User: Last access */ +$handler->display->display_options['fields']['access']['id'] = 'access'; +$handler->display->display_options['fields']['access']['table'] = 'users'; +$handler->display->display_options['fields']['access']['field'] = 'access'; +$handler->display->display_options['fields']['access']['date_format'] = 'time ago'; +/* Field: User: Edit link */ +$handler->display->display_options['fields']['edit_node']['id'] = 'edit_node'; +$handler->display->display_options['fields']['edit_node']['table'] = 'users'; +$handler->display->display_options['fields']['edit_node']['field'] = 'edit_node'; +$handler->display->display_options['fields']['edit_node']['label'] = 'Operations'; +/* Field: User: Cancel link */ +$handler->display->display_options['fields']['cancel_node']['id'] = 'cancel_node'; +$handler->display->display_options['fields']['cancel_node']['table'] = 'users'; +$handler->display->display_options['fields']['cancel_node']['field'] = 'cancel_node'; +$handler->display->display_options['fields']['cancel_node']['label'] = ''; +$handler->display->display_options['fields']['cancel_node']['element_label_colon'] = FALSE; +$handler->display->display_options['fields']['cancel_node']['hide_alter_empty'] = FALSE; +/* Sort criterion: User: Created date */ +$handler->display->display_options['sorts']['created']['id'] = 'created'; +$handler->display->display_options['sorts']['created']['table'] = 'users'; +$handler->display->display_options['sorts']['created']['field'] = 'created'; +$handler->display->display_options['sorts']['created']['order'] = 'DESC'; +/* Filter criterion: User: Name */ +$handler->display->display_options['filters']['uid']['id'] = 'uid'; +$handler->display->display_options['filters']['uid']['table'] = 'users'; +$handler->display->display_options['filters']['uid']['field'] = 'uid'; +$handler->display->display_options['filters']['uid']['operator'] = 'not in'; +$handler->display->display_options['filters']['uid']['value'] = array( + 0 => 0, +); +$handler->display->display_options['filters']['uid']['group'] = 1; +/* Filter criterion: User: Name (raw) */ +$handler->display->display_options['filters']['name']['id'] = 'name'; +$handler->display->display_options['filters']['name']['table'] = 'users'; +$handler->display->display_options['filters']['name']['field'] = 'name'; +$handler->display->display_options['filters']['name']['operator'] = 'contains'; +$handler->display->display_options['filters']['name']['group'] = 1; +$handler->display->display_options['filters']['name']['exposed'] = TRUE; +$handler->display->display_options['filters']['name']['expose']['operator_id'] = 'name_op'; +$handler->display->display_options['filters']['name']['expose']['label'] = 'Username'; +$handler->display->display_options['filters']['name']['expose']['operator'] = 'name_op'; +$handler->display->display_options['filters']['name']['expose']['identifier'] = 'name'; +$handler->display->display_options['filters']['name']['expose']['remember'] = TRUE; +/* Filter criterion: User: E-mail */ +$handler->display->display_options['filters']['mail']['id'] = 'mail'; +$handler->display->display_options['filters']['mail']['table'] = 'users'; +$handler->display->display_options['filters']['mail']['field'] = 'mail'; +$handler->display->display_options['filters']['mail']['operator'] = 'contains'; +$handler->display->display_options['filters']['mail']['group'] = 1; +$handler->display->display_options['filters']['mail']['exposed'] = TRUE; +$handler->display->display_options['filters']['mail']['expose']['operator_id'] = 'mail_op'; +$handler->display->display_options['filters']['mail']['expose']['label'] = 'E-mail'; +$handler->display->display_options['filters']['mail']['expose']['operator'] = 'mail_op'; +$handler->display->display_options['filters']['mail']['expose']['identifier'] = 'mail'; +$handler->display->display_options['filters']['mail']['expose']['remember'] = TRUE; +/* Filter criterion: User: Active */ +$handler->display->display_options['filters']['status']['id'] = 'status'; +$handler->display->display_options['filters']['status']['table'] = 'users'; +$handler->display->display_options['filters']['status']['field'] = 'status'; +$handler->display->display_options['filters']['status']['value'] = 'All'; +$handler->display->display_options['filters']['status']['group'] = 1; +$handler->display->display_options['filters']['status']['exposed'] = TRUE; +$handler->display->display_options['filters']['status']['expose']['operator_id'] = ''; +$handler->display->display_options['filters']['status']['expose']['label'] = 'Active'; +$handler->display->display_options['filters']['status']['expose']['operator'] = 'status_op'; +$handler->display->display_options['filters']['status']['expose']['identifier'] = 'status'; +$handler->display->display_options['filters']['status']['expose']['remember'] = TRUE; +/* Filter criterion: User: Roles */ +$handler->display->display_options['filters']['rid']['id'] = 'rid'; +$handler->display->display_options['filters']['rid']['table'] = 'users_roles'; +$handler->display->display_options['filters']['rid']['field'] = 'rid'; +$handler->display->display_options['filters']['rid']['group'] = 1; +$handler->display->display_options['filters']['rid']['exposed'] = TRUE; +$handler->display->display_options['filters']['rid']['expose']['operator_id'] = 'rid_op'; +$handler->display->display_options['filters']['rid']['expose']['label'] = 'Role'; +$handler->display->display_options['filters']['rid']['expose']['operator'] = 'rid_op'; +$handler->display->display_options['filters']['rid']['expose']['identifier'] = 'rid'; +$handler->display->display_options['filters']['rid']['expose']['remember'] = TRUE; + +/* Display: System */ +$handler = $view->new_display('system', 'System', 'system_1'); +$handler->display->display_options['defaults']['hide_admin_links'] = FALSE; +$handler->display->display_options['hide_admin_links'] = TRUE; +$handler->display->display_options['defaults']['access'] = FALSE; +$handler->display->display_options['path'] = 'admin/people'; +$translatables['admin_views_user'] = array( + t('Defaults'), + t('Users'), + t('more'), + t('Apply'), + t('Reset'), + t('Sort by'), + t('Asc'), + t('Desc'), + t('Items per page'), + t('- All -'), + t('Offset'), + t('« first'), + t('‹ previous'), + t('next ›'), + t('last »'), + t('No users available.'), + t('- Choose an operation -'), + t('Ban IP address of the current user'), + t('Delete'), + t('Change value'), + t('Change user roles'), + t('Send e-mail'), + t('Name'), + t('Active'), + t('Roles'), + t('Member for'), + t('Last access'), + t('Operations'), + t('Username'), + t('E-mail'), + t('Role'), + t('System'), +); diff --git a/dkan/modules/contrib/admin_views/plugins/views_plugin_access_menu.inc b/dkan/modules/contrib/admin_views/plugins/views_plugin_access_menu.inc new file mode 100644 index 000000000..79a2e93f3 --- /dev/null +++ b/dkan/modules/contrib/admin_views/plugins/views_plugin_access_menu.inc @@ -0,0 +1,41 @@ +display->handler->get_option('path'); + + if (empty($path)) { + return FALSE; + } + + $item = menu_get_item($path); + + // If we are on the original router path, the menu system has checked access already. + if ($item['href'] == $_GET['q']) { + return TRUE; + } + + return $item['access']; + } +} diff --git a/dkan/modules/contrib/admin_views/plugins/views_plugin_display_system.inc b/dkan/modules/contrib/admin_views/plugins/views_plugin_display_system.inc new file mode 100644 index 000000000..41d118153 --- /dev/null +++ b/dkan/modules/contrib/admin_views/plugins/views_plugin_display_system.inc @@ -0,0 +1,362 @@ + '', + ); + + // Override the access plugin to always enforce views_plugin_access_menu. + // The UI widget for configuring access is additionally hidden. + // @see options_summary() + $options['defaults']['default']['access'] = FALSE; + $options['access'] = array( + 'default' => array( + 'type' => 'menu', + ), + ); + + return $options; + } + + /** + * Overrides views_plugin_display::options_summary(). + */ + function options_summary(&$categories, &$options) { + parent::options_summary($categories, $options); + + $categories['system'] = array( + 'title' => t('System path settings'), + ); + + // Disable the access plugin configuration in the UI. + // @see option_definition() + $categories['access']['build']['#access'] = FALSE; + + $path = strip_tags('/' . $this->get_option('path')); + if (empty($path)) { + $path = t('None'); + } + + $options['path'] = array( + 'category' => 'system', + 'title' => t('Path'), + 'value' => views_ui_truncate($path, 24), + ); + } + + /** + * Overrides views_plugin_display::options_form(). + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + switch ($form_state['section']) { + case 'path': + $form['#title'] .= t('An existing menu path this view replaces'); + $form['path'] = array( + '#type' => 'textfield', + '#description' => t('This view replaces this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters. For example: "node/%/feed". The path must not be used by another enabled system view, otherwise conflicts will occur and user_access() notices displayed.'), + '#default_value' => $this->get_option('path'), + '#field_prefix' => '' . url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='), + '#field_suffix' => '‎', + '#attributes' => array('dir' => 'ltr'), + ); + break; + } + } + + /** + * Overrides views_plugin_display::options_validate(). + */ + function options_validate(&$form, &$form_state) { + parent::options_validate($form, $form_state); + + switch ($form_state['section']) { + case 'path': + if (strpos($form_state['values']['path'], '$arg') !== FALSE) { + form_error($form['path'], t('"$arg" is no longer supported. Use % instead.')); + } + + if (strpos($form_state['values']['path'], '%') === 0) { + form_error($form['path'], t('"%" may not be used for the first segment of a path.')); + } + // Automatically remove '/' from path. + $form_state['values']['path'] = trim($form_state['values']['path'], '/'); + + $system_view[$form_state['values']['path']] = array($this->view->name => $this->view->current_display); + if (admin_views_duplicate_path($system_view)) { + form_error($form['path'], t('Already used by another system view. Enter a different path.')); + } + break; + } + } + + /** + * Overrides views_plugin_display::options_submit(). + */ + function options_submit(&$form, &$form_state) { + parent::options_submit($form, $form_state); + + switch ($form_state['section']) { + case 'path': + $this->set_option('path', $form_state['values']['path']); + break; + } + } + + /** + * Add this display's path information to Drupal's menu system. + * + * @param array $callbacks + * All existing menu router items defined by modules. Taken by reference, in + * order to adjust any possibly existing child router items of the replaced + * system path. (This method only returns new router items normally.) + */ + function execute_hook_menu(&$callbacks) { + $items = array(); + + // Replace % with the link to our standard views argument loader + // views_arg_load(). + $bits = explode('/', $this->get_option('path')); + $page_arguments = array($this->view->name, $this->display->id); + $this->view->init_handlers(); + $view_arguments = $this->view->argument; + + // Replace % with %views_arg for menu autoloading and add to the + // page arguments so the argument actually comes through. + foreach ($bits as $pos => $bit) { + if ($bit == '%') { + $argument = array_shift($view_arguments); + if (!empty($argument->options['specify_validation']) && $argument->options['validate']['type'] != 'none') { + $bits[$pos] = '%views_arg'; + } + $page_arguments[] = $pos; + } + } + + $path = implode('/', $bits); + if (!$path) { + return $items; + } + + // Only existing system paths can be replaced. + if (!isset($callbacks[$path])) { + // However, if the specified path contains dynamic argument placeholders, + // then we need to search more carefully. + $views_path = $this->get_option('path'); + if (strpos($views_path, '%') !== FALSE) { + $views_path = preg_quote($views_path, '@'); + $views_path = strtr($views_path, array('%' => '%[^/]*')); + $result = preg_grep('@^' . $views_path . '$@', array_keys($callbacks)); + if ($result) { + $parent_path = reset($result); + $parent = &$callbacks[$parent_path]; + } + else { + return $items; + } + } + // No dynamic placeholders found, so nothing can be replaced. + else { + return $items; + } + } + else { + $parent = &$callbacks[$path]; + } + + // Work out whether we need to get the access callback and arguments from + // the parent item. + $default_map = array( + 'access callback' => 'user_access', + 'access arguments' => array(), + ); + + foreach ($default_map as $menu_key => &$default) { + // Override the default if we can. Otherwise this will use the defaults + // above. + if (!empty($callbacks[$path][$menu_key])) { + $default = $callbacks[$path][$menu_key]; + } + elseif (!empty($parent[$menu_key])) { + $default = $parent[$menu_key]; + } + } + + $items[$path] = array( + // default views page entry + 'page callback' => 'views_page', + 'page arguments' => $page_arguments, + // Take over the access definition from the original router item. + // @see option_definition() + // @see views_plugin_access_menu + 'access callback' => $default_map['access callback'], + 'access arguments' => $default_map['access arguments'], + // Identify URL embedded arguments and correlate them to a handler + 'load arguments' => array($this->view->name, $this->display->id, '%index'), + ); + + // List of router item default property values, which are inherited to + // children. These default values are only applied if the original parent + // item does not define them (see below). + // @see _menu_router_build() + $defaults = array( + 'access callback' => 'user_access', + 'menu_name' => NULL, + 'file' => NULL, + 'file path' => NULL, + 'delivery callback' => NULL, + 'theme callback' => NULL, + 'theme arguments' => array(), + ); + + // Grep all router items below the target path. + $num_parent_parts = count(explode('/', $path)); + $children = preg_grep('@^' . preg_quote($path, '@') . '/@', array_keys($callbacks)); + + // Ensure correct inheritance of properties on the original parent path + // (being replaced) to child items. + foreach ($children as $child_path) { + // Only apply property inheritance to direct children of the parent path. + $num_child_parts = count(explode('/', $child_path)); + if ($num_parent_parts == $num_child_parts - 1) { + // Check if the child router item is a views page. If so, there are + // default properties we do not want this item to inherit. + if (isset($callbacks[$child_path]['page callback']) && ($callbacks[$child_path]['page callback'] === 'views_page')) { + continue; + } + $child = &$callbacks[$child_path]; + // Get these first, as we want to know if they existed before parent and + // default values are merged. + $file = isset($child['file']); + $access_callback = isset($child['access callback']); + // Copy all properties from the original parent that will be replaced + // with new values. + // This typically resets 'access arguments', etc. + $child += array_intersect_key($parent, $items[$path]); + // Copy all properties from the original parent, for which the router + // system would inherit parent values or fill in default values. + // This typically adds back 'file' and other properties defined on the + // parent but not on $items[$path]. (The two operations could be + // combined with $items[$path] + $defaults, but are separated for + // documentation purposes and clarity.) + $child += array_intersect_key($parent, $defaults); + // Unset the child 'file' property if its implementing module doesn't + // match it's parent and it didn't have a 'file' preoperty specified + // before. Otherwise, for example, example_module could inherit a 'file' + // property of 'node.admin.inc', so the actual include path would be + // something like .../modules/example_module/node.admin.inc. + if (!$file && isset($child['module'], $parent['module']) && ($child['module'] != $parent['module'])) { + unset($child['file']); + } + // The access callback should only be inherited for default local tasks. + // Ensure it hasn't been mistakenly set. + if (!$access_callback && (!isset($child['type']) || $child['type'] != MENU_DEFAULT_LOCAL_TASK)) { + unset($child['access callback']); + } + // Last catch-22, insert new default properties and their default values + // for the child, which may not be defined on the original parent. + // This typically inserts 'access callback', which can be omitted in + // router item definitions and only gets a default of user_access() in + // the final _menu_router_build(). Without this, the new access callback + // views_access() in $items[$path] would be inherited to all children. + $child += $defaults; + } + } + + // If the original parent path already existed, copy over its remaining + // properties. + $items[$path] += $parent; + + return $items; + } + + /** + * Overrides views_plugin_display::execute(). + * + * Build and render the page view. + * + * Since we replace an existing page, we need to invoke views_set_page_view(). + * Also set the page title, because original page callbacks might do this. + */ + function execute() { + // Let the world know that this is the page view we're using. + views_set_page_view($this->view); + + // Prior to this being called, the $view should already be set to this + // display, and arguments should be set on the view. + $this->view->build(); + if (!empty($this->view->build_info['fail'])) { + return drupal_not_found(); + } + + if (!empty($this->view->build_info['denied'])) { + return drupal_access_denied(); + } + + drupal_add_css(drupal_get_path('module', 'admin_views') . '/admin_views.css'); + + return $this->view->render(); + } + + /** + * Overrides views_plugin_display::get_argument_text(). + */ + function get_argument_text() { + return array( + 'filter value not present' => t('When the filter value is NOT in the URL'), + 'filter value present' => t('When the filter value IS in the URL or a default is provided'), + 'description' => t('The contextual filter values is provided by the URL.'), + ); + } + +} diff --git a/dkan/modules/contrib/admin_views/tests/admin_views.test b/dkan/modules/contrib/admin_views/tests/admin_views.test new file mode 100644 index 000000000..22d4e2bda --- /dev/null +++ b/dkan/modules/contrib/admin_views/tests/admin_views.test @@ -0,0 +1,300 @@ + array('administer users', 'administer permissions'), + 'node' => array('access content overview'), + 'comment' => array('administer comments'), + 'taxonomy' => array('administer taxonomy'), + ); + + function setUp() { + // Setup site and modules. + $modules = func_get_args(); + $modules = isset($modules[0]) && is_array($modules[0]) ? $modules[0] : $modules; + $modules[] = 'admin_views'; + parent::setUp($modules); + + // Fix testing environment. + theme_enable(array('stark')); + variable_set('theme_default', 'stark'); + + // Setup permissions. + $permissions = array( + 'access administration pages', + ); + foreach ($this->permissionMap as $module => $module_permissions) { + if (module_exists($module)) { + $permissions = array_merge($permissions, $module_permissions); + } + } + $this->admin_user = $this->drupalCreateUser($permissions); + + // Setup default configuration. + if (in_array('node', $modules)) { + $this->node_type = $this->drupalCreateContentType(array( + 'type' => 'article', + 'name' => 'Article', + // 2 == COMMENT_NODE_OPEN. + 'comment' => 2, + )); + } + if (in_array('comment', $modules)) { + variable_set('comment_preview_article', DRUPAL_OPTIONAL); + } + } + + protected function assertOriginalRouterItem($module, $path) { + // Retrieve the original router item definition. + $items = module_invoke($module, 'menu'); + $original_item = $items[$path]; + // Retrieve the computed router item definition. + $item = menu_get_item($path); + + // Verify that basic properties are identical. + $title = (isset($original_item['title callback']) ? $original_item['title callback']() : $original_item['title']); + $this->assertEqual($title, $item['title']); + if (isset($original_item['description'])) { + $this->assertEqual($original_item['description'], $item['description']); + } + + // Verify that the title appears. + $this->assertResponse(200); + $this->assertText($original_item['title']); + } +} + +/** + * Tests System display functionality. + */ +class AdminViewsSystemDisplayTestCase extends AdminViewsWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Views System display plugin', + 'description' => 'Tests Views System display plugin functionality.', + 'group' => 'Administration views', + ); + } + + function setUp() { + parent::setUp(array('node', 'comment', 'admin_views_test')); + } + + /** + * Tests proper inheritance of router item properties. + */ + function testRouterItemInheritance() { + $this->drupalLogin($this->admin_user); + $path = 'admin/people'; + $out = $this->drupalGet($path); + $this->assertOriginalRouterItem('user', $path); + + // Verify that local tasks and actions exist and can be accessed. + foreach (array(t('List'), t('Permissions'), t('Add user')) as $link) { + $this->drupalSetContent($out); + $this->assertLink($link); + $this->clickLink($link); + $this->assertResponse(200); + } + + // Test that child page callbacks of a system display work. + $this->drupalGet('admin/content/admin_views_test'); + $this->assertResponse(200); + $this->assertTitle('Administration views test | Drupal'); + $this->assertText('Administration views test page callback'); + } +} + +/** + * Tests default views. + */ +class AdminViewsDefaultViewsTestCase extends AdminViewsWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Default views', + 'description' => 'Tests default views.', + 'group' => 'Administration views', + ); + } + + function setUp() { + parent::setUp(array('node', 'comment')); + } + + /** + * Tests basic appearance and behavior of built-in default views. + */ + function testComment() { + $this->drupalLogin($this->admin_user); + + foreach (array('admin/content/comment', 'admin/content/comment/approval') as $path) { + $this->drupalGet($path); + $this->assertOriginalRouterItem('comment', $path); + + // Verify that a view with its exposed filters appears. + $this->assertFieldByName('subject'); + $this->assertFieldByName('author'); + $this->assertFieldByName('nodeTitle'); + $this->assertFieldByName('status'); + $this->assertFieldByXPath('//select[@name="status"]/option', 'All', 'Published: All option found.'); + $this->assertFieldByXPath('//select[@name="status"]/option', '1', 'Published: Yes option found.'); + $this->assertFieldByXPath('//select[@name="status"]/option', '0', 'Published: No option found.'); + $this->assertFieldByXPath('//input[@type="submit"]', t('Apply'), 'Apply button found.'); + $this->assertFieldByXPath('//input[@type="submit"]', t('Reset'), 'Reset button found.'); + } + } +} + +/** + * Tests system child page display functionality. + * + * This is important, as any other page view menu items that are children of a + * system view can otherwise inherit item properties they don't want. + */ +class AdminViewsPageDisplayTestCase extends AdminViewsWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Views Page display plugin', + 'description' => 'Tests views page functionality for children of system plugins.', + 'group' => 'Administration views', + ); + } + + function setUp() { + parent::setUp(array('node')); + + // Save the test page view. + $this->normalPageView()->save(); + + // Reset views static cache. + views_get_view('admin_views_test_normal', TRUE); + + // Rebuild the menu. + // views_invalidate_cache only sets the rebuild variable. + menu_rebuild(); + } + + /** + * Tests creation of a view page display that is a child of "admin/content". + */ + function testAddPageViewAdminContent() { + $this->drupalLogin($this->admin_user); + + // Test the child view exists by checking for the page title. + $this->drupalGet('admin/content/test'); + $this->assertText('admin_views_test_normal'); + } + + /** + * Returns a test page view with a path under "admin/content". + */ + protected function normalPageView() { + views_include('view'); + $view = new view(); + $view->name = 'admin_views_test_normal'; + $view->description = ''; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->human_name = 'admin_views_test_normal'; + $view->core = 7; + $view->api_version = '3.0'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Master */ + $handler = $view->new_display('default', 'Master', 'default'); + $handler->display->display_options['title'] = 'admin_views_test_normal'; + $handler->display->display_options['use_more_always'] = FALSE; + $handler->display->display_options['access']['type'] = 'perm'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['pager']['options']['items_per_page'] = '10'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'node'; + /* Field: Content: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['label'] = ''; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE; + /* Sort criterion: Content: Post date */ + $handler->display->display_options['sorts']['created']['id'] = 'created'; + $handler->display->display_options['sorts']['created']['table'] = 'node'; + $handler->display->display_options['sorts']['created']['field'] = 'created'; + $handler->display->display_options['sorts']['created']['order'] = 'DESC'; + /* Filter criterion: Content: Published */ + $handler->display->display_options['filters']['status']['id'] = 'status'; + $handler->display->display_options['filters']['status']['table'] = 'node'; + $handler->display->display_options['filters']['status']['field'] = 'status'; + $handler->display->display_options['filters']['status']['value'] = 1; + $handler->display->display_options['filters']['status']['group'] = 1; + $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE; + + /* Display: Page */ + $handler = $view->new_display('page', 'Page', 'page'); + $handler->display->display_options['defaults']['hide_admin_links'] = FALSE; + $handler->display->display_options['path'] = 'admin/content/test'; + + return $view; + } +} + +/** + * Tests default views. + */ +class AdminViewsAccessHandlerTestCase extends AdminViewsWebTestCase { + + public static function getInfo() { + return array( + 'name' => 'Access handler', + 'description' => 'Tests views_plugin_access_menu handler.', + 'group' => 'Administration views', + ); + } + + function setUp() { + parent::setUp(array('node')); + } + + /** + * Tests access handler via views/ajax. + */ + function testAjaxAccess() { + $params = array( + 'view_name' => 'admin_views_user', + 'view_display_id' => 'system_1', + ); + $response_data = $this->drupalGetAJAX('views/ajax', array('query' => $params)); + + $this->assertResponse(200); + // Check no views settings are returned. + $this->assertTrue(empty($response_data[0]['settings']['views'])); + // The next item in the AJAX data will be the insert command containing the + // rendered view. + $this->assertTrue(empty($response_data[1])); + + // Test the access again with the default display. + $params['views_display_id'] = 'default'; + + $response_data = $this->drupalGetAJAX('views/ajax', array('query' => $params)); + + $this->assertResponse(200); + // Check no views settings are returned. + $this->assertTrue(empty($response_data[0]['settings']['views'])); + // The next item in the AJAX data will be the insert command containing the + // rendered view. + $this->assertTrue(empty($response_data[1])); + } +} diff --git a/dkan/modules/contrib/admin_views/tests/admin_views_test/admin_views_test.info b/dkan/modules/contrib/admin_views/tests/admin_views_test/admin_views_test.info new file mode 100644 index 000000000..ff8fdfc8b --- /dev/null +++ b/dkan/modules/contrib/admin_views/tests/admin_views_test/admin_views_test.info @@ -0,0 +1,14 @@ +name = Administration views test +description = Administration views test module +core = 7.x +package = administration +hidden = TRUE + +dependencies[] admin_views + +; Information added by Drupal.org packaging script on 2016-08-02 +version = "7.x-1.6" +core = "7.x" +project = "admin_views" +datestamp = "1470165840" + diff --git a/dkan/modules/contrib/admin_views/tests/admin_views_test/admin_views_test.module b/dkan/modules/contrib/admin_views/tests/admin_views_test/admin_views_test.module new file mode 100644 index 000000000..6f83cc9d6 --- /dev/null +++ b/dkan/modules/contrib/admin_views/tests/admin_views_test/admin_views_test.module @@ -0,0 +1,29 @@ + 'Administration views test', + 'description' => 'Administration views test', + 'page callback' => 'admin_views_test_page_callback', + 'access callback' => TRUE, + ); + + return $items; +} + +/** + * Test page callback. + */ +function admin_views_test_page_callback() { + return 'Administration views test page callback'; +} diff --git a/dkan/modules/contrib/open_data_schema_map/dkan-module-init.sh b/dkan/modules/contrib/open_data_schema_map/dkan-module-init.sh index 3afd68604..6bcbfb4bd 100644 --- a/dkan/modules/contrib/open_data_schema_map/dkan-module-init.sh +++ b/dkan/modules/contrib/open_data_schema_map/dkan-module-init.sh @@ -20,6 +20,7 @@ if wget -q "$URL"; then cd .. tar -xzf dkan-$DKAN_VERSION.tar.gz # We need to fix the archive process to delete this file. + chmod 777 dkan/docroot/sites/default rm -rf dkan/docroot/sites/default/settings.php mv $DKAN_MODULE dkan/ mv dkan $DKAN_MODULE @@ -28,7 +29,8 @@ if wget -q "$URL"; then cd dkan bash dkan-init.sh dkan --skip-init --deps cd .. - ahoy drush "-y --verbose si minimal --sites-subdir=default --account-pass='admin' --db-url=$DATABASE_URL install_configure_form.update_status_module=\"'array\(FALSE,FALSE\)'\"" + echo -ne 'y\n' | ahoy dkan drupal-rebuild $DATABASE_URL + echo -ne 'N\n' | ahoy dkan reinstall else wget -O /tmp/dkan-init.sh https://raw.githubusercontent.com/NuCivic/dkan/$DKAN_VERSION/dkan-init.sh # Make sure the download was at least successful. diff --git a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_ckan/open_data_schema_ckan.info b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_ckan/open_data_schema_ckan.info index 74ea44604..f8078733f 100644 --- a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_ckan/open_data_schema_ckan.info +++ b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_ckan/open_data_schema_ckan.info @@ -5,7 +5,3 @@ package = Open Data dependencies[] = features dependencies[] = open_data_schema_map dependencies[] = pathauto - -; Information added by DKAN release script on 8/23/2017 -version = 7.x-1.13.7 -project = dkan diff --git a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_dcat/open_data_schema_dcat.info b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_dcat/open_data_schema_dcat.info index 31deb2146..92b003c90 100644 --- a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_dcat/open_data_schema_dcat.info +++ b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_dcat/open_data_schema_dcat.info @@ -6,7 +6,3 @@ dependencies[] = features dependencies[] = open_data_schema_map dependencies[] = open_data_schema_map_xml_output dependencies[] = pathauto - -; Information added by DKAN release script on 8/23/2017 -version = 7.x-1.13.7 -project = dkan diff --git a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_map_xml_output/open_data_schema_map_xml_output.info b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_map_xml_output/open_data_schema_map_xml_output.info index 3949e1261..296f94c80 100644 --- a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_map_xml_output/open_data_schema_map_xml_output.info +++ b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_map_xml_output/open_data_schema_map_xml_output.info @@ -3,7 +3,3 @@ description = Provides xml output for for Open Data Schema Map. core = 7.x package = Open Data dependencies[] = open_data_schema_map - -; Information added by DKAN release script on 8/23/2017 -version = 7.x-1.13.7 -project = dkan diff --git a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/open_data_schema_pod.info b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/open_data_schema_pod.info index 8d9997e5b..221438501 100644 --- a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/open_data_schema_pod.info +++ b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/open_data_schema_pod.info @@ -4,7 +4,3 @@ core = 7.x package = Open Data dependencies[] = features dependencies[] = open_data_schema_map - -; Information added by DKAN release script on 8/23/2017 -version = 7.x-1.13.7 -project = dkan diff --git a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/open_data_schema_pod.module b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/open_data_schema_pod.module index ea9bafc00..05a730caa 100644 --- a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/open_data_schema_pod.module +++ b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/open_data_schema_pod.module @@ -137,6 +137,9 @@ function open_data_schema_pod_open_data_schema_map_results_alter(&$result, $mach if ($dataset['accessLevel'] == 'restricted') { $dataset['accessLevel'] = 'restricted public'; } + if ($dataset['accessLevel'] == 'private') { + $dataset['accessLevel'] = 'non-public'; + } } if (isset($dataset['temporal']) && $dataset['temporal'] == "/") { unset($dataset['temporal']); diff --git a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/podValidator.php b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/podValidator.php index 86b07a803..5198a0113 100644 --- a/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/podValidator.php +++ b/dkan/modules/contrib/open_data_schema_map/modules/open_data_schema_pod/podValidator.php @@ -34,7 +34,7 @@ public function getDataJSON() $this->dataJSON->dataset = $this->dataset; } else { - throw new Exception(t("POD validator could not access %url", array("%url" => $this->url))); + throw new \Exception(t("POD validator could not access %url", array("%url" => $this->url))); } } } diff --git a/dkan/modules/contrib/open_data_schema_map/open_data_schema_map.info b/dkan/modules/contrib/open_data_schema_map/open_data_schema_map.info index 3740f7fe3..04565dbeb 100644 --- a/dkan/modules/contrib/open_data_schema_map/open_data_schema_map.info +++ b/dkan/modules/contrib/open_data_schema_map/open_data_schema_map.info @@ -8,7 +8,3 @@ dependencies[] = features dependencies[] = token files[] = open_data_schema_map.features.inc files[] = test/open_data_schema_map_api.test - -; Information added by DKAN release script on 8/23/2017 -version = 7.x-1.13.7 -project = dkan diff --git a/dkan/modules/contrib/recline/README.md b/dkan/modules/contrib/recline/README.md index 5cb504d70..635ad42e5 100644 --- a/dkan/modules/contrib/recline/README.md +++ b/dkan/modules/contrib/recline/README.md @@ -6,7 +6,7 @@ contents using Recline.js ## INSTALLATION -+ Download the Reline.js library from https://github.com/okfn/recline ++ Download the Recline.js library from https://github.com/okfn/recline (zip file) and install in 'sites/all/libraries/'. + Enable recline module. diff --git a/dkan/modules/contrib/recline/dkan-module-init.sh b/dkan/modules/contrib/recline/dkan-module-init.sh index 3afd68604..6bcbfb4bd 100644 --- a/dkan/modules/contrib/recline/dkan-module-init.sh +++ b/dkan/modules/contrib/recline/dkan-module-init.sh @@ -20,6 +20,7 @@ if wget -q "$URL"; then cd .. tar -xzf dkan-$DKAN_VERSION.tar.gz # We need to fix the archive process to delete this file. + chmod 777 dkan/docroot/sites/default rm -rf dkan/docroot/sites/default/settings.php mv $DKAN_MODULE dkan/ mv dkan $DKAN_MODULE @@ -28,7 +29,8 @@ if wget -q "$URL"; then cd dkan bash dkan-init.sh dkan --skip-init --deps cd .. - ahoy drush "-y --verbose si minimal --sites-subdir=default --account-pass='admin' --db-url=$DATABASE_URL install_configure_form.update_status_module=\"'array\(FALSE,FALSE\)'\"" + echo -ne 'y\n' | ahoy dkan drupal-rebuild $DATABASE_URL + echo -ne 'N\n' | ahoy dkan reinstall else wget -O /tmp/dkan-init.sh https://raw.githubusercontent.com/NuCivic/dkan/$DKAN_VERSION/dkan-init.sh # Make sure the download was at least successful. diff --git a/dkan/modules/contrib/recline/js/restdataview.js b/dkan/modules/contrib/recline/js/restdataview.js index a0ec7a372..4ba611c26 100644 --- a/dkan/modules/contrib/recline/js/restdataview.js +++ b/dkan/modules/contrib/recline/js/restdataview.js @@ -7,17 +7,28 @@ attach: function (context) { if (typeof Drupal.settings.recline !== 'undefined' && typeof Drupal.settings.recline.url !== 'undefined') { var map = L.map('rest-map').setView([Drupal.settings.recline.lat, Drupal.settings.recline.lon], 4); - L.esri.basemapLayer('Gray').addTo(map); - L.esri.dynamicMapLayer({ + var baseLayer = L.esri.basemapLayer('Gray').addTo(map); + var fl = L.esri.dynamicMapLayer({ url: Drupal.settings.recline.url, opacity: 0.5, useCors: false }).addTo(map); - var query = L.esri.Tasks.query({ - url: Drupal.settings.recline.url + '/0' - }); - query.bounds(function(error, latLngBounds, response){ - map.fitBounds(latLngBounds); + var bounds = L.latLngBounds([]); + + fl.metadata(function(error, metadata){ + let layersIds = metadata.layers.map(l => l.id); + let counter = sl.length; + layersIds.forEach(id => { + L.esri.query({ + url: Drupal.settings.recline.url + '/' + id + }).bounds(function(error, latLngBounds, response){ + counter--; + bounds.extend(latLngBounds); + if(!counter) { + map.fitBounds(bounds); + } + }); + }) }); } } diff --git a/dkan/modules/contrib/recline/recline.info b/dkan/modules/contrib/recline/recline.info index 65188348e..3f9776aba 100644 --- a/dkan/modules/contrib/recline/recline.info +++ b/dkan/modules/contrib/recline/recline.info @@ -6,7 +6,3 @@ dependencies[] = libraries dependencies[] = file scripts[] = js/jsondataview.js scripts[] = js/restdataview.js - -; Information added by DKAN release script on 8/23/2017 -version = 7.x-1.13.7 -project = dkan diff --git a/dkan/modules/contrib/recline/recline.js b/dkan/modules/contrib/recline/recline.js index 3de0fd6e9..68ae4374a 100644 --- a/dkan/modules/contrib/recline/recline.js +++ b/dkan/modules/contrib/recline/recline.js @@ -157,6 +157,20 @@ delimiter: delimiter }; break; + case 'tsv': + datasetOptions = { + backend: 'csv', + url: file, + delimiter: delimiter + }; + break; + case 'txt': + datasetOptions = { + backend: 'csv', + url: file, + delimiter: delimiter + }; + break; case 'ckan': datasetOptions = { endpoint: 'api', @@ -213,9 +227,15 @@ var formats = { 'csv': ['text/csv', 'csv'], 'xls': ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'], + 'tsv': ['text/tab-separated-values', 'text/tsv', 'tsv', 'tab'], + 'txt': ['text/plain', 'txt'], }; var backend = _.findKey(formats, function(format) { return _.include(format, fileType) }); + // If the backend is a txt but the delimiter is not a tab, we don't need + // to show it using the backend. + if (Drupal.settings.recline.delimiter !== "\t" && backend === 'txt') {return '';} + // If the backend is an xls but the browser version is prior 9 then // we need to fallback to dataproxy if (backend === 'xls' && document.documentMode < 9) return 'dataproxy'; diff --git a/dkan/modules/contrib/recline/recline.module b/dkan/modules/contrib/recline/recline.module index 6000bc0c8..0f79f176c 100644 --- a/dkan/modules/contrib/recline/recline.module +++ b/dkan/modules/contrib/recline/recline.module @@ -552,6 +552,7 @@ function recline_delimiters() { ';' => ';', '|' => '|', '+' => '+', + "\t" => 'tab', ); } diff --git a/dkan/modules/contrib/recline/recline.theme.inc b/dkan/modules/contrib/recline/recline.theme.inc index 27c326dc8..28599ffae 100644 --- a/dkan/modules/contrib/recline/recline.theme.inc +++ b/dkan/modules/contrib/recline/recline.theme.inc @@ -24,13 +24,12 @@ define('RECLINE_REQUEST_TIMEOUT_HEAD', 2); */ define('RECLINE_REQUEST_TIMEOUT_GET', 10); - /** * Returns HTML for an recline field formatter. * - * @param array $variables + * @param array $vars * An associative array containing: - * - item: Associative array of recline field + * - item: Associative array of recline field. * * @ingroup themeable */ @@ -83,7 +82,7 @@ function theme_recline_default_formatter($vars) { return drupal_render($output); } - if(!$type) { + if (!$type) { $request = drupal_http_request($url, array('timeout' => RECLINE_REQUEST_TIMEOUT_HEAD, 'method' => 'HEAD')); // When request fail. if ($request->code != 200) { @@ -110,7 +109,7 @@ function theme_recline_default_formatter($vars) { } } } - + // Displaying previews breaks solr indexing. // @TODO: Create a new display mode from search indexing and remove. if (isset($vars['item']['entity']->search_api_language)) { @@ -122,13 +121,18 @@ function theme_recline_default_formatter($vars) { case 'json': $output['preview'] = recline_preview_json($url); break; + case 'csv': + case 'txt': + case 'tsv': case 'xls': $output['preview'] = recline_preview_multiview($vars); break; + case 'geojson': $output['preview'] = recline_preview_geojson_leaflet($url); break; + case 'zip': $filename = FALSE; @@ -176,21 +180,26 @@ function theme_recline_default_formatter($vars) { case 'html': $output['preview'] = recline_format_link_api($url); break; + case 'png': case 'gif': case 'jpg': $output['preview'] = recline_format_image($url); break; + case 'arcgis': $output['preview'] = recline_preview_arcgis_feature($url); break; + case 'rdf': case 'xml': $output['preview'] = recline_prettify_xml($url); break; + case 'pdf': $output['preview'] = recline_format_link_api($url); break; + case 'wms': // We can accept just the bare endpoint or the XML preview. $parsed = parse_url($url); @@ -232,6 +241,7 @@ function theme_recline_default_formatter($vars) { $output['preview'] = recline_preview_unavailable(); } break; + default: $output[] = recline_preview_unavailable(); } @@ -245,7 +255,7 @@ function recline_preview_wms($url, $titles, $images, $north, $east, $south, $wes $items = array(); foreach ($titles as $title) { if (isset($images[$title])) { - $title = '' . t( $title)) . '"/> ' . $title; + $title = t('@title legend item @title', array('@title' => $title, '@image' => $images[$title])); } $items[] = array( 'data' => $title, @@ -264,10 +274,20 @@ function recline_preview_wms($url, $titles, $images, $north, $east, $south, $wes format: 'image/png', transparent: true, }).addTo(map);map.fitBounds([['" . $south . "','" . $west . "'],['" . $north . "','" . $east . "']]);"; - drupal_add_js($output, array('type' => 'inline', 'scope' => 'footer', 'weight' => 5)); + drupal_add_js($output, array( + 'type' => 'inline', + 'scope' => 'footer', + 'weight' => 5, + )); return array( '#type' => 'markup', - '#markup' => '
' . theme('item_list', array('items' => $items, 'title' => t("Legend"), 'attributes' => array('class' => 'list-inline'))), + '#markup' => '
' . theme('item_list', array( + 'items' => $items, + 'title' => t("Legend"), + 'attributes' => array( + 'class' => 'list-inline', + ), + )), ); } @@ -327,7 +347,17 @@ function recline_preview_json($url) { // When a json is a geojson file then return a geojson preview // instead of a normal json preview. - $types = array('FeatureCollection', 'GeometryCollection', 'Feature', 'Point', 'MultiPoint', 'LineString', 'MultiLineString', 'Polygon', 'MultiPolygon'); + $types = array( + 'FeatureCollection', + 'GeometryCollection', + 'Feature', + 'Point', + 'MultiPoint', + 'LineString', + 'MultiLineString', + 'Polygon', + 'MultiPolygon', + ); foreach ($types as $type) { foreach ($decoded as $key => $value) { if ($type === $value) { @@ -386,13 +416,19 @@ function recline_replace_lt_gt($data) { */ function recline_preview_arcgis_feature($url) { drupal_add_js('https://cdn.jsdelivr.net/leaflet/1.0.2/leaflet.js', 'external'); - drupal_add_js('https:////cdn.jsdelivr.net/leaflet.esri/1.0.0/esri-leaflet.js', 'external'); + drupal_add_js('https:////cdn.jsdelivr.net/leaflet.esri/2.0.0/esri-leaflet.js', 'external'); drupal_add_css('https://cdn.jsdelivr.net/leaflet/1.0.2/leaflet.css', 'external'); drupal_add_css('body { margin:0; padding:0; } #rest-map { position: relative; height: 500px; width: 100%;}', 'inline'); $lat = variable_get('recline_default_lat', "38"); $lon = variable_get('recline_default_lon', "-99"); $module_path = drupal_get_path('module', 'recline'); - drupal_add_js(array('recline' => array('url' => $url, 'lat' => $lat, 'lon' => $lon)), 'setting'); + drupal_add_js(array( + 'recline' => array( + 'url' => $url, + 'lat' => $lat, + 'lon' => $lon, + ) + ),'setting'); drupal_add_js($module_path . '/restdataview.js'); $output = array( 'map' => array( @@ -412,7 +448,7 @@ function recline_preview_geojson_leaflet($url) { $geojson = $response->data; } else { - return ; + return; } libraries_load('leaflet_markercluster'); $leaflet_imgs = libraries_get_path('recline') . '/vendor/leaflet/1.0.2/images/'; @@ -428,15 +464,19 @@ function recline_preview_geojson_leaflet($url) { markers.addLayer(geojson); map.addLayer(markers); map.fitBounds(geojson.getBounds());"; - drupal_add_js($output, array('type' => 'inline', 'scope' => 'footer', 'weight' => 5)); + drupal_add_js($output, array( + 'type' => 'inline', + 'scope' => 'footer', + 'weight' => 5, + )); return array( 'map' => array( '#type' => 'markup', '#markup' => '
', ), ); - return $output; } + /** * Builds output render array for files if item is an archive. */ @@ -466,6 +506,7 @@ function recline_preview_zip($uri) { } return $output; } + /** * Builds icon for resource view. */ @@ -489,9 +530,8 @@ function recline_build_icon($url, $format, $filename, $filemime, $filesize, $des ); } - /** - * Builds output render array for csv files + * Builds output render array for csv files. */ function recline_preview_multiview($variables) { $output = array(); @@ -499,10 +539,10 @@ function recline_preview_multiview($variables) { $module_path = drupal_get_path('module', 'recline'); $item = $variables['item']; - //Check problem loading file + // Check problem loading file. if (!isset($item['uri']) && $item['fid']) { $file = file_load($item['fid']); - $file = (array)$file; + $file = (array) $file; $item = array_replace($item, $file); } $node = $item['entity']; @@ -550,6 +590,10 @@ function recline_preview_multiview($variables) { $map = !$is_remote && !$show_all ? (int) $item['map'] : 1; $embed = !empty($item['embed']) ? (int) $item['embed'] : 0; + if (pathinfo($item['uri'], PATHINFO_EXTENSION) === 'tab') { + $item['filemime'] = 'text/tab-separated-values'; + } + $settings['recline'] = array( 'file' => $file_path, 'fileType' => $item['filemime'], @@ -583,7 +627,7 @@ function recline_preview_multiview($variables) { $output['data_explorer'] = array( '#type' => 'markup', - '#markup' => '', + '#markup' => '
Data Preview: Note that by default the preview only displays up to 100 records. Use the pager to flip through more records or adjust the start and end fields to display the number of records you wish to see.
', ); return $output; } @@ -603,7 +647,7 @@ function template_preprocess_recline_embed_button(&$variables) { * * @param array $variables * An associative array containing: - * - item: Associative array of recline field + * - item: Associative array of recline field. * * @ingroup themeable */ diff --git a/dkan/modules/contrib/search_api_db/PATCHES.txt b/dkan/modules/contrib/search_api_db/PATCHES.txt new file mode 100644 index 000000000..e7e744b0c --- /dev/null +++ b/dkan/modules/contrib/search_api_db/PATCHES.txt @@ -0,0 +1,4 @@ +The following patches have been applied to this project: +- https://www.drupal.org/files/issues/2855634-23--fix_update_7107_for_different_db.patch + +This file was automatically generated by Drush Make (http://drupal.org/project/drush). \ No newline at end of file diff --git a/dkan/modules/contrib/search_api_db/search_api_db.install b/dkan/modules/contrib/search_api_db/search_api_db.install index 0202a0bf4..02b6a77dc 100644 --- a/dkan/modules/contrib/search_api_db/search_api_db.install +++ b/dkan/modules/contrib/search_api_db/search_api_db.install @@ -289,6 +289,9 @@ function search_api_db_update_7107() { $options = unserialize($options); if (!empty($options['indexes'])) { + list($key, $target) = explode(':', $options['database'], 2); + $connection = Database::getConnection($target, $key); + foreach ($options['indexes'] as $index_id => $fields) { $text_table = NULL; @@ -296,7 +299,7 @@ function search_api_db_update_7107() { if (search_api_is_text_type($field['type'])) { $text_table = $field['table']; if (strlen($field_id) > 255) { - db_update($text_table) + $connection->update($text_table) ->fields(array('field_name' => drupal_hash_base64($field_id))) ->condition('field_name', md5($field_id)) ->execute(); @@ -305,8 +308,9 @@ function search_api_db_update_7107() { } // If there is a text table for this index, update its description. - if ($text_table) { - db_change_field($text_table, 'field_name', 'field_name', $spec); + if ($text_table && db_table_exists($text_table)) { + $connection->schema() + ->changeField($text_table, 'field_name', 'field_name', $spec); } } } diff --git a/dkan/modules/contrib/visualization_entity/CHANGELOG.txt b/dkan/modules/contrib/visualization_entity/CHANGELOG.txt index ec9cab319..723397f38 100644 --- a/dkan/modules/contrib/visualization_entity/CHANGELOG.txt +++ b/dkan/modules/contrib/visualization_entity/CHANGELOG.txt @@ -1,11 +1,18 @@ 7.x-1.x ------- - Added help text to chart creation form. +- Added validation on axis ticks configuration. +- Fixed x-frame-options error on embeded chart visualizations. +- Add help text to configuration fields in the chart entity form. +- Added 'Data type' settings also for series values ('y' values). +- Fixed parsing of 'Numeral' values on series. -7.x-1.13.4 ----------- +7.x-1.2 +------- - Update eck to 7.x-2.0-rc9. - Removed dataproxy as an option from the Select backend source type field on charts. - Fixed 'edit/delete' paths used on 'edit/delete' links on visualization tables. - Fixed the Chart form to comply with Section 508 requirements for keyboard access. - Use vertical goal for horizontal bar charts. + + diff --git a/dkan/modules/contrib/visualization_entity/dkan-module-init.sh b/dkan/modules/contrib/visualization_entity/dkan-module-init.sh index 9041558ce..6bcbfb4bd 100644 --- a/dkan/modules/contrib/visualization_entity/dkan-module-init.sh +++ b/dkan/modules/contrib/visualization_entity/dkan-module-init.sh @@ -20,6 +20,7 @@ if wget -q "$URL"; then cd .. tar -xzf dkan-$DKAN_VERSION.tar.gz # We need to fix the archive process to delete this file. + chmod 777 dkan/docroot/sites/default rm -rf dkan/docroot/sites/default/settings.php mv $DKAN_MODULE dkan/ mv dkan $DKAN_MODULE @@ -28,16 +29,14 @@ if wget -q "$URL"; then cd dkan bash dkan-init.sh dkan --skip-init --deps cd .. - ahoy drush "-y --verbose si minimal --sites-subdir=default --account-pass='admin' --db-url=$DATABASE_URL install_configure_form.update_status_module=\"'array\(FALSE,FALSE\)'\"" - chmod +w docroot/sites/default/settings.php - printf "// DKAN Datastore Fast Import options.\n\$databases['default']['default']['pdo'] = array(\n PDO::MYSQL_ATTR_LOCAL_INFILE => 1,\n PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => 1,\n);" >> docroot/sites/default/settings.php - chmod -w docroot/sites/default/settings.php + echo -ne 'y\n' | ahoy dkan drupal-rebuild $DATABASE_URL + echo -ne 'N\n' | ahoy dkan reinstall else - wget -O /tmp/dkan-init.sh https://raw.githubusercontent.com/NuCivic/dkan/$DKAN_VERSION/dkan-module-init.sh + wget -O /tmp/dkan-init.sh https://raw.githubusercontent.com/NuCivic/dkan/$DKAN_VERSION/dkan-init.sh # Make sure the download was at least successful. if [ $? -ne 0 ] ; then echo "" - echo "[Error] Failed to download the dkan-module-init.sh script from github dkan. Branch: $DKAN_BRANCH . Perhaps someone deleted the branch?" + echo "[Error] Failed to download the dkan-init.sh script from github dkan. Branch: $DKAN_BRANCH . Perhaps someone deleted the branch?" echo "" exit 1 fi diff --git a/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/README.md b/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/README.md index c4fe8e140..2d2e71a7d 100644 --- a/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/README.md +++ b/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/README.md @@ -35,7 +35,7 @@ drush cc all Once the module is enabled, new chart entities can be created by going to /admin/structure/entity-type/visualization/ve_chart/add. A multi-step process will guide you through creation of a chart based on an uploaded data file. #### Step One - Choose a Resource -Use the form to upload or link to a data source for the visulization. +Use the form to upload or link to a data source for the visualization. Valid source data include: * CSV * Google Spreadsheet @@ -61,7 +61,7 @@ Multiple filters can be applied to data. * **Format** Select an appropriate format for the X Axis labels. * **Axis Label** will provide a custom label for the x axis. **Note:** Axis labels do not display for Pie Charts. * **Label rotation** will change angle of label values. -* **Tick Values** with **step value** will update the number of ticks for the X axis. **NOTE:** If the range set for tick values is smaller than the range of complete data represented, the chart will be abreviated. +* **Tick Values** with **step value** will update the number of ticks for the X axis. **NOTE:** If the range set for tick values is smaller than the range of complete data represented, the chart will be abbreviated. ###### Y Axis diff --git a/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/css/ve_chart.css b/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/css/ve_chart.css index b63709591..1d6edd1bb 100644 --- a/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/css/ve_chart.css +++ b/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/css/ve_chart.css @@ -7,6 +7,12 @@ .field-name-field-ve-settings { display: none; } +#chart-with-controls h4 { + font-weight: normal; +} +#chart-with-controls.col-md-12 { + padding: 0; +} #chart-with-controls .tab-content { overflow: hidden; } @@ -30,6 +36,7 @@ svg { #ve-chart-form .pane-content{ overflow: auto; + padding: 4px; } #ve-chart-form .stages li { @@ -43,7 +50,7 @@ svg { #chart-selector { width: 100%; overflow: auto; - padding: 0px; + padding: 0 0 15px; } #chart-selector button{ height: 180px; @@ -72,6 +79,9 @@ svg { margin-top: 0px; margin-bottom: 0px; position: relative; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; } .expander span { @@ -88,7 +98,9 @@ svg { border: 1px solid #ddd; border-radius: 5px; } - +.pad { + padding: 15px; +} .form-panel .form-group:last-child{ margin-bottom: 0px; } @@ -100,8 +112,16 @@ svg { } #query-editor .btn { - padding: 6px 12px; + padding: 5px 12px; border-right: none; + height: 34px; + margin: 4px 0; +} +#ve-chart-form input.form-control { + margin: 4px 1em 0 0; +} +#control_chart_series_chosen { + margin-bottom: 1em; } #pager li.prev.action-pagination-update a { @@ -116,6 +136,7 @@ svg { #pager li.page-range a { padding: 3px; + height: 35px; } #pager .pagination { @@ -168,4 +189,64 @@ svg { #chart-selector .linePlusBarChart { background-image: url('img/lineplusbar.png'); -} \ No newline at end of file +} + +.filter fieldset { + border: 1px solid #ddd; + border-radius: 4px; + margin: 5px 0; + padding: 40px 8px 8px; + position: relative; +} + +.filter fieldset legend, +.filter-term label { + display: block; + max-width: 100%; + margin: 5px 0 0; + font-size: 1em; + font-weight: bold; + background: #DDDDDD; + padding: 4px 10px; + border-radius: 4px 4px 0 0; +} +.filter fieldset legend { + position: absolute; + top: 0; + left: 0; + right: 0; + padding: 6px 10px; + margin: 0; +} +.filters .form-stacked button { + margin-top: 10px; +} +.filters .form-stacked button#add-filter-btn { + margin-top: 0; +} +.filters .filter-term input { + border-radius: 0 0 4px 4px +} + +.data-details { display: table; } +.data-results { + display: table-cell; + padding: 0 20px; + vertical-align: middle; +} + +/* Help Pop-overs */ +.fa-question-circle-o:before { + font-family: 'FontAwesome'; + content: "\f29c"; +} +.help { + padding: 0 8px; +} +#query-editor .help { + display: table-cell; + vertical-align: middle; +} +#filter-editor .help { + display: inline; +} diff --git a/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/js/visualization_entity_charts_editors.js b/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/js/visualization_entity_charts_editors.js index 1c5f5978e..40e6ab420 100644 --- a/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/js/visualization_entity_charts_editors.js +++ b/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/js/visualization_entity_charts_editors.js @@ -1,3 +1,8 @@ +/** + * @file + * Visualization Entity Chart Editors. + */ + this.recline = this.recline || {}; this.recline.View = this.recline.View || {}; this.recline.View.nvd3 = this.recline.View.nvd3 || {}; @@ -15,6 +20,9 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; \
\ \ + \
\ \ \ @@ -25,20 +33,21 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; 'change input': 'onFormSubmit' }, - initialize: function() { + initialize: function () { _.bindAll(this, 'render'); this.listenTo(this.model, 'change', this.render); this.render(); }, - onFormSubmit: function(e) { + onFormSubmit: function (e) { e.preventDefault(); var query = this.$el.find('.search-query').val(); this.model.set({q: query}); }, - render: function() { + render: function () { var tmplData = this.model.toJSON(); var templated = Mustache.render(this.template, tmplData); this.$el.html(templated); + $('[data-toggle="popover"]').popover(); } }); @@ -64,6 +73,11 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; \ \ \ + \ \
\ {{#filters}} \ @@ -80,22 +94,20 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {};
\
\ \ - \ + \
\
\ ', range: ' \
\
\ -
\ - \ -
\ + \ + {{field}} {{type}} \ + \ + \
\ \ \ @@ -111,8 +123,8 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {};
\
\ \ - {{field}} {{type}} \ - × \ + {{field}} {{type}} \ + \ \
\ \ @@ -136,34 +148,35 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; 'click .js-edit button': 'onTermFiltersUpdate', 'click #add-filter-btn': 'onAddFilter' }, - initialize: function() { + initialize: function () { _.bindAll(this, 'render'); this.listenTo(this.model.fields, 'all', this.render); this.listenTo(this.model.queryState, 'change change:filters:new-blank', this.render); this.render(); }, - render: function() { + render: function () { var self = this; var tmplData = $.extend(true, {}, this.model.queryState.toJSON()); - // we will use idx in list as there id ... - tmplData.filters = _.map(tmplData.filters, function(filter, idx) { + // We will use idx in list as the id. + tmplData.filters = _.map(tmplData.filters, function (filter, idx) { filter.id = idx; return filter; }); tmplData.fields = this.model.fields.toJSON(); - tmplData.filterRender = function() { + tmplData.filterRender = function () { return Mustache.render(self.filterTemplates[this.type], this); }; var out = Mustache.render(this.template, tmplData); this.$el.html(out); + $('[data-toggle="popover"]').popover(); }, - onAddFilterShow: function(e) { + onAddFilterShow: function (e) { e.preventDefault(); var $target = $(e.target); $target.hide(); this.$el.find('.js-add').show(); }, - onAddFilter: function(e) { + onAddFilter: function (e) { e.preventDefault(); var $target = $(e.target).closest('.form-stacked'); $target.hide(); @@ -171,18 +184,18 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; var field = $target.find('select.fields').val(); this.model.queryState.addFilter({type: filterType, field: field}); }, - onRemoveFilter: function(e) { + onRemoveFilter: function (e) { e.preventDefault(); var $target = $(e.target); var filterId = $target.attr('data-filter-id'); this.model.queryState.removeFilter(filterId); }, - onTermFiltersUpdate: function(e) { + onTermFiltersUpdate: function (e) { var self = this; e.preventDefault(); var filters = self.model.queryState.get('filters'); var $form = $(e.target).closest('.form-stacked'); - _.each($form.find('input'), function(input) { + _.each($form.find('input'), function (input) { var $input = $(input); var filterType = $input.attr('data-filter-type'); var fieldId = $input.attr('data-filter-field'); @@ -194,11 +207,13 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; case 'term': filters[filterIndex].term = value; break; + case 'range': filters[filterIndex][name] = value; break; + case 'geo_distance': - if(name === 'distance') { + if (name === 'distance') { filters[filterIndex].distance = parseFloat(value); } else { @@ -229,25 +244,28 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; 'change input': 'onFormSubmit' }, - initialize: function() { + initialize: function () { _.bindAll(this, 'render'); this.listenTo(this.model.queryState, 'change', this.render); this.render(); }, - onFormSubmit: function(e) { + onFormSubmit: function (e) { e.preventDefault(); - // filter is 0-based; form is 1-based - var formFrom = parseInt(this.$el.find('input[name="from"]').val())-1; - var formTo = parseInt(this.$el.find('input[name="to"]').val())-1; - var maxRecord = this.model.recordCount-1; - if (this.model.queryState.get('from') != formFrom) { // changed from; update from + // Filter is 0-based; form is 1-based. + var formFrom = parseInt(this.$el.find('input[name="from"]').val()) - 1; + var formTo = parseInt(this.$el.find('input[name="to"]').val()) - 1; + var maxRecord = this.model.recordCount - 1; + if (this.model.queryState.get('from') != formFrom) { + // Changed from; update from. this.model.queryState.set({from: Math.min(maxRecord, Math.max(formFrom, 0))}); - } else if (this.model.queryState.get('to') != formTo) { // change to; update size + } + else if (this.model.queryState.get('to') != formTo) { + // Change to; update size. var to = Math.min(maxRecord, Math.max(formTo, 0)); - this.model.queryState.set({size: Math.min(maxRecord+1, Math.max(to-formFrom+1, 1))}); + this.model.queryState.set({size: Math.min(maxRecord + 1, Math.max(to - formFrom + 1, 1))}); } }, - onPaginationUpdate: function(e) { + onPaginationUpdate: function (e) { e.preventDefault(); var $el = $(e.target); var newFrom = 0; @@ -257,7 +275,8 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; if ($el.parent().hasClass('prev')) { newFrom = Math.max(currFrom - Math.max(0, size), 0); updateQuery = newFrom != currFrom; - } else { + } + else { newFrom = Math.max(currFrom + size, 0); updateQuery = (newFrom < this.model.recordCount); } @@ -265,14 +284,14 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; this.model.queryState.set({from: newFrom}); } }, - render: function() { + render: function () { var tmplData = this.model.toJSON(); var from = parseInt(this.model.queryState.get('from')); - tmplData.from = from+1; - tmplData.to = Math.min(from+this.model.queryState.get('size'), this.model.recordCount); + tmplData.from = from + 1; + tmplData.to = Math.min(from + this.model.queryState.get('size'), this.model.recordCount); var templated = Mustache.render(this.template, tmplData); this.$el.html(templated); return this; } }); -})(jQuery, recline.View.nvd3, window); \ No newline at end of file +})(jQuery, recline.View.nvd3, window); diff --git a/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/js/visualization_entity_charts_steps.js b/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/js/visualization_entity_charts_steps.js index 2b2096438..8496f3fed 100644 --- a/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/js/visualization_entity_charts_steps.js +++ b/dkan/modules/contrib/visualization_entity/modules/visualization_entity_charts/js/visualization_entity_charts_steps.js @@ -1,3 +1,8 @@ +/** + * @file + * Provides multi-page form for chart visualization. + */ + this.recline = this.recline || {}; this.recline.View = this.recline.View || {}; this.recline.View.nvd3 = this.recline.View.nvd3 || {}; @@ -6,10 +11,14 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; 'use strict'; /** - * Chart options step + * Chart options step. */ global.ChartOptionsView = Backbone.View.extend({ - template: '
' + + template: '
' + + 'Chart Preview: Note that by default the preview only displays up to 100 records. ' + + 'Click on the Dataset tab below to review the data in use. Adjust the start and end fields of the ' + + 'pager to set the number of records you wish to use.
' + + '
' + '
' + '
' + '
' + - '
' + + '
' + + '' + + '{{recordCount}} records' + + '
' + '
' + '
' + '
' + @@ -61,12 +73,14 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; '
' + '
' + '' + - '' + + '' + '
', events: { - '#query-editor button': 'onEditorUpdate' + '#query-editor button': 'onEditorUpdate', + 'click #finish': 'finish' }, - initialize: function(options){ + initialize: function (options) { + console.log('initialize'); var self = this; self.options = _.defaults(options || {}, self.options); self.state = self.options.state; @@ -78,24 +92,23 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; }; }, copyQueryState: function(){ - console.log('copyQueryState'); var self = this; self.state.set('queryState', self.state.get('model').queryState.toJSON()); }, - render: function(){ + render: function () { var self = this; var graphType = self.state.get('graphType'); - self.listenTo(self.state.get('model').queryState, 'change', self.copyQueryState); self.$el.html(Mustache.render(self.template, self.state.toJSON())); + self.$el.find('.doc-count').text(self.state.get('model').recordCount || 'Unknown'); self.$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { self.graph.render(); }); - self.$('.expander').on('click', function(){ + self.$('.expander').on('click', function () { var visible = self.$(this).next().is(':visible'); var sp = self.$(this).find('span'); - var sign = (!visible) ? '-' : '+' ; + var sign = (!visible) ? '-' : '+'; sp.html(sign); self.$(this).next().slideToggle('fast'); }); @@ -112,25 +125,25 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; state: self.state }); - // Pager widget + // Pager widget. self.pager = new recline.View.Pager({ model: self.state.get('model'), state: self.state }); - // Search wiget + // Search wiget. self.queryEditor = new recline.View.nvd3.QueryEditor({ model: self.state.get('model').queryState, state: self.state }); - // Filter widget + // Filter widget. self.filterEditor = new recline.View.nvd3.FilterEditor({ model: self.state.get('model'), state: self.state }); - // Grid + // Grid. self.grid = new recline.View.SlickGrid({ model: self.state.get('model'), el: self.$('#grid'), @@ -145,7 +158,7 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; self.assign(self.queryEditor, '#query-editor'); self.assign(self.filterEditor, '#filter-editor'); - // Slickgrid needs to update after tab content is displayed + // Slickgrid needs to update after tab content is displayed. $('#grid') .closest('.tab-content') .prev() @@ -156,38 +169,49 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; self.$('.chosen-select').chosen({width: '95%'}); }, - onEditorUpdate: function(){ + onEditorUpdate: function () { return false; }, updateState: function(state, cb){ + // TO CHECK: This never gets executed. cb(state); }, - assign: function(view, selector){ + assign: function (view, selector) { var self = this; view.setElement(self.$(selector)).render(); }, + finish: function(event) { + var self = this; + if (!self.validate()) { + event.preventDefault(); + } + }, + validate: function() { + var self = this; + return self.controls.validate(); + }, }); /** - * Choose chart view + * Choose chart view. */ global.ChooseChartView = Backbone.View.extend({ template: '
' + '
' + '' + - '
{{source.url}}
'+ + '
{{source.url}}
' + '
' + '
' + '' + - '
{{xfield}}
'+ + '
{{xfield}}
' + '
' + '
' + '' + - '
{{seriesFields}}
'+ + '
{{seriesFields}}
' + '
' + '
' + '{{#graphTypes}}' + - '' + + '' + '{{/graphTypes}}' + '' + '
' + @@ -195,7 +219,7 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; '' + '' + '
', - initialize: function(options){ + initialize: function (options) { var self = this; self.options = _.defaults(options || {}, self.options); self.state = self.options.state; @@ -207,73 +231,97 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; events: { 'click #chart-selector button': 'selectChart' }, - selectChart: function(e){ + selectChart: function (e) { var self = this; self.$('button').removeClass('selected'); self.$(e.target).addClass('selected'); }, - getSelected: function(){ + getSelected: function () { var self = this; return self.$('button.selected').data('selected'); }, - render: function(){ + render: function () { var self = this; var graphTypes = [ 'discreteBarChart', 'multiBarChart', 'multiBarHorizontalChart', 'stackedAreaChart', 'pieChart', 'lineChart', 'lineWithFocusChart', 'scatterChart', 'linePlusBarChart' ]; - self.state.set('graphTypes', graphTypes.map(function(type, index){ - var selected = type === (self.state.get('graphType') || 'discreteBarChart' ); + self.state.set('graphTypes', graphTypes.map(function (type, index) { + var selected = type === (self.state.get('graphType') || 'discreteBarChart'); return {value: type, selected: selected}; })); self.$el.html(Mustache.render(self.template, self.state.toJSON())); self.$('.chosen-select').chosen({width: '95%'}); + + $('[data-toggle="popover"]').popover({ trigger: "hover" }); }, - updateState: function(state, cb){ + updateState: function (state, cb) { var self = this; var type = self.getSelected(); state.set('graphType', type); - cb(state); - } + var result = self.validate(); + cb(state, result); + }, + validate: function() { + return true; + }, }); /** - * Data options view + * Data options view. */ global.DataOptionsView = Backbone.View.extend({ - template: '
' + + template: '
' + '
' + '' + - '
{{source.url}}
'+ + '
{{source.url}}
' + '
' + + '
' + + '
' + '' + + '' + '' + + '
' + + '' + + '
' + + '{{#yDataTypes}}' + + '' + + '{{/yDataTypes}}' + + '
' + '
' + - '
' + - '' + - '' + - '
' + - '
' + - '{{#xDataTypes}}' + - '' + - '{{/xDataTypes}}' + + '
' + + '
' + + '' + + '' + + '
' + + '
' + + '
' + + '' + + '
' + + '{{#xDataTypes}}' + + '' + + '{{/xDataTypes}}' + + '
' + '
' + '
' + '' + '' + '
' + '
', - initialize: function(options){ + initialize: function (options) { var self = this; self.options = _.defaults(options || {}, self.options); self.state = self.options.state; @@ -282,13 +330,16 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; name: 'dataOptions' }; }, - render: function(){ + render: function () { var self = this; var dataTypes = ['Number', 'String', 'Date', 'Auto']; self.state.set('fields', _.applyOption( _.arrayToOptions(_.getFields(self.state.get('model'))), self.state.get('seriesFields') )); + self.state.set('yDataTypes', _.applyOption( + _.arrayToOptions(dataTypes), [self.state.get('yDataType') || 'Auto'] + )); self.state.set('xfields', _.applyOption( _.arrayToOptions(_.getFields(self.state.get('model'))), [self.state.get('xfield')] )); @@ -298,25 +349,37 @@ this.recline.View.nvd3 = this.recline.View.nvd3 || {}; self.$el.html(Mustache.render(self.template, self.state.toJSON())); self.$('.chosen-select').chosen({width: '95%'}); + + $('[data-toggle="popover"]').popover(); }, - updateState: function(state, cb){ + updateState: function (state, cb) { var self = this; state.set('seriesFields', self.$('#control-chart-series').val()); + state.set('yDataType', self.$('input[name=control-chart-y-data-type]:checked').val()); state.set('xfield', self.$('#control-chart-xfield').val()); state.set('xDataType', self.$('input[name=control-chart-x-data-type]:checked').val()); - cb(state); - } + var result = self.validate(); + cb(state, result); + }, + validate: function() { + return true; + }, }); /** - * Load data view + * Load data view. + * + * Hiding Source Url field until further work can be done on it, it is useless at this point. */ global.LoadDataView = Backbone.View.extend({ - template: '
' + - '' + + template: '' + '
' + + '' + + ' (Experimental : Backends other than DKAN are still a work in progress.)' + '(?:[^"]|\\")*)" (?:is|should be) selected/ + * @Then /^the option "(?P