<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 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 Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc service
     * @name openlmis-repository.OpenlmisResource
     *
     * @description
     * Generic repository for communicating with the OpenLMIS RESTful endpoints.
     */
    angular
        .module('openlmis-repository')
        .factory('OpenlmisResource', OpenlmisResource);

    OpenlmisResource.$inject = ['$resource', '$q', 'MAX_URI_LENGTH', 'openlmisUrlFactory', 'ParameterSplitter'];

    function OpenlmisResource($resource, $q, MAX_URI_LENGTH, openlmisUrlFactory, ParameterSplitter) {

        OpenlmisResource.prototype.query = query;
        OpenlmisResource.prototype.get = get;
        OpenlmisResource.prototype.getAll = getAll;
        OpenlmisResource.prototype.update = update;
        OpenlmisResource.prototype.create = create;
        OpenlmisResource.prototype.delete = deleteObject;
        OpenlmisResource.prototype.search = search;
        OpenlmisResource.prototype.throwMethodNotSupported = throwMethodNotSupported;

        return OpenlmisResource;

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name OpenlmisResource
         * @constructor
         *
         * @description
         * Creates an instance of the OpenlmisResource class.
         *
         * Configuration options:
         * - paginated - flag defining whether response returned by the query request is paginated; defaults to true
         *
         * @param {String} uri    the URI pointing to the resource
         * @param {Object} config the optional configuration object, modifies the default behavior making this class
         *                        more flexible
         */
        function OpenlmisResource(uri, config) {
            this.uri = uri;
            this.config = config;
            var resourceUrl = uri;

            if (uri.slice(-1) === '/') {
                resourceUrl = uri.slice(0, -1);
            }

            resourceUrl = openlmisUrlFactory(resourceUrl);
            this.resourceUrl = resourceUrl;
            this.lastModified = undefined;

            this.resource = $resource(resourceUrl + '/:id', {}, {
                query: {
                    url: resourceUrl,
                    isArray: !isPaginated(config)
                },
                update: {
                    method: 'PUT'
                }
            });

            this.idParam = getIdParam(config);
            this.splitter = new ParameterSplitter();
            this.isVersioned = isVersioned(config);
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name get
         *
         * @description
         * Retrieves an object with the given ID.
         *
         * @param  {string}  id            the ID of the object
         * @param  {string}  versionNumber the optional version number of the object
         * @return {Promise}               the promise resolving to server response,
         *                                 rejects if ID is not given or if the request fails
         */
        function get(id, versionNumber) {
            if (id) {
                var resourceUrl = this.resourceUrl,
                    params = {
                        versionNumber: versionNumber
                    },
                    resource = this.resource;

                if (this.config && this.config.cache) {
                    resource = generateResource(resourceUrl, this.lastModified, this.config, params);
                }
                return resource.get({
                    id: id
                }).$promise;
            }
            return $q.reject();
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name getAll
         *
         * @description
         * Return the response of the GET request in a form of a list. Passes the given object as request parameters.
         *
         * @param  {Object}  params the map of request parameters
         * @return {Promise}        the promise resolving to the server response, rejected if request fails
         */
        function getAll(params) {
            var config = this.config;
            return this.query(params)
                .then(function(response) {
                    return isPaginated(config) ? response.content : response;
                });
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name query
         *
         * @description
         * Return the response of the GET request. Passes the given object as request parameters.
         *
         * @param  {Object}  params the map of request parameters
         * @return {Promise}        the promise resolving to the server response, rejected if request fails
         */
        function query(params) {
            var requests = [],
                resourceUrl = this.resourceUrl,
                config = this.config,
                resource = this.resource,
                lastModified = this.lastModified;

            this.splitter.split(this.uri, params)
                .forEach(function(params) {
                    if (config && config.cache && (!params || !isPageAndSortParams(params))) {
                        resource = generateResource(resourceUrl, lastModified, config, params);
                    }
                    requests.push(resource.query(params).$promise);
                });

            return $q.all(requests)
                .then(function(responses) {
                    if (responses[0] instanceof Array) {
                        return responses.reduce(function(left, right) {
                            right.forEach(function(item) {
                                left.push(item);
                            });
                            return left;
                        });
                    }

                    return responses.reduce(function(left, right) {
                        if (left.content.content === undefined) {
                            left.content = left.content.concat(right.content);
                            left.numberOfElements += right.numberOfElements;
                            left.totalElements += right.totalElements;
                        } else {
                            left.content.content = left.content.content.concat(right.content.content);
                            left.content.numberOfElements += right.content.numberOfElements;
                            left.content.totalElements += right.content.totalElements;
                        }
                        return left;
                    });
                });
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name update
         *
         * @description
         * Saves the given object on the OpenLMIS server. Uses PUT method.
         *
         * @param  {Object}  object the object to be saved on the server
         * @return {Promise}        the promise resolving to the server response, rejected if request fails or object is
         *                          undefined or if the ID is undefined
         */
        function update(object) {
            if (object) {
                var resourceUrl = this.resourceUrl,
                    resource = this.resource;

                if (this.config && this.config.cache) {
                    resource = generateResource(resourceUrl, undefined, this.config, undefined);
                }
                return resource.update({
                    id: object[this.idParam]
                }, object).$promise;
            }
            return $q.reject();
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name create
         *
         * @description
         * Creates the given object on the OpenLMIS server. Uses POST method.
         *
         * @param  {Object}  object        the object to be created on the server
         * @param  {Object}  customParams  the custom parameters to be passed to the request
         * @return {Promise}               the promise resolving to the server response, rejected if request fails
         */
        function create(object, customParams) {
            var resourceUrl = this.resourceUrl,
                resource = this.resource;

            if (this.config && this.config.cache) {
                resource = generateResource(resourceUrl, undefined, this.config, customParams);
            }
            return resource.save(customParams, object).$promise;
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name search
         *
         * @description
         * Search the given objects on the OpenLMIS server. Uses POST method.
         *
         * @param  {Object}  objectsList   the objects list to be searched on the server
         * @return {Promise}               the promise resolving to the server response, rejected if request fails
         */
        function search(objectsList) {
            if (objectsList) {
                var resourceUrl = this.resourceUrl;
                var resource = generateResource(resourceUrl, undefined, this.config, undefined);

                return resource.search(undefined, objectsList).$promise;
            }
            return $q.reject();
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name delete
         *
         * @description
         * Deletes the object on the OpenLMIS server.
         *
         * @param  {Object}  object the object to be deleted from the server
         * @return {Promise}        the promise resolving to the server response, rejected if request fails or object is
         *                          undefined or if the ID is undefined
         */
        function deleteObject(object) {
            var resourceUrl = this.resourceUrl,
                resource = this.resource;

            if (this.config && this.config.cache) {
                resource = generateResource(resourceUrl, {}, this.config, undefined);
            }
            if (object && object[this.idParam]) {
                return resource.delete({
                    id: object[this.idParam]
                }).$promise;
            }
            return $q.reject();
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name throwMethodNotSupported
         *
         * @description
         * Throws 'Method not supported' exception. Useful for overriding methods which are not supported by specific
         * endpoint.
         */
        function throwMethodNotSupported() {
            throw 'Method not supported';
        }

        function isPaginated(config) {
            return !config || config.paginated || config.paginated === undefined;
        }

        function getIdParam(config) {
            if (config) {
                return config.idParam || 'id';
            }
            return 'id';
        }

        function generateResource(resourceUrl, headerValue, config, params) {
            var header = {};

            if (headerValue) {
                header['If-Modified-Since'] = headerValue;
            }

            return $resource(resourceUrl + '/:id', params, {
                get: {
                    method: 'GET',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    },
                    headers: header,
                    isArray: !isPaginated(config)
                },
                query: {
                    url: resourceUrl,
                    method: 'GET',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    },
                    headers: header,
                    isArray: !isPaginated(config)
                },
                update: {
                    method: 'PUT',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    }
                },
                save: {
                    method: 'POST',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    }
                },
                search: {
                    method: 'POST',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    }
                },
                delete: {
                    method: 'DELETE',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    }
                }
            });
        }

        function transformJson(data) {
            if (data) {
                return angular.fromJson(data);
            }
            return data;
        }

        function transformResponse(data, headers, status, config) {
            var response = {};
            data = transformJson(data);
            response.content = data;

            if (response.content) {
                if (response.content.content) {
                    response.content.content.forEach(function(doc) {
                        doc.lastModified = headers('last-modified');
                        doc._id = isVersioned(config) ? doc.id + '/' + doc.meta.versionNumber : doc.id;
                    });
                } else if (response.content instanceof Array) {
                    response.content.forEach(function(doc) {
                        doc.lastModified = headers('last-modified');
                        doc._id = isVersioned(config) ? doc.id + '/'
                            + doc.meta.versionNumber : doc.id;
                    });
                } else {
                    response.content.lastModified = headers('last-modified');
                    response.content._id = isVersioned(config) ? response.content.id + '/'
                        + response.content.meta.versionNumber : response.content.id;
                }
                response.lastModified = headers('last-modified');
            }
            response.status = status;
            return response;
        }

        function isVersioned(config) {
            return config && config.versioned;
        }

        function isPageAndSortParams(params) {
            return params.sort !== undefined && params.page !== undefined;
        }
    }
})();
<commit_msg>Revert "Revert "OLMIS-6949: Moved reduntant reduce content to separate function""<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 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 Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc service
     * @name openlmis-repository.OpenlmisResource
     *
     * @description
     * Generic repository for communicating with the OpenLMIS RESTful endpoints.
     */
    angular
        .module('openlmis-repository')
        .factory('OpenlmisResource', OpenlmisResource);

    OpenlmisResource.$inject = ['$resource', '$q', 'MAX_URI_LENGTH', 'openlmisUrlFactory', 'ParameterSplitter'];

    function OpenlmisResource($resource, $q, MAX_URI_LENGTH, openlmisUrlFactory, ParameterSplitter) {

        OpenlmisResource.prototype.query = query;
        OpenlmisResource.prototype.get = get;
        OpenlmisResource.prototype.getAll = getAll;
        OpenlmisResource.prototype.update = update;
        OpenlmisResource.prototype.create = create;
        OpenlmisResource.prototype.delete = deleteObject;
        OpenlmisResource.prototype.search = search;
        OpenlmisResource.prototype.throwMethodNotSupported = throwMethodNotSupported;

        return OpenlmisResource;

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name OpenlmisResource
         * @constructor
         *
         * @description
         * Creates an instance of the OpenlmisResource class.
         *
         * Configuration options:
         * - paginated - flag defining whether response returned by the query request is paginated; defaults to true
         *
         * @param {String} uri    the URI pointing to the resource
         * @param {Object} config the optional configuration object, modifies the default behavior making this class
         *                        more flexible
         */
        function OpenlmisResource(uri, config) {
            this.uri = uri;
            this.config = config;
            var resourceUrl = uri;

            if (uri.slice(-1) === '/') {
                resourceUrl = uri.slice(0, -1);
            }

            resourceUrl = openlmisUrlFactory(resourceUrl);
            this.resourceUrl = resourceUrl;
            this.lastModified = undefined;

            this.resource = $resource(resourceUrl + '/:id', {}, {
                query: {
                    url: resourceUrl,
                    isArray: !isPaginated(config)
                },
                update: {
                    method: 'PUT'
                }
            });

            this.idParam = getIdParam(config);
            this.splitter = new ParameterSplitter();
            this.isVersioned = isVersioned(config);
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name get
         *
         * @description
         * Retrieves an object with the given ID.
         *
         * @param  {string}  id            the ID of the object
         * @param  {string}  versionNumber the optional version number of the object
         * @return {Promise}               the promise resolving to server response,
         *                                 rejects if ID is not given or if the request fails
         */
        function get(id, versionNumber) {
            if (id) {
                var resourceUrl = this.resourceUrl,
                    params = {
                        versionNumber: versionNumber
                    },
                    resource = this.resource;

                if (this.config && this.config.cache) {
                    resource = generateResource(resourceUrl, this.lastModified, this.config, params);
                }
                return resource.get({
                    id: id
                }).$promise;
            }
            return $q.reject();
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name getAll
         *
         * @description
         * Return the response of the GET request in a form of a list. Passes the given object as request parameters.
         *
         * @param  {Object}  params the map of request parameters
         * @return {Promise}        the promise resolving to the server response, rejected if request fails
         */
        function getAll(params) {
            var config = this.config;
            return this.query(params)
                .then(function(response) {
                    return isPaginated(config) ? response.content : response;
                });
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name query
         *
         * @description
         * Return the response of the GET request. Passes the given object as request parameters.
         *
         * @param  {Object}  params the map of request parameters
         * @return {Promise}        the promise resolving to the server response, rejected if request fails
         */
        function query(params) {
            var requests = [],
                resourceUrl = this.resourceUrl,
                config = this.config,
                resource = this.resource,
                lastModified = this.lastModified;

            this.splitter.split(this.uri, params)
                .forEach(function(params) {
                    if (config && config.cache && (!params || !isPageAndSortParams(params))) {
                        resource = generateResource(resourceUrl, lastModified, config, params);
                    }
                    requests.push(resource.query(params).$promise);
                });

            return $q.all(requests)
                .then(function(responses) {
                    if (responses[0] instanceof Array) {
                        return responses.reduce(function(left, right) {
                            right.forEach(function(item) {
                                left.push(item);
                            });
                            return left;
                        });
                    }

                    return responses.reduce(function(left, right) {
                        if (left.content.content) {
                            left.content = shortenMerge(left.content, right.content);
                        } else {
                            left = shortenMerge(left, right);
                        }
                        return left;
                    });
                });
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name update
         *
         * @description
         * Saves the given object on the OpenLMIS server. Uses PUT method.
         *
         * @param  {Object}  object the object to be saved on the server
         * @return {Promise}        the promise resolving to the server response, rejected if request fails or object is
         *                          undefined or if the ID is undefined
         */
        function update(object) {
            if (object) {
                var resourceUrl = this.resourceUrl,
                    resource = this.resource;

                if (this.config && this.config.cache) {
                    resource = generateResource(resourceUrl, undefined, this.config, undefined);
                }
                return resource.update({
                    id: object[this.idParam]
                }, object).$promise;
            }
            return $q.reject();
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name create
         *
         * @description
         * Creates the given object on the OpenLMIS server. Uses POST method.
         *
         * @param  {Object}  object        the object to be created on the server
         * @param  {Object}  customParams  the custom parameters to be passed to the request
         * @return {Promise}               the promise resolving to the server response, rejected if request fails
         */
        function create(object, customParams) {
            var resourceUrl = this.resourceUrl,
                resource = this.resource;

            if (this.config && this.config.cache) {
                resource = generateResource(resourceUrl, undefined, this.config, customParams);
            }
            return resource.save(customParams, object).$promise;
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name search
         *
         * @description
         * Search the given objects on the OpenLMIS server. Uses POST method.
         *
         * @param  {Object}  objectsList   the objects list to be searched on the server
         * @return {Promise}               the promise resolving to the server response, rejected if request fails
         */
        function search(objectsList) {
            if (objectsList) {
                var resourceUrl = this.resourceUrl;
                var resource = generateResource(resourceUrl, undefined, this.config, undefined);

                return resource.search(undefined, objectsList).$promise;
            }
            return $q.reject();
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name delete
         *
         * @description
         * Deletes the object on the OpenLMIS server.
         *
         * @param  {Object}  object the object to be deleted from the server
         * @return {Promise}        the promise resolving to the server response, rejected if request fails or object is
         *                          undefined or if the ID is undefined
         */
        function deleteObject(object) {
            var resourceUrl = this.resourceUrl,
                resource = this.resource;

            if (this.config && this.config.cache) {
                resource = generateResource(resourceUrl, {}, this.config, undefined);
            }
            if (object && object[this.idParam]) {
                return resource.delete({
                    id: object[this.idParam]
                }).$promise;
            }
            return $q.reject();
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-repository.OpenlmisResource
         * @name throwMethodNotSupported
         *
         * @description
         * Throws 'Method not supported' exception. Useful for overriding methods which are not supported by specific
         * endpoint.
         */
        function throwMethodNotSupported() {
            throw 'Method not supported';
        }

        function isPaginated(config) {
            return !config || config.paginated || config.paginated === undefined;
        }

        function getIdParam(config) {
            if (config) {
                return config.idParam || 'id';
            }
            return 'id';
        }

        function generateResource(resourceUrl, headerValue, config, params) {
            var header = {};

            if (headerValue) {
                header['If-Modified-Since'] = headerValue;
            }

            return $resource(resourceUrl + '/:id', params, {
                get: {
                    method: 'GET',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    },
                    headers: header,
                    isArray: !isPaginated(config)
                },
                query: {
                    url: resourceUrl,
                    method: 'GET',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    },
                    headers: header,
                    isArray: !isPaginated(config)
                },
                update: {
                    method: 'PUT',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    }
                },
                save: {
                    method: 'POST',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    }
                },
                search: {
                    method: 'POST',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    }
                },
                delete: {
                    method: 'DELETE',
                    transformResponse: function(data, headers, status) {
                        return transformResponse(data, headers, status, config);
                    }
                }
            });
        }

        function transformJson(data) {
            if (data) {
                return angular.fromJson(data);
            }
            return data;
        }

        function transformResponse(data, headers, status, config) {
            var response = {};
            data = transformJson(data);
            response.content = data;

            if (response.content) {
                if (response.content.content) {
                    response.content.content.forEach(function(doc) {
                        doc.lastModified = headers('last-modified');
                        doc._id = isVersioned(config) ? doc.id + '/' + doc.meta.versionNumber : doc.id;
                    });
                } else if (response.content instanceof Array) {
                    response.content.forEach(function(doc) {
                        doc.lastModified = headers('last-modified');
                        doc._id = isVersioned(config) ? doc.id + '/'
                            + doc.meta.versionNumber : doc.id;
                    });
                } else {
                    response.content.lastModified = headers('last-modified');
                    response.content._id = isVersioned(config) ? response.content.id + '/'
                        + response.content.meta.versionNumber : response.content.id;
                }
                response.lastModified = headers('last-modified');
            }
            response.status = status;
            return response;
        }

        function isVersioned(config) {
            return config && config.versioned;
        }

        function isPageAndSortParams(params) {
            return params.sort !== undefined && params.page !== undefined;
        }

        function shortenMerge(left, right) {
            left.content = left.content.concat(right.content);
            left.numberOfElements += right.numberOfElements;
            left.totalElements += right.totalElements;
            return left;
        }
    }
})();
<|endoftext|>


<commit_before>import React, { memo } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { useIntl } from 'react-intl';
import { Select, Option } from '@strapi/design-system/Select';
import { Box } from '@strapi/design-system/Box';
import { useTracking } from '@strapi/helper-plugin';
import { onChangeListHeaders } from '../actions';
import { selectDisplayedHeaders } from '../selectors';
import getAllAllowedHeaders from './utils/getAllAllowedHeader';

const FieldPicker = ({ layout }) => {
  const dispatch = useDispatch();
  const displayedHeaders = useSelector(selectDisplayedHeaders);
  const { trackUsage } = useTracking();
  const { formatMessage } = useIntl();

  const allAllowedHeaders = getAllAllowedHeaders(layout.contentType.attributes).map(attrName => {
    const metadatas = layout.contentType.metadatas[attrName].list;

    return {
      name: attrName,
      intlLabel: { id: metadatas.label, defaultMessage: metadatas.label },
    };
  });
  const values = displayedHeaders.map(({ name }) => name);

  const handleChange = updatedValues => {
    // removing a header
    if (updatedValues.length < values.length) {
      const removedHeader = values.filter(value => {
        return updatedValues.indexOf(value) === -1;
      });

      dispatch(onChangeListHeaders({ name: removedHeader[0], value: true }));
    } else {
      trackUsage('didChangeDisplayedFields');
      const addedHeader = updatedValues.filter(value => {
        return values.indexOf(value) === -1;
      });

      dispatch(onChangeListHeaders({ name: addedHeader[0], value: false }));
    }
  };

  return (
    <Box paddingLeft={3}>
      <Select
        aria-label="change displayed fields"
        value={values}
        onChange={handleChange}
        customizeContent={values => `${values.length} currently selected`}
        multi
        size="S"
      >
        {allAllowedHeaders.map(header => {
          return (
            <Option key={header.name} value={header.name}>
              {formatMessage({
                id: header.intlLabel.id || header.name,
                defaultMessage: header.intlLabel.defaultMessage || header.name,
              })}
            </Option>
          );
        })}
      </Select>
    </Box>
  );
};

FieldPicker.propTypes = {
  layout: PropTypes.shape({
    contentType: PropTypes.shape({
      attributes: PropTypes.object.isRequired,
      metadatas: PropTypes.object.isRequired,
      info: PropTypes.shape({ label: PropTypes.string.isRequired }).isRequired,
      layouts: PropTypes.shape({
        list: PropTypes.array.isRequired,
        editRelations: PropTypes.array,
      }).isRequired,
      options: PropTypes.object.isRequired,
      settings: PropTypes.object.isRequired,
    }).isRequired,
  }).isRequired,
};

export default memo(FieldPicker);
<commit_msg>Fix button alignments<commit_after>import React, { memo } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { useIntl } from 'react-intl';
import { Select, Option } from '@strapi/design-system/Select';
import { Box } from '@strapi/design-system/Box';
import { useTracking } from '@strapi/helper-plugin';
import { onChangeListHeaders } from '../actions';
import { selectDisplayedHeaders } from '../selectors';
import getAllAllowedHeaders from './utils/getAllAllowedHeader';

const FieldPicker = ({ layout }) => {
  const dispatch = useDispatch();
  const displayedHeaders = useSelector(selectDisplayedHeaders);
  const { trackUsage } = useTracking();
  const { formatMessage } = useIntl();

  const allAllowedHeaders = getAllAllowedHeaders(layout.contentType.attributes).map(attrName => {
    const metadatas = layout.contentType.metadatas[attrName].list;

    return {
      name: attrName,
      intlLabel: { id: metadatas.label, defaultMessage: metadatas.label },
    };
  });
  const values = displayedHeaders.map(({ name }) => name);

  const handleChange = updatedValues => {
    // removing a header
    if (updatedValues.length < values.length) {
      const removedHeader = values.filter(value => {
        return updatedValues.indexOf(value) === -1;
      });

      dispatch(onChangeListHeaders({ name: removedHeader[0], value: true }));
    } else {
      trackUsage('didChangeDisplayedFields');
      const addedHeader = updatedValues.filter(value => {
        return values.indexOf(value) === -1;
      });

      dispatch(onChangeListHeaders({ name: addedHeader[0], value: false }));
    }
  };

  return (
    <Box>
      <Select
        aria-label="change displayed fields"
        value={values}
        onChange={handleChange}
        customizeContent={values => `${values.length} currently selected`}
        multi
        size="S"
      >
        {allAllowedHeaders.map(header => {
          return (
            <Option key={header.name} value={header.name}>
              {formatMessage({
                id: header.intlLabel.id || header.name,
                defaultMessage: header.intlLabel.defaultMessage || header.name,
              })}
            </Option>
          );
        })}
      </Select>
    </Box>
  );
};

FieldPicker.propTypes = {
  layout: PropTypes.shape({
    contentType: PropTypes.shape({
      attributes: PropTypes.object.isRequired,
      metadatas: PropTypes.object.isRequired,
      info: PropTypes.shape({ label: PropTypes.string.isRequired }).isRequired,
      layouts: PropTypes.shape({
        list: PropTypes.array.isRequired,
        editRelations: PropTypes.array,
      }).isRequired,
      options: PropTypes.object.isRequired,
      settings: PropTypes.object.isRequired,
    }).isRequired,
  }).isRequired,
};

export default memo(FieldPicker);
<|endoftext|>


<commit_before>/**
 * Copyright © 2011-2014 EMBL - European Bioinformatics Institute
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * functions used for processing user input via SOLR calls. Process the response and
 * displays the results as facets on the left bar.
 *
 */

(function($){

	function _updateFacetCount(facet, facetResponse, facetMode){
		//var num = facetMode ? '' : facetResponse.response.numFound;
		num = facetResponse.response.numFound;
		$('div.flist li#' + facet + ' span.fcount').html(num);
	}

	var jsonBase = MPI2.searchAndFacetConfig.facetParams;

	$.fn.fetchSolrFacetCount = function(oUrlHashParams){

		var q = oUrlHashParams.q;
		if ( typeof q == 'undefined' ){
			// check search kw
			if ( window.location.search != '' ){
				q = window.location.search.replace(/&.+/, '').replace('?q=','');
				$('input#s').val(decodeURI(q));
			}
			else {
				q = '*:*';
			}
		}

		q = decodeURI(q);
		console.log('test q: '+ q');

		if ( oUrlHashParams.fq ){
			jsonBase.geneFacet.filterParams = {'fq': $.fn.fieldNameMapping(oUrlHashParams.fq, 'gene')};
		}

		var facetMode = oUrlHashParams.facetName;
		var oFacets = {};
		oFacets.count = {};

		jsonBase.geneFacet.srchParams.q = q;
		// console.log($.extend({}, jsonBase.geneFacet.srchParams, jsonBase.geneFacet.filterParams));
	 	// facet types are done sequencially; starting from gene
	    $.ajax({
	    		url: solrUrl + '/gene/select',
	       	   // data: $.extend({}, jsonBase.geneFacet.srchParams, oUrlHashParams.fq ? jsonBase.geneFacet.filterParams = {'fq': oUrlHashParams.fq} : jsonBase.geneFacet.filterParams),
	    		data: $.extend({}, jsonBase.geneFacet.srchParams, jsonBase.geneFacet.filterParams),
	       	    dataType: 'jsonp',
	       	    jsonp: 'json.wrf',
	       	    timeout: 5000,
	       	    success: function (geneResponse) {
	       	    	//console.log(geneResponse);
	       	    	$('div.flist li#gene span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
	       	    	oFacets.count.gene = geneResponse.response.numFound;
	       	    	_updateFacetCount('gene', geneResponse, facetMode);
	       	    	_doMPAutoSuggest(geneResponse, q, oFacets, facetMode, oUrlHashParams.fq);
	       	    },
	       	    error: function (jqXHR, textStatus, errorThrown) {
	       	        $('div#facetSrchMsg').html('Error fetching data ...');
	       	    }
	    });
	}

	function _doMPAutoSuggest(geneResponse, q, oFacets, facetMode, fq){

		jsonBase.mpFacet.srchParams.q = q;
		if ( fq ){
			jsonBase.mpFacet.filterParams = {'fq': $.fn.fieldNameMapping(fq, 'mp')};
		}

		$.ajax({
    	    url: solrUrl + '/mp/select',
    	    data: $.extend({}, jsonBase.mpFacet.srchParams, jsonBase.mpFacet.filterParams),
    	    dataType: 'jsonp',
    	    jsonp: 'json.wrf',
    	    timeout: 5000,
    	    success: function (mpResponse) {
    	    	//console.log(mpResponse);
    	    	$('div.flist li#mp span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
       	    	oFacets.count.mp = mpResponse.response.numFound;
       	    	_updateFacetCount('mp', mpResponse, facetMode);
    	    	_doDiseaseAutoSuggest(geneResponse, mpResponse, q, oFacets, facetMode,fq);
    	    },
    	    error: function (jqXHR, textStatus, errorThrown) {
				$('div#facetSrchMsg').html('Error fetching data ...');
			}
		});
	}
	function _doDiseaseAutoSuggest(geneResponse, mpResponse, q, oFacets, facetMode, fq){

		jsonBase.diseaseFacet.srchParams.q = q;
		if ( fq ){
			jsonBase.diseaseFacet.filterParams = {'fq': $.fn.fieldNameMapping(fq, 'disease')};
		}

		//console.log($.fn.stringifyJsonAsUrlParams(jsonBase.diseaseFacet.srchParams));
		$.ajax({
    	    url: solrUrl + '/disease/select',
    	    data: $.extend({}, jsonBase.diseaseFacet.srchParams, jsonBase.diseaseFacet.filterParams),
    	    dataType: 'jsonp',
    	    jsonp: 'json.wrf',
    	    timeout: 10000,
    	    success: function (diseaseResponse) {
    	    	$('div.flist li#disease span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
    	    	oFacets.count.disease = diseaseResponse.response.numFound;
    	    	_updateFacetCount('disease', diseaseResponse, facetMode);
    	    	_doTissueAutoSuggest(geneResponse, mpResponse, diseaseResponse, q, oFacets, facetMode, fq);
    	    },
			error: function (jqXHR, textStatus, errorThrown) {
				$('div#facetSrchMsg').html('Error fetching data ...');
			}
		});
	}

	function _doTissueAutoSuggest(geneResponse, mpResponse, diseaseResponse, q, oFacets, facetMode, fq){
		jsonBase.maFacet.srchParams.q = q;
		jsonBase.maFacet.srchParams.sort = 'ma_term asc';
		if ( fq ){
			jsonBase.maFacet.filterParams = {'fq': $.fn.fieldNameMapping(fq, 'ma')};
		}
		$.ajax({
    	    url: solrUrl + '/ma/select',
    	    data: $.extend({}, jsonBase.maFacet.srchParams, jsonBase.maFacet.filterParams),
    	    dataType: 'jsonp',
    	    jsonp: 'json.wrf',
    	    timeout: 10000,
    	    success: function (maResponse) {

    	    	$('div.flist li#ma span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
    	    	oFacets.count.ma = maResponse.response.numFound;
    	    	_updateFacetCount('ma', maResponse, facetMode);
    	    	_doPipelineAutoSuggest(geneResponse, mpResponse, diseaseResponse, maResponse, q, oFacets, facetMode, fq);
    	    },
			error: function (jqXHR, textStatus, errorThrown) {
				$('div#facetSrchMsg').html('Error fetching data ...');
			}
		});
	}

	function _doPipelineAutoSuggest(geneResponse, mpResponse, diseaseResponse, maResponse, q, oFacets, facetMode, fq){

		jsonBase.pipelineFacet.srchParams.q = q;
		if ( fq ){
			jsonBase.pipelineFacet.filterParams = {'fq': $.fn.fieldNameMapping(fq, 'pipeline')};
		}

		$.ajax({
    	    url: solrUrl + '/pipeline/select',
    	    data: $.extend({}, jsonBase.pipelineFacet.srchParams, jsonBase.pipelineFacet.filterParams),
    	    dataType: 'jsonp',
    	    jsonp: 'json.wrf',
    	    timeout: 5000,
    	    success: function (pipelineResponse) {
    	    	$('div.flist li#pipeline span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
    	    	oFacets.count.pipeline = pipelineResponse.response.numFound;
    	    	_updateFacetCount('pipeline', pipelineResponse, facetMode);
    	    	_doImageAutosuggest(geneResponse, mpResponse, diseaseResponse, maResponse, pipelineResponse, q, oFacets, facetMode, fq);
    	    },
			error: function (jqXHR, textStatus, errorThrown) {
				$('div#facetSrchMsg').html('Error fetching data ...');
			}
		});
	}

	function _doImageAutosuggest(geneResponse, mpResponse, diseaseResponse, maResponse, pipelineResponse, q, oFacets, facetMode, fq){

		jsonBase.imagesFacet.srchParams.q = q;
		if ( fq ){
			jsonBase.imagesFacet.filterParams = {'fq': $.fn.fieldNameMapping(fq, 'images')};
		}
		$.ajax({
    	    url: solrUrl + '/images/select',
    	    data: $.extend({}, jsonBase.imagesFacet.srchParams, jsonBase.imagesFacet.filterParams),
    	    dataType: 'jsonp',
    	    jsonp: 'json.wrf',
    	    timeout: 5000,
    	    success: function (imagesResponse) {
    	    	$('div.flist li#images span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
    	    	oFacets.count.images = imagesResponse.response.numFound;
    	    	_updateFacetCount('images', imagesResponse, facetMode);

    	    	/* now check which core needs to be displayed by default in the order of
    	    	 * gene -> mp -> ma -> pipeline -> images -> disease
    	    	 * ie, fetch facet full result for that facet and display only facet count for the rest of the facets
    	    	 * Other facet results will be fetched on demand */
    	    	var hashParams = $.fn.parseHashString(window.location.hash.substring(1));

    	    	var coreName, facetName;

    	    	if ( hashParams.coreName ){
    	    		coreName = hashParams.coreName;
    	    	}
    	    	else if (hashParams.facetName ){
    	    		facetName = hashParams.facetName;
    	    	}
    	    	else {
    	    		coreName = _setSearchMode(oFacets.count);
    	    	}

    	    	$('div#facetSrchMsg').html(' ');

    	    	if ( ! coreName && ! facetName ){
    	    		// nothing found
    	    		$('div#mpi2-search').html('INFO: Search keyword "' + decodeURI(q) + '" has returned no entry in the database');
    	    	}
    	    	else {
    	        	// remove all previous facet results before loading new facet results
    	    		var thisCore = coreName ? coreName : facetName;
    	        	$('li.fmcat > ul').html('');

    	        	//var widgetName = coreName+'Facet';
    	        	var widgetName = thisCore+'Facet';
    	        	hashParams.fq = hashParams.fq ? hashParams.fq : jsonBase[widgetName].fq;
    	        	hashParams.widgetName = widgetName;
    	        	hashParams.q = q;

    	        	window.jQuery('li#' + thisCore)[widgetName]({
    					data: {
    							core: coreName,
    							//qf: jsonBase[widgetName].qf,
    							facetCount: oFacets.count[thisCore],
    							hashParams: hashParams
    							},
    			        geneGridElem: 'div#mpi2-search'
    				});

    	        	// load none-zero facet results on demand
    	        	var aCores = MPI2.searchAndFacetConfig.cores;

    	        	//delete active core, no need to invoke again

    	        	var index;// = aCores.indexOf(coreName);
    	        	for ( var i=0; i< aCores.length; i++){
    	        		if (aCores[i] == thisCore ){
    	        			index = i;
    	        		}
    	        	}
    	        	aCores.splice(index, 1); // remove core that has the index result already in dataTable

    	        	for ( var i=0; i< aCores.length; i++){
    	        		var core = aCores[i];
    	        		if ( oFacets.count[core] != 0 ){
    	        			_prepareCores(core, q, oFacets);
    	        		}
    	        	}
    	    	}
    	    },
			error: function (jqXHR, textStatus, errorThrown) {
				$('div#facetSrchMsg').html('Error fetching data ...');
			}
		});
	}

	function _prepareCores(core, q, oFacets){

		var widgetName = core + 'Facet';

		window.jQuery('li#' + core).click(function(){

			var $this = window.jQuery(this);

			// check widget has not been created
			if ( typeof $this.data(widgetName) === 'undefined' ){
				var hashParams = {};

				//window.location.hash = $.fn.stringifyJsonAsUrlParams(hashParams);
				hashParams.fq = jsonBase[widgetName].fq;
	        	hashParams.widgetName = widgetName;
	        	hashParams.q = q;

				//if ( $this.find('.facetCatList').html() == '' && $this.find('span.facetCount').text() != '0' ){
				if ( $this.find('ul').html() == '' && $this.find('span.fcount').text() != '0' ){
					$this[widgetName]({
						data: {
							core: core,
							//qf: jsonBase[core + 'Facet'].qf,
							facetCount: oFacets.count[core],
							hashParams: hashParams
							},
							geneGridElem: 'div#mpi2-search'
					});
				}
			}
		});
	}

	function _setSearchMode(oCounts){

		// priority order of facet to be opened based on search result
		if ( oCounts.gene != 0 ){
			return 'gene';
		}
		else if ( oCounts.mp != 0){
			return 'mp';
		}
		else if ( oCounts.disease != 0 ){
			return 'disease';
		}
		else if ( oCounts.ma != 0){
			return 'ma';
		}
		else if ( oCounts.pipeline != 0 ){
			return 'pipeline';
		}
		else if ( oCounts.images != 0 ){
			return 'images';
		}
		else {
			return false; // nothing found
		}
	}

})(jQuery);
<commit_msg>fixed typo<commit_after>/**
 * Copyright © 2011-2014 EMBL - European Bioinformatics Institute
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.
 *
 * functions used for processing user input via SOLR calls. Process the response and
 * displays the results as facets on the left bar.
 *
 */

(function($){

	function _updateFacetCount(facet, facetResponse, facetMode){
		//var num = facetMode ? '' : facetResponse.response.numFound;
		num = facetResponse.response.numFound;
		$('div.flist li#' + facet + ' span.fcount').html(num);
	}

	var jsonBase = MPI2.searchAndFacetConfig.facetParams;

	$.fn.fetchSolrFacetCount = function(oUrlHashParams){

		var q = oUrlHashParams.q;
		if ( typeof q == 'undefined' ){
			// check search kw
			if ( window.location.search != '' ){
				q = window.location.search.replace(/&.+/, '').replace('?q=','');
				$('input#s').val(decodeURI(q));
			}
			else {
				q = '*:*';
			}
		}

		q = decodeURI(q);
		console.log('test q: '+ q);

		if ( oUrlHashParams.fq ){
			jsonBase.geneFacet.filterParams = {'fq': $.fn.fieldNameMapping(oUrlHashParams.fq, 'gene')};
		}

		var facetMode = oUrlHashParams.facetName;
		var oFacets = {};
		oFacets.count = {};

		jsonBase.geneFacet.srchParams.q = q;
		// console.log($.extend({}, jsonBase.geneFacet.srchParams, jsonBase.geneFacet.filterParams));
	 	// facet types are done sequencially; starting from gene
	    $.ajax({
	    		url: solrUrl + '/gene/select',
	       	   // data: $.extend({}, jsonBase.geneFacet.srchParams, oUrlHashParams.fq ? jsonBase.geneFacet.filterParams = {'fq': oUrlHashParams.fq} : jsonBase.geneFacet.filterParams),
	    		data: $.extend({}, jsonBase.geneFacet.srchParams, jsonBase.geneFacet.filterParams),
	       	    dataType: 'jsonp',
	       	    jsonp: 'json.wrf',
	       	    timeout: 5000,
	       	    success: function (geneResponse) {
	       	    	//console.log(geneResponse);
	       	    	$('div.flist li#gene span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
	       	    	oFacets.count.gene = geneResponse.response.numFound;
	       	    	_updateFacetCount('gene', geneResponse, facetMode);
	       	    	_doMPAutoSuggest(geneResponse, q, oFacets, facetMode, oUrlHashParams.fq);
	       	    },
	       	    error: function (jqXHR, textStatus, errorThrown) {
	       	        $('div#facetSrchMsg').html('Error fetching data ...');
	       	    }
	    });
	}

	function _doMPAutoSuggest(geneResponse, q, oFacets, facetMode, fq){

		jsonBase.mpFacet.srchParams.q = q;
		if ( fq ){
			jsonBase.mpFacet.filterParams = {'fq': $.fn.fieldNameMapping(fq, 'mp')};
		}

		$.ajax({
    	    url: solrUrl + '/mp/select',
    	    data: $.extend({}, jsonBase.mpFacet.srchParams, jsonBase.mpFacet.filterParams),
    	    dataType: 'jsonp',
    	    jsonp: 'json.wrf',
    	    timeout: 5000,
    	    success: function (mpResponse) {
    	    	//console.log(mpResponse);
    	    	$('div.flist li#mp span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
       	    	oFacets.count.mp = mpResponse.response.numFound;
       	    	_updateFacetCount('mp', mpResponse, facetMode);
    	    	_doDiseaseAutoSuggest(geneResponse, mpResponse, q, oFacets, facetMode,fq);
    	    },
    	    error: function (jqXHR, textStatus, errorThrown) {
				$('div#facetSrchMsg').html('Error fetching data ...');
			}
		});
	}
	function _doDiseaseAutoSuggest(geneResponse, mpResponse, q, oFacets, facetMode, fq){

		jsonBase.diseaseFacet.srchParams.q = q;
		if ( fq ){
			jsonBase.diseaseFacet.filterParams = {'fq': $.fn.fieldNameMapping(fq, 'disease')};
		}

		//console.log($.fn.stringifyJsonAsUrlParams(jsonBase.diseaseFacet.srchParams));
		$.ajax({
    	    url: solrUrl + '/disease/select',
    	    data: $.extend({}, jsonBase.diseaseFacet.srchParams, jsonBase.diseaseFacet.filterParams),
    	    dataType: 'jsonp',
    	    jsonp: 'json.wrf',
    	    timeout: 10000,
    	    success: function (diseaseResponse) {
    	    	$('div.flist li#disease span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
    	    	oFacets.count.disease = diseaseResponse.response.numFound;
    	    	_updateFacetCount('disease', diseaseResponse, facetMode);
    	    	_doTissueAutoSuggest(geneResponse, mpResponse, diseaseResponse, q, oFacets, facetMode, fq);
    	    },
			error: function (jqXHR, textStatus, errorThrown) {
				$('div#facetSrchMsg').html('Error fetching data ...');
			}
		});
	}

	function _doTissueAutoSuggest(geneResponse, mpResponse, diseaseResponse, q, oFacets, facetMode, fq){
		jsonBase.maFacet.srchParams.q = q;
		jsonBase.maFacet.srchParams.sort = 'ma_term asc';
		if ( fq ){
			jsonBase.maFacet.filterParams = {'fq': $.fn.fieldNameMapping(fq, 'ma')};
		}
		$.ajax({
    	    url: solrUrl + '/ma/select',
    	    data: $.extend({}, jsonBase.maFacet.srchParams, jsonBase.maFacet.filterParams),
    	    dataType: 'jsonp',
    	    jsonp: 'json.wrf',
    	    timeout: 10000,
    	    success: function (maResponse) {

    	    	$('div.flist li#ma span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
    	    	oFacets.count.ma = maResponse.response.numFound;
    	    	_updateFacetCount('ma', maResponse, facetMode);
    	    	_doPipelineAutoSuggest(geneResponse, mpResponse, diseaseResponse, maResponse, q, oFacets, facetMode, fq);
    	    },
			error: function (jqXHR, textStatus, errorThrown) {
				$('div#facetSrchMsg').html('Error fetching data ...');
			}
		});
	}

	function _doPipelineAutoSuggest(geneResponse, mpResponse, diseaseResponse, maResponse, q, oFacets, facetMode, fq){

		jsonBase.pipelineFacet.srchParams.q = q;
		if ( fq ){
			jsonBase.pipelineFacet.filterParams = {'fq': $.fn.fieldNameMapping(fq, 'pipeline')};
		}

		$.ajax({
    	    url: solrUrl + '/pipeline/select',
    	    data: $.extend({}, jsonBase.pipelineFacet.srchParams, jsonBase.pipelineFacet.filterParams),
    	    dataType: 'jsonp',
    	    jsonp: 'json.wrf',
    	    timeout: 5000,
    	    success: function (pipelineResponse) {
    	    	$('div.flist li#pipeline span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
    	    	oFacets.count.pipeline = pipelineResponse.response.numFound;
    	    	_updateFacetCount('pipeline', pipelineResponse, facetMode);
    	    	_doImageAutosuggest(geneResponse, mpResponse, diseaseResponse, maResponse, pipelineResponse, q, oFacets, facetMode, fq);
    	    },
			error: function (jqXHR, textStatus, errorThrown) {
				$('div#facetSrchMsg').html('Error fetching data ...');
			}
		});
	}

	function _doImageAutosuggest(geneResponse, mpResponse, diseaseResponse, maResponse, pipelineResponse, q, oFacets, facetMode, fq){

		jsonBase.imagesFacet.srchParams.q = q;
		if ( fq ){
			jsonBase.imagesFacet.filterParams = {'fq': $.fn.fieldNameMapping(fq, 'images')};
		}
		$.ajax({
    	    url: solrUrl + '/images/select',
    	    data: $.extend({}, jsonBase.imagesFacet.srchParams, jsonBase.imagesFacet.filterParams),
    	    dataType: 'jsonp',
    	    jsonp: 'json.wrf',
    	    timeout: 5000,
    	    success: function (imagesResponse) {
    	    	$('div.flist li#images span.fcount').html(MPI2.searchAndFacetConfig.searchSpin);
    	    	oFacets.count.images = imagesResponse.response.numFound;
    	    	_updateFacetCount('images', imagesResponse, facetMode);

    	    	/* now check which core needs to be displayed by default in the order of
    	    	 * gene -> mp -> ma -> pipeline -> images -> disease
    	    	 * ie, fetch facet full result for that facet and display only facet count for the rest of the facets
    	    	 * Other facet results will be fetched on demand */
    	    	var hashParams = $.fn.parseHashString(window.location.hash.substring(1));

    	    	var coreName, facetName;

    	    	if ( hashParams.coreName ){
    	    		coreName = hashParams.coreName;
    	    	}
    	    	else if (hashParams.facetName ){
    	    		facetName = hashParams.facetName;
    	    	}
    	    	else {
    	    		coreName = _setSearchMode(oFacets.count);
    	    	}

    	    	$('div#facetSrchMsg').html(' ');

    	    	if ( ! coreName && ! facetName ){
    	    		// nothing found
    	    		$('div#mpi2-search').html('INFO: Search keyword "' + decodeURI(q) + '" has returned no entry in the database');
    	    	}
    	    	else {
    	        	// remove all previous facet results before loading new facet results
    	    		var thisCore = coreName ? coreName : facetName;
    	        	$('li.fmcat > ul').html('');

    	        	//var widgetName = coreName+'Facet';
    	        	var widgetName = thisCore+'Facet';
    	        	hashParams.fq = hashParams.fq ? hashParams.fq : jsonBase[widgetName].fq;
    	        	hashParams.widgetName = widgetName;
    	        	hashParams.q = q;

    	        	window.jQuery('li#' + thisCore)[widgetName]({
    					data: {
    							core: coreName,
    							//qf: jsonBase[widgetName].qf,
    							facetCount: oFacets.count[thisCore],
    							hashParams: hashParams
    							},
    			        geneGridElem: 'div#mpi2-search'
    				});

    	        	// load none-zero facet results on demand
    	        	var aCores = MPI2.searchAndFacetConfig.cores;

    	        	//delete active core, no need to invoke again

    	        	var index;// = aCores.indexOf(coreName);
    	        	for ( var i=0; i< aCores.length; i++){
    	        		if (aCores[i] == thisCore ){
    	        			index = i;
    	        		}
    	        	}
    	        	aCores.splice(index, 1); // remove core that has the index result already in dataTable

    	        	for ( var i=0; i< aCores.length; i++){
    	        		var core = aCores[i];
    	        		if ( oFacets.count[core] != 0 ){
    	        			_prepareCores(core, q, oFacets);
    	        		}
    	        	}
    	    	}
    	    },
			error: function (jqXHR, textStatus, errorThrown) {
				$('div#facetSrchMsg').html('Error fetching data ...');
			}
		});
	}

	function _prepareCores(core, q, oFacets){

		var widgetName = core + 'Facet';

		window.jQuery('li#' + core).click(function(){

			var $this = window.jQuery(this);

			// check widget has not been created
			if ( typeof $this.data(widgetName) === 'undefined' ){
				var hashParams = {};

				//window.location.hash = $.fn.stringifyJsonAsUrlParams(hashParams);
				hashParams.fq = jsonBase[widgetName].fq;
	        	hashParams.widgetName = widgetName;
	        	hashParams.q = q;

				//if ( $this.find('.facetCatList').html() == '' && $this.find('span.facetCount').text() != '0' ){
				if ( $this.find('ul').html() == '' && $this.find('span.fcount').text() != '0' ){
					$this[widgetName]({
						data: {
							core: core,
							//qf: jsonBase[core + 'Facet'].qf,
							facetCount: oFacets.count[core],
							hashParams: hashParams
							},
							geneGridElem: 'div#mpi2-search'
					});
				}
			}
		});
	}

	function _setSearchMode(oCounts){

		// priority order of facet to be opened based on search result
		if ( oCounts.gene != 0 ){
			return 'gene';
		}
		else if ( oCounts.mp != 0){
			return 'mp';
		}
		else if ( oCounts.disease != 0 ){
			return 'disease';
		}
		else if ( oCounts.ma != 0){
			return 'ma';
		}
		else if ( oCounts.pipeline != 0 ){
			return 'pipeline';
		}
		else if ( oCounts.images != 0 ){
			return 'images';
		}
		else {
			return false; // nothing found
		}
	}

})(jQuery);
<|endoftext|>


<commit_before>/**
 * @constructor
 */
function FormProcessor() {
  'use strict';
  if ('undefined' === typeof jQuery) {
    throw new Error('Presto-Calc\'s JavaScript requires jQuery');
  }
  if ('undefined' === typeof Ladda) {
    throw new Error('Presto-Calc\'s JavaScript requires Ladda');
  }
}

FormProcessor.prototype = {
  constructor: FormProcessor,

  /**
   * @param $form
   * @param button
   */
  process: function ($form, button) {
    'use strict';

    jQuery('#results').remove();
    jQuery('#errors').remove();

    var l = Ladda.create(button);
    l.start();

    var startDateVal = $form.find('#startDate').val().split('-');
    var endDateVal = $form.find('#endDate').val().split('-');

    // In JS, 00 = January & 11 = December
    var data = {
      startDate:       new Date(startDateVal[0], startDateVal[1] - 1, startDateVal[2]),
      endDate:         new Date(endDateVal[0], endDateVal[1] - 1, endDateVal[2]),
      tripsWorkDay:    parseInt($form.find('#tripsWorkDay').val(), 10),
      tripsWeekendDay: parseInt($form.find('#tripsWeekendDay').val(), 10),
      costSingleTrip:  parseFloat($form.find('#prestoSingleTrip').val()),
      costMonthlyPass: parseFloat($form.find('#prestoMonthlyPass').val())
    };

    if (data.endDate - data.startDate < 1) {
      jQuery('
Your end date must be after your start date.
').insertBefore($form);
      l.stop();
      return false;
    }

    var curDate = data.startDate;
    var totalTrips = 0;
    var days = 0;
    while (curDate <= data.endDate) {
      days++;
      if (curDate.getDay() === 0 || curDate.getDay() === 6) {
        totalTrips += data.tripsWeekendDay;
      } else {
        totalTrips += data.tripsWorkDay;
      }
      curDate.setDate(curDate.getDate() + 1);
    }

    var $resultsDiv = jQuery('

Results

')
      .append('By our calculations, you will make ' + totalTrips + ' payable trips during the given period ('+days+' days).
');
    if (totalTrips * data.costSingleTrip > data.costMonthlyPass) {
      $resultsDiv.append(jQuery('You should buy your monthly pass!'));
    } else {
      $resultsDiv.append(jQuery('You should not buy your monthly pass!'));
    }
    $resultsDiv.append('
It would cost you ' + totalTrips * data.costSingleTrip + ' to pay for each trip individually.');

    $resultsDiv.insertBefore($form.parents('#config-form'));

    console.log(data);
    l.stop();
  }
};
<commit_msg>Fixed code style<commit_after>/**
 * @constructor
 */
function FormProcessor() {
  'use strict';
  if ('undefined' === typeof jQuery) {
    throw new Error('Presto-Calc\'s JavaScript requires jQuery');
  }
  if ('undefined' === typeof Ladda) {
    throw new Error('Presto-Calc\'s JavaScript requires Ladda');
  }
}

FormProcessor.prototype = {
  constructor: FormProcessor,

  /**
   * @param $form
   * @param button
   */
  process: function ($form, button) {
    'use strict';

    jQuery('#results').remove();
    jQuery('#errors').remove();

    var l = Ladda.create(button);
    l.start();

    var startDateVal = $form.find('#startDate').val().split('-');
    var endDateVal = $form.find('#endDate').val().split('-');

    // In JS, 00 = January & 11 = December
    var data = {
      startDate:       new Date(startDateVal[0], startDateVal[1] - 1, startDateVal[2]),
      endDate:         new Date(endDateVal[0], endDateVal[1] - 1, endDateVal[2]),
      tripsWorkDay:    parseInt($form.find('#tripsWorkDay').val(), 10),
      tripsWeekendDay: parseInt($form.find('#tripsWeekendDay').val(), 10),
      costSingleTrip:  parseFloat($form.find('#prestoSingleTrip').val()),
      costMonthlyPass: parseFloat($form.find('#prestoMonthlyPass').val())
    };

    if ((data.endDate - data.startDate) < 1) {
      jQuery('
Your end date must be after your start date.
').insertBefore($form);
      l.stop();
      return false;
    }

    var curDate = data.startDate;
    var totalTrips = 0;
    var days = 0;
    while (curDate <= data.endDate) {
      days++;
      if (curDate.getDay() === 0 || curDate.getDay() === 6) {
        totalTrips += data.tripsWeekendDay;
      } else {
        totalTrips += data.tripsWorkDay;
      }
      curDate.setDate(curDate.getDate() + 1);
    }

    var $resultsDiv = jQuery('

Results

')
      .append('By our calculations, you will make ' + totalTrips + ' payable trips during the given period ('+days+' days).
');
    if (totalTrips * data.costSingleTrip > data.costMonthlyPass) {
      $resultsDiv.append(jQuery('You should buy your monthly pass!'));
    } else {
      $resultsDiv.append(jQuery('You should not buy your monthly pass!'));
    }
    $resultsDiv.append('
It would cost you ' + totalTrips * data.costSingleTrip + ' to pay for each trip individually.');

    $form.parents('#config-form').before($resultsDiv);

    l.stop();
  }
};
<|endoftext|>


<commit_before>import StringManipulator from 'src/database/stringManipulation';
import exceptions from 'src/database/exceptions';
import constants from 'src/database/constants';
import DateTime from 'src/database/generated-data/dateTime';

const alasql = require('alasql');

const stringManipulator = new StringManipulator();
const dateTime = new DateTime();

function getDataOutOfAlasql(data) {
  return Object.values(data[0][0])[0];
}

function getSecondDataOutOfAlasql(data) {
  return Object.values(data[0][0])[1];
}

function getArray(data) {
  return data[0];
}

function getCurrentFilePath(fileId) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('SELECT ', constants.HEADER_FILE_MANAGER_PATH,
                                                   ' FROM ', constants.ENTITIES_FILE_MANAGER,
                                                   ' WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                   ' = ', fileId)])
    .then(filePath => resolve(filePath))
    .catch(sqlErr => reject(sqlErr))
  );
}

function getCurrentFolderPath(folderId) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('SELECT ', constants.HEADER_FOLDER_PATH,
                                                   ' FROM ', constants.ENTITIES_FOLDER,
                                                   ' WHERE ', constants.HEADER_FOLDER_FOLDER_ID,
                                                   ' = ', folderId)])
    .then(folderPath => resolve(folderPath))
    .catch(sqlErr => reject(sqlErr))
  );
}

// duplicate private function to help with cascadeChangeFilePath
function changeSingleFilePath(fileId, newPath) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('UPDATE ', constants.ENTITIES_FILE_MANAGER,
                                                   ' SET ', constants.HEADER_FILE_MANAGER_PATH,
                                                   ' = "', newPath,
                                                   '" WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                   ' = ', fileId)])
    .then(() => resolve())
    .catch(sqlError => reject(sqlError))
  );
}

function cascadeChangeFilePath(index, prevBasePath, newBasePath, fileArr) {
  return new Promise((resolve, reject) => {
    if (index >= fileArr.length) {
      return true;
    }
    const fileToChangePathIndex = Object.values(fileArr[index])[0];
    let newPath;
    return getCurrentFilePath(fileToChangePathIndex)
    .then((currentFilePath) => {
      const childPath = currentFilePath.toString().split(prevBasePath)[1];
      newPath = stringManipulator.stringConcat(newBasePath, childPath);
      return changeSingleFilePath(fileToChangePathIndex, newPath)
      .catch(sqlErr => reject(sqlErr));
    })
    .then(() => {
      cascadeChangeFilePath(index + 1, prevBasePath, newBasePath, fileArr)
      .catch(err => reject(err));
      resolve();
    })
    .catch(err => reject(err));
  });
}

function changeSingleFolderPath(folderId, newPath) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('UPDATE ', constants.ENTITIES_FOLDER,
                                                   ' SET ', constants.HEADER_FOLDER_PATH,
                                                   ' = "', newPath,
                                                   '" WHERE ', constants.HEADER_FOLDER_FOLDER_ID,
                                                   ' = ', folderId)])
    .then(() => resolve())
    .catch(sqlError => reject(sqlError))
  );
}

function changeSingleFolderName(folderId, newFolderName) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('UPDATE ', constants.ENTITIES_FOLDER,
                                                   ' SET ', constants.HEADER_FOLDER_FOLDER_NAME,
                                                   ' = "', newFolderName,
                                                   '" WHERE ', constants.HEADER_FOLDER_FOLDER_ID,
                                                   ' = ', folderId)])
    .then(() => resolve())
    .catch(sqlError => reject(sqlError))
  );
}

function cascadeChangeFolderPath(index, prevBasePath, newBasePath, folderArr) {
  return new Promise((resolve, reject) => {
    if (index >= folderArr.length) {
      return true;
    }
    const folderToChangePathIndex = Object.values(folderArr[index])[0];
    let newPath;
    return getCurrentFolderPath(folderToChangePathIndex)
    .then((currentFolderPath) => {
      const childPath = currentFolderPath.toString().split(prevBasePath)[1];
      newPath = stringManipulator.stringConcat(newBasePath, childPath);
      return changeSingleFolderPath(folderToChangePathIndex, newPath)
      .catch(sqlErr => reject(sqlErr));
    })
    .then(() => {
      cascadeChangeFolderPath(index + 1, prevBasePath, newBasePath, folderArr)
      .catch(err => reject(err));
      resolve();
    })
    .catch(err => reject(err));
  });
}

function deleteSingleFolder(folderId) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('DELETE FROM ', constants.ENTITIES_FOLDER,
                                                   ' WHERE ', constants.HEADER_FOLDER_FOLDER_ID,
                                                   ' = ', folderId)])
    .then(() => resolve())
    .catch(sqlError => reject(sqlError))
  );
}

function cascadeDeleteFolder(index, folderArr) {
  return new Promise((resolve, reject) => {
    if (index >= folderArr.length) {
      return true;
    }
    const folderToDeleteIndex = Object.values(folderArr[index])[0];
    return deleteSingleFolder(folderToDeleteIndex)
    .then(() => {
      cascadeDeleteFolder(index + 1, folderArr)
      .catch(err => reject(err));
      resolve();
    })
    .catch(err => reject(err));
  });
}

}

export default function sqlCommands() {
  this.linkDatabaseToIndexedDB = function linkDatabaseToIndexedDB(databaseName) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) => {
        const databaseRequestStr = stringManipulator.stringConcat(
          'CREATE INDEXEDDB DATABASE IF NOT EXISTS ', databaseName, ';',
          'ATTACH INDEXEDDB DATABASE ', databaseName, ';',
          'USE ', databaseName, ';');
        return alasql.promise([databaseRequestStr])
          .then(data => resolve(true))
          .catch(sqlError => reject(sqlError));
      });
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.getFullTableData = function getFullTableData(tableName) {
    // ensure working in browsers that support Promise
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT * FROM ', tableName)])
        .then(data => resolve(getArray(data)))
        .catch(sqlError => reject(sqlError)));
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.createTable = function createTable(sqlStatement) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('CREATE TABLE IF NOT EXISTS ', sqlStatement)])
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.insertContent = function insertContent(tableName, alasqlArray) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise(stringManipulator.stringConcat('INSERT INTO ', tableName,
                                                       ' VALUES ?'), alasqlArray)
        .then(data => resolve(data))
        .catch(sqlError => reject(sqlError)));
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.partialSearchFileName = function partialSearchFileName(searchString) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT * FROM ', constants.ENTITIES_FILE_MANAGER,
                                                       ' WHERE ', constants.HEADER_FILE_MANAGER_FILE_NAME,
                                                       ' LIKE "%', searchString, '%"')])
        .then(data => resolve(getArray(data)))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };
  this.getMaxFileId = function getMaxFileId() {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT max(', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                       ') FROM ', constants.ENTITIES_FILE_MANAGER)])
        .then((data) => {
          const maxFileId = getDataOutOfAlasql(data);
          if (typeof maxFileId === 'number') {
            resolve(maxFileId);
          } else {
            resolve(-1);
          }
        }).catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };
  this.getMaxFolderId = function getMaxFolderId() {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT MAX(', constants.HEADER_FOLDER_FOLDER_ID,
                                                       ') FROM ', constants.ENTITIES_FOLDER)])
        .then((data) => {
          const maxFolderId = getDataOutOfAlasql(data);
          if (typeof maxFolderId === 'number') {
            resolve(maxFolderId);
          } else {
            resolve(0);
          }
        }).catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.partialSearchFolderName = function partialSearchFolderName(searchString) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT * FROM ', constants.ENTITIES_FOLDER,
                                                       ' WHERE ', constants.HEADER_FOLDER_FOLDER_NAME,
                                                       ' LIKE "%', searchString, '%"')])
        .then(data => resolve(getArray(data)))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.loadFilesFromFolder = function loadFilesFromFolder(folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT * FROM ', constants.ENTITIES_FILE_MANAGER,
                                                       ' WHERE ', constants.HEADER_FILE_MANAGER_FOLDER_ID,
                                                       ' = ', folderId)])
        .then(data => resolve(getArray(data)))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.loadFoldersFromFolder = function loadFoldersFromFolder(folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT * FROM ', constants.ENTITIES_FOLDER,
                                                       ' WHERE ', constants.HEADER_FOLDER_PARENT_FOLDER_ID,
                                                       ' = ', folderId)])
        .then(data => resolve(getArray(data)))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.loadFile = function loadFile(fileId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT ', constants.HEADER_FILE_MANAGER_FILE_MARKDOWN,
                                                       ' FROM ', constants.ENTITIES_FILE_MANAGER,
                                                       ' WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                       ' = ', fileId)])
        .then(data => resolve(getDataOutOfAlasql(data)))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.saveFile = function saveFile(fileId, markdownFile) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) => {
        .then(() => {
          const currentDateTime = dateTime.getCurrentDateTime();
          alasql.promise([stringManipulator.stringConcat('UPDATE ', constants.ENTITIES_FILE_MANAGER,
                                                         ' SET ', constants.HEADER_FILE_MANAGER_LAST_MODIFIED_DATE,
                                                         ' = "', currentDateTime,
                                                         '" WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                         ' = ', fileId)])
          .catch(sqlError => reject(sqlError));
        })
        .then(() => resolve(true))
        .catch(sqlErr => reject(sqlErr));
      });
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.deleteFile = function deleteFile(fileId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('DELETE FROM ', constants.ENTITIES_FILE_MANAGER,
                                                       ' WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                       ' = ', fileId)])
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.deleteFolder = function deleteFolder(folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('DELETE FROM ', constants.ENTITIES_FOLDER,
                                                       ' WHERE ', constants.HEADER_FOLDER_FOLDER_ID,
                                                       ' = ', folderId)])
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  // external library not functioning so I cannot do anything here
  this.deleteTable = function deleteTable(tableName) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('DROP TABLE IF EXISTS ', tableName)])
        .then(isSuccess => resolve(isSuccess))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };
}
<commit_msg>Add deleteSingleFile function to sqlCommands.js<commit_after>import StringManipulator from 'src/database/stringManipulation';
import exceptions from 'src/database/exceptions';
import constants from 'src/database/constants';
import DateTime from 'src/database/generated-data/dateTime';

const alasql = require('alasql');

const stringManipulator = new StringManipulator();
const dateTime = new DateTime();

function getDataOutOfAlasql(data) {
  return Object.values(data[0][0])[0];
}

function getSecondDataOutOfAlasql(data) {
  return Object.values(data[0][0])[1];
}

function getArray(data) {
  return data[0];
}

function getCurrentFilePath(fileId) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('SELECT ', constants.HEADER_FILE_MANAGER_PATH,
                                                   ' FROM ', constants.ENTITIES_FILE_MANAGER,
                                                   ' WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                   ' = ', fileId)])
    .then(filePath => resolve(filePath))
    .catch(sqlErr => reject(sqlErr))
  );
}

function getCurrentFolderPath(folderId) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('SELECT ', constants.HEADER_FOLDER_PATH,
                                                   ' FROM ', constants.ENTITIES_FOLDER,
                                                   ' WHERE ', constants.HEADER_FOLDER_FOLDER_ID,
                                                   ' = ', folderId)])
    .then(folderPath => resolve(folderPath))
    .catch(sqlErr => reject(sqlErr))
  );
}

// duplicate private function to help with cascadeChangeFilePath
function changeSingleFilePath(fileId, newPath) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('UPDATE ', constants.ENTITIES_FILE_MANAGER,
                                                   ' SET ', constants.HEADER_FILE_MANAGER_PATH,
                                                   ' = "', newPath,
                                                   '" WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                   ' = ', fileId)])
    .then(() => resolve())
    .catch(sqlError => reject(sqlError))
  );
}

function cascadeChangeFilePath(index, prevBasePath, newBasePath, fileArr) {
  return new Promise((resolve, reject) => {
    if (index >= fileArr.length) {
      return true;
    }
    const fileToChangePathIndex = Object.values(fileArr[index])[0];
    let newPath;
    return getCurrentFilePath(fileToChangePathIndex)
    .then((currentFilePath) => {
      const childPath = currentFilePath.toString().split(prevBasePath)[1];
      newPath = stringManipulator.stringConcat(newBasePath, childPath);
      return changeSingleFilePath(fileToChangePathIndex, newPath)
      .catch(sqlErr => reject(sqlErr));
    })
    .then(() => {
      cascadeChangeFilePath(index + 1, prevBasePath, newBasePath, fileArr)
      .catch(err => reject(err));
      resolve();
    })
    .catch(err => reject(err));
  });
}

function changeSingleFolderPath(folderId, newPath) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('UPDATE ', constants.ENTITIES_FOLDER,
                                                   ' SET ', constants.HEADER_FOLDER_PATH,
                                                   ' = "', newPath,
                                                   '" WHERE ', constants.HEADER_FOLDER_FOLDER_ID,
                                                   ' = ', folderId)])
    .then(() => resolve())
    .catch(sqlError => reject(sqlError))
  );
}

function changeSingleFolderName(folderId, newFolderName) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('UPDATE ', constants.ENTITIES_FOLDER,
                                                   ' SET ', constants.HEADER_FOLDER_FOLDER_NAME,
                                                   ' = "', newFolderName,
                                                   '" WHERE ', constants.HEADER_FOLDER_FOLDER_ID,
                                                   ' = ', folderId)])
    .then(() => resolve())
    .catch(sqlError => reject(sqlError))
  );
}

function cascadeChangeFolderPath(index, prevBasePath, newBasePath, folderArr) {
  return new Promise((resolve, reject) => {
    if (index >= folderArr.length) {
      return true;
    }
    const folderToChangePathIndex = Object.values(folderArr[index])[0];
    let newPath;
    return getCurrentFolderPath(folderToChangePathIndex)
    .then((currentFolderPath) => {
      const childPath = currentFolderPath.toString().split(prevBasePath)[1];
      newPath = stringManipulator.stringConcat(newBasePath, childPath);
      return changeSingleFolderPath(folderToChangePathIndex, newPath)
      .catch(sqlErr => reject(sqlErr));
    })
    .then(() => {
      cascadeChangeFolderPath(index + 1, prevBasePath, newBasePath, folderArr)
      .catch(err => reject(err));
      resolve();
    })
    .catch(err => reject(err));
  });
}

function deleteSingleFolder(folderId) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('DELETE FROM ', constants.ENTITIES_FOLDER,
                                                   ' WHERE ', constants.HEADER_FOLDER_FOLDER_ID,
                                                   ' = ', folderId)])
    .then(() => resolve())
    .catch(sqlError => reject(sqlError))
  );
}

function cascadeDeleteFolder(index, folderArr) {
  return new Promise((resolve, reject) => {
    if (index >= folderArr.length) {
      return true;
    }
    const folderToDeleteIndex = Object.values(folderArr[index])[0];
    return deleteSingleFolder(folderToDeleteIndex)
    .then(() => {
      cascadeDeleteFolder(index + 1, folderArr)
      .catch(err => reject(err));
      resolve();
    })
    .catch(err => reject(err));
  });
}

// duplicate private function to help with cascadeDeleteFile
function deleteSingleFile(fileId) {
  return new Promise((resolve, reject) =>
    alasql.promise([stringManipulator.stringConcat('DELETE FROM ', constants.ENTITIES_FILE_MANAGER,
                                                   ' WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                   ' = ', fileId)])
    .then(() => resolve())
    .catch(sqlError => reject(sqlError))
  );
}

}

export default function sqlCommands() {
  this.linkDatabaseToIndexedDB = function linkDatabaseToIndexedDB(databaseName) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) => {
        const databaseRequestStr = stringManipulator.stringConcat(
          'CREATE INDEXEDDB DATABASE IF NOT EXISTS ', databaseName, ';',
          'ATTACH INDEXEDDB DATABASE ', databaseName, ';',
          'USE ', databaseName, ';');
        return alasql.promise([databaseRequestStr])
          .then(data => resolve(true))
          .catch(sqlError => reject(sqlError));
      });
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.getFullTableData = function getFullTableData(tableName) {
    // ensure working in browsers that support Promise
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT * FROM ', tableName)])
        .then(data => resolve(getArray(data)))
        .catch(sqlError => reject(sqlError)));
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.createTable = function createTable(sqlStatement) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('CREATE TABLE IF NOT EXISTS ', sqlStatement)])
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.insertContent = function insertContent(tableName, alasqlArray) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise(stringManipulator.stringConcat('INSERT INTO ', tableName,
                                                       ' VALUES ?'), alasqlArray)
        .then(data => resolve(data))
        .catch(sqlError => reject(sqlError)));
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.partialSearchFileName = function partialSearchFileName(searchString) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT * FROM ', constants.ENTITIES_FILE_MANAGER,
                                                       ' WHERE ', constants.HEADER_FILE_MANAGER_FILE_NAME,
                                                       ' LIKE "%', searchString, '%"')])
        .then(data => resolve(getArray(data)))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };
  this.getMaxFileId = function getMaxFileId() {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT max(', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                       ') FROM ', constants.ENTITIES_FILE_MANAGER)])
        .then((data) => {
          const maxFileId = getDataOutOfAlasql(data);
          if (typeof maxFileId === 'number') {
            resolve(maxFileId);
          } else {
            resolve(-1);
          }
        }).catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };
  this.getMaxFolderId = function getMaxFolderId() {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT MAX(', constants.HEADER_FOLDER_FOLDER_ID,
                                                       ') FROM ', constants.ENTITIES_FOLDER)])
        .then((data) => {
          const maxFolderId = getDataOutOfAlasql(data);
          if (typeof maxFolderId === 'number') {
            resolve(maxFolderId);
          } else {
            resolve(0);
          }
        }).catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.partialSearchFolderName = function partialSearchFolderName(searchString) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT * FROM ', constants.ENTITIES_FOLDER,
                                                       ' WHERE ', constants.HEADER_FOLDER_FOLDER_NAME,
                                                       ' LIKE "%', searchString, '%"')])
        .then(data => resolve(getArray(data)))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.loadFilesFromFolder = function loadFilesFromFolder(folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT * FROM ', constants.ENTITIES_FILE_MANAGER,
                                                       ' WHERE ', constants.HEADER_FILE_MANAGER_FOLDER_ID,
                                                       ' = ', folderId)])
        .then(data => resolve(getArray(data)))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.loadFoldersFromFolder = function loadFoldersFromFolder(folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT * FROM ', constants.ENTITIES_FOLDER,
                                                       ' WHERE ', constants.HEADER_FOLDER_PARENT_FOLDER_ID,
                                                       ' = ', folderId)])
        .then(data => resolve(getArray(data)))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.loadFile = function loadFile(fileId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('SELECT ', constants.HEADER_FILE_MANAGER_FILE_MARKDOWN,
                                                       ' FROM ', constants.ENTITIES_FILE_MANAGER,
                                                       ' WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                       ' = ', fileId)])
        .then(data => resolve(getDataOutOfAlasql(data)))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.saveFile = function saveFile(fileId, markdownFile) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) => {
        .then(() => {
          const currentDateTime = dateTime.getCurrentDateTime();
          alasql.promise([stringManipulator.stringConcat('UPDATE ', constants.ENTITIES_FILE_MANAGER,
                                                         ' SET ', constants.HEADER_FILE_MANAGER_LAST_MODIFIED_DATE,
                                                         ' = "', currentDateTime,
                                                         '" WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                         ' = ', fileId)])
          .catch(sqlError => reject(sqlError));
        })
        .then(() => resolve(true))
        .catch(sqlErr => reject(sqlErr));
      });
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.deleteFile = function deleteFile(fileId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('DELETE FROM ', constants.ENTITIES_FILE_MANAGER,
                                                       ' WHERE ', constants.HEADER_FILE_MANAGER_FILE_ID,
                                                       ' = ', fileId)])
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  this.deleteFolder = function deleteFolder(folderId) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('DELETE FROM ', constants.ENTITIES_FOLDER,
                                                       ' WHERE ', constants.HEADER_FOLDER_FOLDER_ID,
                                                       ' = ', folderId)])
        .then(data => resolve(true))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };

  // external library not functioning so I cannot do anything here
  this.deleteTable = function deleteTable(tableName) {
    if (typeof Promise === 'function') {
      return new Promise((resolve, reject) =>
        alasql.promise([stringManipulator.stringConcat('DROP TABLE IF EXISTS ', tableName)])
        .then(isSuccess => resolve(isSuccess))
        .catch(sqlError => reject(sqlError))
      );
    } else {
      throw new exceptions.PromiseFunctionNotDefined();
    }
  };
}
<|endoftext|>