├── assets ├── css │ ├── variables.css │ ├── singlequery.component.css │ ├── responsive.css │ ├── select2.css │ ├── learn.css │ ├── autocomplete.css │ ├── loading.css │ ├── docsidebar.css │ ├── main.css │ ├── app.component.css │ ├── modal.css │ ├── result.css │ ├── features_sidebar.css │ ├── features.css │ └── header.css ├── vendor │ └── JSONURL.js ├── images │ ├── logo.png │ ├── favicon.ico │ ├── icon_16.png │ ├── icon_32.png │ ├── icon_48.png │ ├── icon_128.png │ └── Mirage_Flat_9.png ├── styles │ ├── responsive.scss │ ├── variables.scss │ ├── select2.scss │ ├── learn.scss │ ├── autocomplete.scss │ ├── docsidebar.scss │ ├── loading.scss │ ├── app.component.scss │ ├── main.scss │ ├── features_sidebar.scss │ ├── features.scss │ ├── modal.scss │ ├── result.scss │ └── header.scss └── js │ └── helper.js ├── .bowerrc ├── .dockerignore ├── app ├── shared │ ├── config.ts │ ├── pipes │ │ ├── prettyJson.ts │ │ └── prettyTime.ts │ ├── storage.service.ts │ ├── globalshare.service.ts │ ├── docService.ts │ ├── queryList.ts │ └── editorHook.ts ├── features │ ├── share │ │ ├── share.url.component.html │ │ └── share.url.component.ts │ ├── docSidebar │ │ ├── docsidebar.component.html │ │ └── docsidebar.component.ts │ ├── appselect │ │ ├── appselect.component.html │ │ └── appselect.component.ts │ ├── confirm │ │ ├── confirm-modal.component.ts │ │ └── confirm-modal.component.html │ ├── modal │ │ ├── error-modal.component.ts │ │ └── error-modal.component.html │ ├── list │ │ ├── time │ │ │ └── time.component.ts │ │ ├── list.query.component.html │ │ └── list.query.component.ts │ ├── save │ │ ├── save.query.component.ts │ │ └── save.query.component.html │ ├── subscribe │ │ ├── subscribe.component.ts │ │ ├── subscribe.component.html │ │ └── AuthOperation.ts │ └── learn │ │ ├── learn.component.ts │ │ └── learn.component.html ├── queryBlocks │ ├── types │ │ └── types.component.html │ ├── select2 │ │ ├── select2.component.html │ │ └── select2.component.ts │ ├── editable │ │ ├── editable.component.html │ │ └── editable.component.ts │ ├── singlequery │ │ └── queries │ │ │ ├── match_phase_prefix.query.spec.ts │ │ │ ├── exists.query.ts │ │ │ ├── terms.query.ts │ │ │ ├── ids.query.ts │ │ │ ├── exists.query.spec.ts │ │ │ ├── missing.query.spec.ts │ │ │ ├── lt.query.spec.ts │ │ │ ├── gt.query.spec.ts │ │ │ ├── term.query.spec.ts │ │ │ ├── fuzzy.query.spec.ts │ │ │ ├── prefix.query.spec.ts │ │ │ ├── range.query.spec.ts │ │ │ ├── regexp.query.spec.ts │ │ │ ├── terms.query.spec.ts │ │ │ ├── wildcard.query.spec.ts │ │ │ ├── match_phrase.query.spec.ts │ │ │ ├── common.query.spec.ts │ │ │ ├── ids.query.spec.ts │ │ │ ├── span_first.query.spec.ts │ │ │ ├── span_term.query.spec.ts │ │ │ ├── multi-match.query.spec.ts │ │ │ ├── query_string.query.spec.ts │ │ │ ├── match.query.spec.ts │ │ │ ├── simple_query_string.query.spec.ts │ │ │ ├── geopolygon.query.spec.ts │ │ │ ├── geodistancerange.query.spec.ts │ │ │ └── geoshape.query.spec.ts │ ├── queryBlocks.component.html │ └── boolquery │ │ └── boolquery.component.ts ├── main.ts ├── jsonEditor │ └── jsonEditor.component.html └── result │ ├── result.component.html │ └── result.component.ts ├── bs-config.json ├── .codeclimate.yml ├── typings.json ├── .gitignore ├── mirage.appcache ├── mirageSample.appcache ├── tsconfig.json ├── Dockerfile ├── LICENSE.md ├── tslint.js ├── bower.json ├── index.html ├── index_prod.html ├── systemjs.config.js └── package.json /assets/css/variables.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/css/singlequery.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | node_modules/ 3 | dist/ 4 | bower_components/ 5 | *.zip 6 | -------------------------------------------------------------------------------- /assets/vendor/JSONURL.js: -------------------------------------------------------------------------------- 1 | const JSONURL = new LZMA("dist/vendor/lzma_worker.js"); -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appbaseio/mirage/HEAD/assets/images/logo.png -------------------------------------------------------------------------------- /assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appbaseio/mirage/HEAD/assets/images/favicon.ico -------------------------------------------------------------------------------- /assets/images/icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appbaseio/mirage/HEAD/assets/images/icon_16.png -------------------------------------------------------------------------------- /assets/images/icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appbaseio/mirage/HEAD/assets/images/icon_32.png -------------------------------------------------------------------------------- /assets/images/icon_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appbaseio/mirage/HEAD/assets/images/icon_48.png -------------------------------------------------------------------------------- /assets/images/icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appbaseio/mirage/HEAD/assets/images/icon_128.png -------------------------------------------------------------------------------- /assets/images/Mirage_Flat_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appbaseio/mirage/HEAD/assets/images/Mirage_Flat_9.png -------------------------------------------------------------------------------- /app/shared/config.ts: -------------------------------------------------------------------------------- 1 | export interface Config { 2 | url: string; 3 | appname: string; 4 | username: string; 5 | password: string; 6 | host: string; 7 | } -------------------------------------------------------------------------------- /bs-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 3030, 3 | "files": ["*", "*/*.js", "**/*.js"], 4 | "server": { "baseDir": "./" }, 5 | "ui": { 6 | "port": 3031 7 | } 8 | } -------------------------------------------------------------------------------- /app/features/share/share.url.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/css/responsive.css: -------------------------------------------------------------------------------- 1 | @media screen and (max-width: 768px) { 2 | #mirage-container { 3 | position: absolute; 4 | width: 100%; 5 | height: 100%; 6 | overflow: auto; } } 7 | -------------------------------------------------------------------------------- /app/queryBlocks/types/types.component.html: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /assets/styles/responsive.scss: -------------------------------------------------------------------------------- 1 | @media screen and (max-width: 768px) { 2 | #mirage-container { 3 | position: absolute; 4 | width: 100%; 5 | height: 100%; 6 | overflow: auto; 7 | } 8 | } -------------------------------------------------------------------------------- /app/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | 3 | import { AppModule } from './app.module'; 4 | 5 | platformBrowserDynamic().bootstrapModule(AppModule); 6 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | tslint: 3 | enabled: true 4 | config: tslint.json 5 | ratings: 6 | paths: 7 | - "**.ts" 8 | exclude_paths: 9 | - bower_components 10 | - node_modules 11 | - typings 12 | - dist -------------------------------------------------------------------------------- /assets/styles/variables.scss: -------------------------------------------------------------------------------- 1 | $primary-color: #FCC829; 2 | $secondary-color: #FFAF3B; 3 | $link-color: #81260D; 4 | $contrast-color: #fff; 5 | $grey-bg: #f7f7f7; 6 | $dark-grey: #eee; 7 | $grey-font: #828282; 8 | $primary-font-color: #555; 9 | -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "globalDependencies": { 3 | "core-js": "registry:dt/core-js#0.0.0+20160602141332", 4 | "jasmine": "registry:dt/jasmine#2.2.0+20160621224255", 5 | "node": "registry:dt/node#6.0.0+20160621231320" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components 3 | app/*.js 4 | app/*.js.map 5 | app/**/*.js 6 | app/**/*.js.map 7 | app/**/**/*.js 8 | app/**/**/*.js.map 9 | dist 10 | typings 11 | _site 12 | site 13 | *.log 14 | mirage-unpacked 15 | mirage-unpacked? 16 | npm-debug.log.* -------------------------------------------------------------------------------- /app/shared/pipes/prettyJson.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({name: 'prettyJson'}) 4 | export class prettyJson implements PipeTransform { 5 | transform(value : Object) : any { 6 | return JSON.stringify(value, null, 4); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /app/shared/pipes/prettyTime.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | declare var moment; 3 | 4 | @Pipe({name: 'prettyTime'}) 5 | export class prettyTime implements PipeTransform { 6 | transform(value : Object) : any { 7 | return moment(value).fromNow(true); 8 | } 9 | } -------------------------------------------------------------------------------- /mirage.appcache: -------------------------------------------------------------------------------- 1 | CACHE MANIFEST 2 | # 1516884744843 3 | ./assets/images/favicon.ico 4 | ./dist/css/vendor.min.css 5 | ./dist/css/style.min.css 6 | ./dist/js/vendor.min.js 7 | ./dist/vendor/JSONURL.js 8 | ./dist/js/custom.min.js 9 | ./dist/angular/build.min.js 10 | 11 | NETWORK: 12 | * -------------------------------------------------------------------------------- /mirageSample.appcache: -------------------------------------------------------------------------------- 1 | CACHE MANIFEST 2 | # {{version}} 3 | ./assets/images/favicon.ico 4 | ./dist/css/vendor.min.css 5 | ./dist/css/style.min.css 6 | ./dist/js/vendor.min.js 7 | ./dist/vendor/JSONURL.js 8 | ./dist/js/custom.min.js 9 | ./dist/angular/build.min.js 10 | 11 | NETWORK: 12 | * -------------------------------------------------------------------------------- /assets/css/select2.css: -------------------------------------------------------------------------------- 1 | .select2-container { 2 | width: 100% !important; } 3 | 4 | .select2-container--default .select2-selection--multiple { 5 | border-color: #ccc; } 6 | 7 | .select2-container--default.select2-container--focus .select2-selection--multiple { 8 | border-color: #3BC7F6; } 9 | -------------------------------------------------------------------------------- /assets/styles/select2.scss: -------------------------------------------------------------------------------- 1 | .select2-container { 2 | width: 100% !important; 3 | } 4 | .select2-container--default .select2-selection--multiple { 5 | border-color: #ccc; 6 | } 7 | .select2-container--default.select2-container--focus .select2-selection--multiple { 8 | border-color: #3BC7F6; 9 | } 10 | -------------------------------------------------------------------------------- /app/shared/storage.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable() 4 | export class StorageService { 5 | set(key: any, value: any) { 6 | window.localStorage.setItem(key, value); 7 | } 8 | get(key: any) { 9 | return window.localStorage.getItem(key); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/features/docSidebar/docsidebar.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 | 6 | 7 |
8 |
-------------------------------------------------------------------------------- /assets/styles/learn.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | #learnModal { 3 | .modal-title { 4 | font-size: 20px; 5 | } 6 | .learn-list-contianer { 7 | padding: 15px 0; 8 | .learn-list { 9 | padding-left: 0; 10 | list-style: none; 11 | font-size: 16px; 12 | li { 13 | margin-bottom: 10px; 14 | } 15 | } 16 | .introBottom { 17 | display: table; 18 | width: 100%; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | "typings/main", 15 | "typings/main.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /app/shared/globalshare.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@angular/core"; 2 | 3 | @Injectable() 4 | export class GlobalShare { 5 | public informationList: any = {}; 6 | 7 | constructor() {} 8 | 9 | setValue(key, val) { 10 | this[key] = val; 11 | console.log(this.informationList); 12 | } 13 | 14 | getValue(key) { 15 | console.log(this); 16 | console.log(key, this[key]); 17 | return this[key]; 18 | } 19 | } -------------------------------------------------------------------------------- /assets/css/learn.css: -------------------------------------------------------------------------------- 1 | #learnModal .modal-title { 2 | font-size: 20px; } 3 | 4 | #learnModal .learn-list-contianer { 5 | padding: 15px 0; } 6 | #learnModal .learn-list-contianer .learn-list { 7 | padding-left: 0; 8 | list-style: none; 9 | font-size: 16px; } 10 | #learnModal .learn-list-contianer .learn-list li { 11 | margin-bottom: 10px; } 12 | #learnModal .learn-list-contianer .introBottom { 13 | display: table; 14 | width: 100%; } 15 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10-alpine 2 | MAINTAINER appbase.io 3 | 4 | WORKDIR /mirage 5 | ADD package.json yarn.lock /mirage/ 6 | 7 | RUN apk --no-cache update && apk --no-cache add git make gcc g++ python && rm -rf /var/cache/apk/* 8 | RUN yarn global add bower gulp http-server 9 | 10 | ADD . /mirage 11 | 12 | RUN bower install --allow-root && yarn && yarn cache clean && yarn build_gh_pages && rm -rf /mirage/bower_components && rm -rf /tmp/* 13 | 14 | EXPOSE 3030 15 | CMD ["http-server", "-p 3030"] 16 | -------------------------------------------------------------------------------- /app/shared/docService.ts: -------------------------------------------------------------------------------- 1 | import {EventEmitter, Injectable} from '@angular/core'; 2 | import {BehaviorSubject} from 'rxjs/BehaviorSubject'; 3 | 4 | @Injectable() 5 | export class DocService { 6 | constructor() {} 7 | 8 | // Observable navItem source 9 | private _navItemSource = new BehaviorSubject(''); 10 | // Observable navItem stream 11 | navItem$ = this._navItemSource.asObservable(); 12 | // service command 13 | emitNavChangeEvent(string) { 14 | this._navItemSource.next(string); 15 | } 16 | } -------------------------------------------------------------------------------- /app/features/appselect/appselect.component.html: -------------------------------------------------------------------------------- 1 |
2 | 4 |
    5 |
  • {{app.appname}}
  • 6 |
7 |
8 | -------------------------------------------------------------------------------- /app/features/confirm/confirm-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, SimpleChange, Input, Output, EventEmitter } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: 'confirm-modal', 5 | templateUrl: './app/features/confirm/confirm-modal.component.html', 6 | inputs: ['callback'] 7 | }) 8 | 9 | export class ConfirmModalComponent implements OnInit, OnChanges { 10 | @Input() info: any; 11 | @Output() callback = new EventEmitter(); 12 | ngOnInit() { 13 | } 14 | ngOnChanges() { 15 | } 16 | confirm(flag: boolean) { 17 | this.callback.emit(flag); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2016 Appbase Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /tslint.js: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:latest", 3 | "rules": { 4 | "class-name": true, 5 | "semicolon": [true, "always"], 6 | "triple-equals": [true, "allow-null-check"], 7 | "eofline": true, 8 | "whitespace": [true, 9 | "check-decl", 10 | "check-operator", 11 | "check-separator", 12 | "check-type" 13 | ], 14 | "variable-name": [ 15 | "allow-leading-underscore" 16 | ], 17 | "curly": false, 18 | "no-reference": false, 19 | "no-var-requires": false, 20 | "ordered-imports": false, 21 | "no-trailing-whitespace": false 22 | }, 23 | "rulesDirectory": [] 24 | } -------------------------------------------------------------------------------- /app/features/modal/error-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, SimpleChange, Input, Output, EventEmitter } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: 'error-modal', 5 | templateUrl: './app/features/modal/error-modal.component.html', 6 | inputs: ['callback'] 7 | }) 8 | 9 | export class ErrorModalComponent implements OnInit, OnChanges { 10 | @Input() info: any; 11 | @Input() errorHookHelp: any; 12 | @Output() callback = new EventEmitter(); 13 | ngOnInit() { 14 | var self = this; 15 | this.errorHookHelp.applyEditor({ 16 | lineNumbers: false, 17 | lineWrapping: true 18 | }); 19 | } 20 | ngOnChanges() { 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/features/list/time/time.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, SimpleChange, Input, Output, EventEmitter } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: 'time-relative', 5 | template: ` 6 | {{time | prettyTime}} 7 | ` 8 | }) 9 | 10 | export class TimeComponent implements OnInit, OnChanges { 11 | @Input() time: any; 12 | ngOnInit() { 13 | this.setTimeInterval(false); 14 | } 15 | ngOnChanges() {} 16 | 17 | setTimeInterval(flag: boolean) { 18 | this.time = flag ? this.time+1 : this.time-1; 19 | flag = flag ? false : true; 20 | setTimeout(function() { 21 | this.setTimeInterval(flag); 22 | }.bind(this), 1000*60); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /assets/styles/autocomplete.scss: -------------------------------------------------------------------------------- 1 | .autocomplete { 2 | position: relative; 3 | width: 100%; 4 | z-index: 999; 5 | text-align: left; 6 | .search { 7 | width: 100%; 8 | } 9 | .autolist { 10 | list-style: none; 11 | position: absolute; 12 | left: 0; 13 | top: 35px; 14 | background: #fff; 15 | width: 100%; 16 | max-height: 300px; 17 | overflow: auto; 18 | border: 1px solid; 19 | padding: 0; 20 | border-radius: 4px; 21 | border-color: #3BC7F6; 22 | li { 23 | cursor: pointer; 24 | padding: 6px 12px; 25 | &:hover { 26 | background: #3BC7F6; 27 | color: #fff; 28 | border-color: transparent; 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mirage", 3 | "description": "🔎 GUI for Elasticsearch Queries", 4 | "main": "index.js", 5 | "authors": ["Farhan Chauhan "], 6 | "license": "Apache-2.0", 7 | "moduleType": [], 8 | "homepage": "", 9 | "private": true, 10 | "ignore": ["**/.*", "node_modules", "bower_components", "test", "tests"], 11 | "dependencies": { 12 | "bootstrap": "~3.3.6", 13 | "select2": "~4.0.1", 14 | "font-awesome": "~4.5.0", 15 | "codemirror": "^5.44.0", 16 | "crypto-js": "^3.1.6", 17 | "moment": "2.13.0", 18 | "jquery": "~2.2.4", 19 | "lzma": "^2.3.0", 20 | "urlsafe-base64": "https://github.com/farhan687/urlsafe-base64.git", 21 | "auth0.js": "^7.3.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /assets/css/autocomplete.css: -------------------------------------------------------------------------------- 1 | .autocomplete { 2 | position: relative; 3 | width: 100%; 4 | z-index: 999; 5 | text-align: left; } 6 | .autocomplete .search { 7 | width: 100%; } 8 | .autocomplete .autolist { 9 | list-style: none; 10 | position: absolute; 11 | left: 0; 12 | top: 35px; 13 | background: #fff; 14 | width: 100%; 15 | max-height: 300px; 16 | overflow: auto; 17 | border: 1px solid; 18 | padding: 0; 19 | border-radius: 4px; 20 | border-color: #3BC7F6; } 21 | .autocomplete .autolist li { 22 | cursor: pointer; 23 | padding: 6px 12px; } 24 | .autocomplete .autolist li:hover { 25 | background: #3BC7F6; 26 | color: #fff; 27 | border-color: transparent; } 28 | -------------------------------------------------------------------------------- /app/queryBlocks/select2/select2.component.html: -------------------------------------------------------------------------------- 1 | 5 | 9 | -------------------------------------------------------------------------------- /app/jsonEditor/jsonEditor.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 11 |
12 |
13 |
14 |
15 | 22 |
23 |
24 |
25 | 26 |
27 |
28 | -------------------------------------------------------------------------------- /app/features/confirm/confirm-modal.component.html: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /app/features/docSidebar/docsidebar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, SimpleChange, Input, Output, EventEmitter } from "@angular/core"; 2 | import { SafeResourceUrl, DomSanitizer } from '@angular/platform-browser'; 3 | 4 | @Component({ 5 | selector: 'doc-sidebar', 6 | templateUrl: './app/features/docSidebar/docsidebar.component.html', 7 | inputs: ['setDocSample'] 8 | }) 9 | 10 | export class DocSidebarComponent implements OnInit, OnChanges { 11 | @Input() docLink; 12 | @Output() setDocSample = new EventEmitter(); 13 | public url: SafeResourceUrl; 14 | public open: boolean = false; 15 | 16 | constructor(public sanitizer: DomSanitizer) { } 17 | 18 | ngOnInit() {} 19 | 20 | ngOnChanges(changes) { 21 | if(changes.docLink.currentValue) { 22 | this.url = this.sanitizer.bypassSecurityTrustResourceUrl(changes.docLink.currentValue); 23 | this.open = true; 24 | } 25 | } 26 | 27 | close() { 28 | this.setDocSample.emit(null); 29 | this.open = false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /assets/styles/docsidebar.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | .doc-container { 3 | position: absolute; 4 | width: 35%; 5 | height: 100%; 6 | top: 0; 7 | right: 0; 8 | display: block; 9 | .iframe-container { 10 | position: absolute; 11 | width: 100%; 12 | height: 100%; 13 | top: 0; 14 | right: 0; 15 | display: block; 16 | z-index: 20001; 17 | background: #fff; 18 | padding-bottom: 36px; 19 | box-shadow: -1px 1px 3px 0px rgba(0,0,0,.2),0 -1px 5px 0 rgba(0,0,0,.14),0 2px 1px -1px rgba(0,0,0,.12); 20 | iframe { 21 | height: 100%; 22 | width: 100%; 23 | } 24 | .close-iframe { 25 | position: absolute; 26 | top: 14px; 27 | right: 8px; 28 | font-size: 14px; 29 | line-height: 30px; 30 | width: 30px; 31 | height: 30px; 32 | padding-top: 7px; 33 | text-align: center; 34 | display: inline-block; 35 | border-radius: 50%; 36 | background: $primary-color; 37 | color: #fff; 38 | cursor: pointer; 39 | border: 1px solid #ddd; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/features/save/save.query.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnChanges, SimpleChange } from "@angular/core"; 2 | import { StorageService } from "../../shared/storage.service"; 3 | declare var $: any; 4 | 5 | @Component({ 6 | selector: 'save-query', 7 | templateUrl: './app/features/save/save.query.component.html', 8 | inputs: ['config', 'mapping', 'queryList'], 9 | providers: [StorageService] 10 | }) 11 | 12 | export class SaveQueryComponent { 13 | public config; 14 | public mapping; 15 | public queryList; 16 | public query_info = { 17 | name: '', 18 | tag: '' 19 | }; 20 | 21 | constructor(public storageService: StorageService) {} 22 | 23 | openModal() { 24 | $('#saveQueryModal').modal('show'); 25 | } 26 | 27 | save() { 28 | var queryData = { 29 | mapping: this.mapping, 30 | config: this.config, 31 | name: this.query_info.name, 32 | tag: this.query_info.tag 33 | }; 34 | this.queryList.push(queryData); 35 | try { 36 | this.storageService.set('queryList', JSON.stringify(this.queryList)); 37 | } catch (e) {} 38 | console.log(this.queryList); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /assets/css/loading.css: -------------------------------------------------------------------------------- 1 | .loading { 2 | height: 100%; 3 | width: 100%; 4 | display: table; 5 | background: rgba(247, 247, 247, 0.9); 6 | position: fixed; 7 | z-index: 4; } 8 | .loading .vertical-cell { 9 | height: 100%; 10 | width: 100%; 11 | display: table-cell; 12 | vertical-align: middle; } 13 | 14 | .loading { 15 | height: 100%; 16 | width: 100%; 17 | display: table; 18 | background: rgba(247, 247, 247, 0.9); 19 | position: fixed; 20 | z-index: 10; } 21 | 22 | .loadingBar { 23 | position: fixed; 24 | display: none; 25 | top: 0; 26 | left: 0; 27 | right: 0; 28 | height: 2px; 29 | z-index: 800; 30 | background: #48e79a; 31 | transform: translateX(100%); } 32 | 33 | .is-loadingApp .loadingBar { 34 | display: block; 35 | animation: shift-rightwards 1s ease-in-out infinite; 36 | animation-delay: .8s; } 37 | 38 | @keyframes shift-rightwards { 39 | 0% { 40 | transform: translateX(-100%); } 41 | 40% { 42 | transform: translateX(0); } 43 | 60% { 44 | transform: translateX(0); } 45 | 100% { 46 | transform: translateX(100%); } } 47 | -------------------------------------------------------------------------------- /assets/styles/loading.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | .loading { 3 | height: 100%; 4 | width: 100%; 5 | display: table; 6 | background: rgba($grey-bg, 0.9); 7 | position: fixed; 8 | z-index: 4; 9 | .vertical-cell { 10 | height: 100%; 11 | width: 100%; 12 | display: table-cell; 13 | vertical-align: middle; 14 | } 15 | } 16 | .loading { 17 | height: 100%; 18 | width: 100%; 19 | display: table; 20 | background: rgba(247, 247, 247, .9); 21 | position: fixed; 22 | z-index: 10; 23 | } 24 | .loadingBar { 25 | position: fixed; 26 | display: none; 27 | top: 0; 28 | left: 0; 29 | right: 0; 30 | height: 2px; 31 | z-index: 800; 32 | background: #48e79a; 33 | transform: translateX(100%) 34 | } 35 | .is-loadingApp .loadingBar { 36 | display: block; 37 | animation: shift-rightwards 1s ease-in-out infinite; 38 | animation-delay: .8s 39 | } 40 | @keyframes shift-rightwards { 41 | 0% { 42 | transform: translateX(-100%) 43 | } 44 | 40% { 45 | transform: translateX(0) 46 | } 47 | 60% { 48 | transform: translateX(0) 49 | } 50 | 100% { 51 | transform: translateX(100%) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /assets/css/docsidebar.css: -------------------------------------------------------------------------------- 1 | .doc-container { 2 | position: absolute; 3 | width: 35%; 4 | height: 100%; 5 | top: 0; 6 | right: 0; 7 | display: block; } 8 | .doc-container .iframe-container { 9 | position: absolute; 10 | width: 100%; 11 | height: 100%; 12 | top: 0; 13 | right: 0; 14 | display: block; 15 | z-index: 20001; 16 | background: #fff; 17 | padding-bottom: 36px; 18 | box-shadow: -1px 1px 3px 0px rgba(0, 0, 0, 0.2), 0 -1px 5px 0 rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12); } 19 | .doc-container .iframe-container iframe { 20 | height: 100%; 21 | width: 100%; } 22 | .doc-container .iframe-container .close-iframe { 23 | position: absolute; 24 | top: 14px; 25 | right: 8px; 26 | font-size: 14px; 27 | line-height: 30px; 28 | width: 30px; 29 | height: 30px; 30 | padding-top: 7px; 31 | text-align: center; 32 | display: inline-block; 33 | border-radius: 50%; 34 | background: #FCC829; 35 | color: #fff; 36 | cursor: pointer; 37 | border: 1px solid #ddd; } 38 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mirage 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 | 29 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/features/modal/error-modal.component.html: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /app/features/list/list.query.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | -------------------------------------------------------------------------------- /app/features/subscribe/subscribe.component.ts: -------------------------------------------------------------------------------- 1 | import { OnInit, OnChanges, Component, Input, Output, ViewChild, EventEmitter, AfterViewInit } from "@angular/core"; 2 | import { Headers, Http } from '@angular/http'; 3 | import { AuthOperation } from './AuthOperation'; 4 | 5 | declare var $: any; 6 | 7 | @Component({ 8 | selector: 'subscribe-modal', 9 | templateUrl: './app/features/subscribe/subscribe.component.html' 10 | }) 11 | 12 | export class SubscribeModalComponent { 13 | public options: any = { 14 | option1: { 15 | value: 'major', 16 | text: 'New MIRAGE releases' 17 | }, 18 | option2: { 19 | value: 'all', 20 | text: 'Limited major updates' 21 | } 22 | }; 23 | public subscribeOption: string = "major"; 24 | public profile: any = null; 25 | @ViewChild(AuthOperation) private authOperation: AuthOperation; 26 | 27 | constructor(private http: Http) { 28 | this.updateStatus = this.updateStatus.bind(this); 29 | } 30 | 31 | open() { 32 | $('#subscribeModal').modal('show'); 33 | } 34 | 35 | updateStatus(info: any) { 36 | this.profile = info.profile; 37 | } 38 | 39 | subscribe() { 40 | this.authOperation.login(this.subscribeOption); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /app/queryBlocks/editable/editable.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | {{editableField}} 5 |
6 |
7 | {{editPlaceholder}} 8 |
9 |
10 |
11 | 12 |
13 |
14 | 17 |
18 |
19 | 22 |
23 |
-------------------------------------------------------------------------------- /app/shared/queryList.ts: -------------------------------------------------------------------------------- 1 | export var queryList = { 2 | analyzed:{ 3 | string: [ 4 | 'match', 5 | 'match_phrase', 6 | 'term', 7 | 'terms', 8 | 'exists', 9 | 'missing', 10 | 'multi_match', 11 | 'query_string', 12 | 'prefix', 13 | 'wildcard', 14 | 'regexp', 15 | 'fuzzy', 16 | 'simple_query_string', 17 | 'match_phrase_prefix', 18 | 'ids', 19 | 'common', 20 | 'span_term', 21 | 'span_first' 22 | ], 23 | numeric: [ 24 | 'match', 25 | 'range', 26 | 'gt', 27 | 'lt', 28 | 'exists', 29 | 'missing', 30 | 'ids', 31 | 'common' 32 | ], 33 | geo_point: [ 34 | 'geo_distance', 35 | 'geo_distance_range', 36 | 'geo_bounding_box', 37 | 'geo_polygon', 38 | 'geohash_cell' 39 | ], 40 | geo_shape: [ 41 | 'geo_shape' 42 | ] 43 | }, 44 | not_analyzed: { 45 | string: [ 46 | 'term', 47 | 'exists', 48 | 'terms', 49 | 'prefix' 50 | ], 51 | numeric: [ 52 | 'match', 53 | 'range', 54 | 'gt', 55 | 'lt' 56 | ], 57 | geo_point: [ 58 | 'geo_distance', 59 | 'geo_bounding_box', 60 | 'geo_distance_range', 61 | 'geo_polygon', 62 | 'geohash_cell' 63 | ] 64 | }, 65 | boolQuery: [ 66 | 'must', 67 | 'must_not', 68 | 'should', 69 | 'filter' 70 | ], 71 | allowedDataTypes: [ 72 | 'string', 73 | 'text', 74 | 'keyword', 75 | 'date', 76 | 'numeric', 77 | 'geo_point', 78 | 'geo_shape' 79 | ] 80 | }; 81 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/match_phase_prefix.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { Match_phase_prefixQuery } from './match_phase_prefix.query'; 2 | 3 | describe('Match_phase_prefix query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: Match_phase_prefixQuery; 8 | var expectedFormat = { 9 | 'match_phase_prefixQuery': { 10 | 'foo': 'bar' 11 | } 12 | }; 13 | 14 | // instantiate query component and set the input fields 15 | beforeEach(function() { 16 | query = new Match_phase_prefixQuery(); 17 | query.queryName = 'match_phase_prefixQuery'; 18 | query.fieldName = 'foo'; 19 | query.inputs = { 20 | input: { 21 | value: 'bar' 22 | } 23 | }; 24 | }); 25 | 26 | function isValidJson(str: string) { 27 | try { 28 | JSON.parse(str); 29 | } catch (e) { 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | // Test to check if queryformat is valid json 36 | it('is valid json', () => { 37 | var format = query.setFormat(); 38 | var validJson = isValidJson(JSON.stringify(format)); 39 | expect(validJson).toEqual(true); 40 | }); 41 | 42 | // Test to check if result of setformat is equal to expected query format. 43 | it('Is setformat matches with expected query format', () => { 44 | var format = query.setFormat(); 45 | expect(format).toEqual(expectedFormat); 46 | }); 47 | 48 | }) 49 | -------------------------------------------------------------------------------- /index_prod.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mirage 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /assets/js/helper.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | if (typeof Object.defineProperty === 'function') { 3 | try { Object.defineProperty(Array.prototype, 'sortBy', { value: sb }); } catch (e) {} 4 | } 5 | if (!Array.prototype.sortBy) Array.prototype.sortBy = sb; 6 | 7 | function sb(f) { 8 | for (var i = this.length; i;) { 9 | var o = this[--i]; 10 | this[i] = [].concat(f.call(o, o, i), o); 11 | } 12 | this.sort(function(a, b) { 13 | for (var i = 0, len = a.length; i < len; ++i) { 14 | if (a[i] != b[i]) return a[i] < b[i] ? -1 : 1; 15 | } 16 | return 0; 17 | }); 18 | for (var i = this.length; i;) { 19 | this[--i] = this[i][this[i].length - 1]; 20 | } 21 | return this; 22 | } 23 | 24 | var originalLeave = $.fn.popover.Constructor.prototype.leave; 25 | $.fn.popover.Constructor.prototype.leave = function(obj){ 26 | var self = obj instanceof this.constructor ? 27 | obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 28 | var container, timeout; 29 | 30 | originalLeave.call(this, obj); 31 | 32 | if(obj.currentTarget) { 33 | container = $(obj.currentTarget).siblings('.popover') 34 | timeout = self.timeout; 35 | container.one('mouseenter', function(){ 36 | //We entered the actual popover – call off the dogs 37 | clearTimeout(timeout); 38 | //Let's monitor popover content instead 39 | container.one('mouseleave', function(){ 40 | $.fn.popover.Constructor.prototype.leave.call(self, self); 41 | }); 42 | }) 43 | } 44 | }; 45 | })(); 46 | -------------------------------------------------------------------------------- /app/features/save/save.query.component.html: -------------------------------------------------------------------------------- 1 | 2 | Save Query 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/features/list/list.query.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, SimpleChange, Input, Output, EventEmitter } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: 'list-query', 5 | templateUrl: './app/features/list/list.query.component.html', 6 | inputs: ['newQuery', 'deleteQuery', 'clearAll', 'searchByMethod'] 7 | }) 8 | 9 | export class ListQueryComponent implements OnInit { 10 | @Input() savedQueryList; 11 | @Input() sort_by; 12 | @Input() sort_direction; 13 | @Input() searchTerm; 14 | @Input() filteredQuery; 15 | @Output() newQuery = new EventEmitter < boolean > (); 16 | @Output() deleteQuery = new EventEmitter < any > (); 17 | @Output() clearAll = new EventEmitter < any > (); 18 | @Output() sort = new EventEmitter < any > (); 19 | @Output() searchList = new EventEmitter < any > (); 20 | public searchByMethod: any; 21 | public direction: boolean = false; 22 | 23 | ngOnInit() {} 24 | 25 | applyQuery(currentQuery) { 26 | var queryData = this.savedQueryList.filter(function(query) { 27 | return query.name === currentQuery.name && query.tag === currentQuery.tag; 28 | }); 29 | if(queryData.length) { 30 | this.newQuery.emit(queryData[0]); 31 | } 32 | } 33 | 34 | applyDeleteQuery(query) { 35 | this.deleteQuery.emit(query); 36 | } 37 | 38 | applyClearAll() { 39 | this.clearAll.emit(null); 40 | } 41 | 42 | applySearchList() { 43 | this.searchList.emit({ 44 | searchTerm: this.searchTerm, 45 | searchByMethod: this.searchByMethod 46 | }); 47 | } 48 | 49 | tagApply(event, tag, searchByMethod) { 50 | this.searchTerm = tag; 51 | this.searchByMethod = searchByMethod; 52 | this.applySearchList(); 53 | event.stopPropagation(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/features/learn/learn.component.ts: -------------------------------------------------------------------------------- 1 | import { OnInit, OnChanges, Component, Input, Output, ViewChild, EventEmitter, AfterViewInit } from "@angular/core"; 2 | import { Headers, Http } from '@angular/http'; 3 | import { AuthOperation } from '../subscribe/AuthOperation'; 4 | import { StorageService } from "../../shared/storage.service"; 5 | 6 | declare var $: any; 7 | 8 | @Component({ 9 | selector: 'learn-modal', 10 | templateUrl: './app/features/learn/learn.component.html', 11 | inputs: ['saveQuery', 'newQuery'] 12 | }) 13 | 14 | export class LearnModalComponent { 15 | 16 | constructor(private http: Http, public storageService: StorageService) { 17 | this.updateStatus = this.updateStatus.bind(this); 18 | } 19 | 20 | @Output() saveQuery = new EventEmitter(); 21 | @Output() newQuery = new EventEmitter(); 22 | public queries: any = []; 23 | public subscribeOption: string = "major"; 24 | public profile: any = null; 25 | public serverAddress: string = 'https://ossauth.appbase.io'; 26 | @ViewChild(AuthOperation) private authOperation: AuthOperation; 27 | 28 | loadLearn() { 29 | let self = this; 30 | this.http.get('./app/shared/default.data.json').toPromise().then(function(res) { 31 | let data = res.json(); 32 | data.queries.forEach((query) => { 33 | self.saveQuery.emit(query); 34 | }); 35 | setTimeout(function() { 36 | self.newQuery.emit(data.queries[0]); 37 | }, 500); 38 | $('#learnModal').modal('hide'); 39 | $('#learnInfoModal').modal('show'); 40 | }).catch(function(e) { 41 | console.log(e); 42 | }); 43 | } 44 | 45 | updateStatus(info: any) { 46 | this.profile = info.profile; 47 | } 48 | 49 | subscribe() { 50 | this.authOperation.login(this.subscribeOption); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /assets/css/main.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; } 3 | 4 | .p-l-15 { 5 | padding-left: 15px !important; } 6 | 7 | .pd-0 { 8 | padding: 0 !important; } 9 | 10 | .pd-r0 { 11 | padding-right: 0; } 12 | 13 | .pd-l0 { 14 | padding-left: 0; } 15 | 16 | .pd-r10 { 17 | padding-right: 10px; } 18 | 19 | .pr-5 { 20 | padding-right: 5px !important; } 21 | 22 | .m-r5 { 23 | margin-right: 5px; } 24 | 25 | .m-r10 { 26 | margin-right: 10px; } 27 | 28 | .m-0 { 29 | margin: 0; } 30 | 31 | .m-b0 { 32 | margin-bottom: 0; } 33 | 34 | .m-b15 { 35 | margin-bottom: 15px; } 36 | 37 | .mt-10 { 38 | margin-top: 10px; } 39 | 40 | .mt-5 { 41 | margin-top: 5px; } 42 | 43 | .m-tb-15 { 44 | margin-top: 15px; 45 | margin-bottom: 15px; } 46 | 47 | .clearfix { 48 | clear: both; } 49 | 50 | a { 51 | cursor: pointer; } 52 | 53 | .btn-primary { 54 | color: #fff; 55 | background-color: #FCC829; 56 | border-color: #fcc210; } 57 | .btn-primary:hover, .btn-primary:focus, .btn-primary.active { 58 | background-color: #fcc210; } 59 | 60 | .btn-grey { 61 | color: #828282; 62 | border-color: transparent; 63 | background: transparent; 64 | padding: 2px; } 65 | .btn-grey:hover { 66 | color: #757575; } 67 | 68 | .btn-theme { 69 | color: #fff; 70 | background-color: #FCC829; 71 | border-color: #FFAF3B; } 72 | .btn-theme:hover { 73 | color: #fff; 74 | background-color: #FFAF3B; 75 | border-color: #FFAF3B; } 76 | 77 | .btn { 78 | border-radius: 0; 79 | border: 0; } 80 | 81 | html, 82 | body { 83 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 84 | font-size: 14px; 85 | line-height: 1.42857143; 86 | color: #333; } 87 | 88 | a { 89 | color: #81260D; } 90 | 91 | .popover { 92 | z-index: 99999; 93 | min-width: 350px; } 94 | 95 | .disableClick { 96 | pointer-events: none; } 97 | -------------------------------------------------------------------------------- /systemjs.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * System configuration for Angular 2 samples 3 | * Adjust as necessary for your application needs. 4 | */ 5 | (function(global) { 6 | // map tells the System loader where to look for things 7 | var map = { 8 | 'app': 'app', // 'dist', 9 | '@angular': 'node_modules/@angular', 10 | 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api', 11 | 'rxjs': 'node_modules/rxjs' 12 | }; 13 | // packages tells the System loader how to load when no filename and/or no extension 14 | var packages = { 15 | 'app': { main: 'main.js', defaultExtension: 'js' }, 16 | 'rxjs': { defaultExtension: 'js' }, 17 | 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, 18 | }; 19 | var ngPackageNames = [ 20 | 'common', 21 | 'compiler', 22 | 'core', 23 | 'forms', 24 | 'http', 25 | 'platform-browser', 26 | 'platform-browser-dynamic', 27 | 'router', 28 | 'router-deprecated', 29 | 'upgrade', 30 | ]; 31 | // Individual files (~300 requests): 32 | function packIndex(pkgName) { 33 | packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; 34 | } 35 | // Bundled (~40 requests): 36 | function packUmd(pkgName) { 37 | packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' }; 38 | } 39 | // Most environments should use UMD; some (Karma) need the individual index files 40 | var setPackageConfig = System.packageWithIndex ? packIndex : packUmd; 41 | // Add package entries for angular packages 42 | ngPackageNames.forEach(setPackageConfig); 43 | var config = { 44 | map: map, 45 | packages: packages 46 | }; 47 | System.config(config); 48 | })(this); 49 | -------------------------------------------------------------------------------- /assets/styles/app.component.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | .loading { 3 | height: 100%; 4 | width: 100%; 5 | display: table; 6 | background: rgba($grey-bg, 0.9); 7 | position: fixed; 8 | z-index: 4; 9 | .vertical-cell { 10 | height: 100%; 11 | width: 100%; 12 | display: table-cell; 13 | vertical-align: middle; 14 | } 15 | } 16 | .header { 17 | position: absolute; 18 | top: 0; 19 | left: 0; 20 | width: 100%; 21 | z-index: 9; 22 | background: $grey-bg; 23 | border-bottom: 0; 24 | padding: 6px; 25 | max-height: 40px; 26 | margin: 0 auto; 27 | .header-container { 28 | display: inline-block; 29 | .img-container { 30 | max-width: 170px; 31 | display: inline-block; 32 | float: left; 33 | padding: 5px; 34 | left: 10px; 35 | } 36 | .tag-line { 37 | padding-left: 15px; 38 | line-height: 30px; 39 | font-size: 20px; 40 | } 41 | } 42 | } 43 | .app-container { 44 | position: relative; 45 | padding-top: 88px; 46 | padding-bottom: 0; 47 | height: 100%; 48 | .applogin-component { 49 | position: relative; 50 | height: 100%; 51 | padding-top: 60px; 52 | padding-bottom: 36px; 53 | } 54 | .query-main-container { 55 | position: relative; 56 | min-height: 100%; 57 | height: auto; 58 | display: block; 59 | } 60 | &.without-hf { 61 | padding: 0; 62 | .applogin-component { 63 | position: relative; 64 | height: 100%; 65 | padding-top: 0; 66 | padding-bottom: 0; 67 | } 68 | .query-result-container.layoutApplied { 69 | padding-bottom: 15px; 70 | } 71 | } 72 | &.without-h { 73 | padding: 0; 74 | .applogin-component { 75 | position: relative; 76 | height: 100%; 77 | padding-top: 0; 78 | } 79 | } 80 | &.without-f { 81 | .applogin-component { 82 | position: relative; 83 | height: 100%; 84 | padding-bottom: 0; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/shared/editorHook.ts: -------------------------------------------------------------------------------- 1 | declare var $: any, jQuery: any, CodeMirror: any; 2 | 3 | export var EditorHook = function(config) { 4 | this.editorId = config.editorId; 5 | this.$editor = "#" + config.editorId; 6 | }; 7 | 8 | EditorHook.prototype.applyEditor = function(settings) { 9 | var self = this; 10 | this.settings = settings; 11 | var defaultOptions = { 12 | lineNumbers: true, 13 | mode: { 14 | name: "javascript", 15 | json: true 16 | }, 17 | autoCloseBrackets: true, 18 | matchBrackets: true, 19 | showCursorWhenSelecting: true, 20 | indentWithTabs: true, 21 | tabSize: 2, 22 | extraKeys: { 23 | "Ctrl-Q": function(cm) { 24 | cm.foldCode(cm.getCursor()); 25 | } 26 | }, 27 | foldGutter: true, 28 | gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"] 29 | }; 30 | var options = settings 31 | ? jQuery.extend(defaultOptions, settings) 32 | : defaultOptions; 33 | self.editor = CodeMirror.fromTextArea( 34 | document.getElementById(self.editorId), 35 | options 36 | ); 37 | }; 38 | 39 | EditorHook.prototype.setValue = function(value) { 40 | if (this.editor && this.editor.setValue) { 41 | this.editor.setValue(value); 42 | } 43 | }; 44 | 45 | EditorHook.prototype.focus = function(value) { 46 | this.editor.toTextArea(); 47 | this.applyEditor(this.settings); 48 | this.setValue(value); 49 | }; 50 | 51 | EditorHook.prototype.getValue = function() { 52 | return this.editor.getValue(); 53 | }; 54 | 55 | EditorHook.prototype.getInstance = function() { 56 | return this.editor; 57 | }; 58 | 59 | EditorHook.prototype.prepend = function(data) { 60 | const totalLine = data.split(/\r\n|\r|\n/).length; 61 | this.editor.replaceRange(data, { line: 0, ch: 0 }); 62 | for (let i = 0; i < totalLine - 1; i++) { 63 | this.editor.addLineClass(i, "wrap", "streaming-response"); 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /app/features/appselect/appselect.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, SimpleChange, Input, Output, EventEmitter } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: 'appselect', 5 | templateUrl: './app/features/appselect/appselect.component.html', 6 | inputs: ['setConfig', 'onAppSelectChange'] 7 | }) 8 | 9 | export class AppselectComponent implements OnInit, OnChanges { 10 | @Input() appsList: any; 11 | @Input() config: any; 12 | @Input() connected: boolean; 13 | @Output() onAppSelectChange = new EventEmitter(); 14 | @Output() setConfig = new EventEmitter(); 15 | public filteredApps: any = []; 16 | public appFocus: boolean = false; 17 | 18 | ngOnInit() { 19 | // this.handleInput(); 20 | this.onAppSelectChange.emit(this.config.appname); 21 | } 22 | ngOnChanges() { 23 | this.onAppSelectChange.emit(this.config.appname); 24 | } 25 | handleInput() { 26 | this.filteredApps = this.getFilterApp(); 27 | if(this.filteredApps.length) { 28 | this.appFocus = true; 29 | } else { 30 | this.appFocus = false; 31 | } 32 | this.onAppSelectChange.emit(this.config.appname); 33 | } 34 | getFilterApp() { 35 | return this.appsList.filter(function(app, index) { 36 | return this.config.appname === '' || (this.config.appname !== '' && app.appname.toUpperCase().indexOf(this.config.appname.toUpperCase()) !== -1) 37 | }.bind(this)); 38 | } 39 | focusInput() { 40 | this.filteredApps = this.getFilterApp(); 41 | if(this.filteredApps.length) { 42 | this.appFocus = true; 43 | } 44 | this.onAppSelectChange.emit(this.config.appname); 45 | } 46 | blurInput() { 47 | setTimeout(function() { 48 | this.appFocus = false; 49 | }.bind(this), 500); 50 | this.onAppSelectChange.emit(this.config.appname); 51 | } 52 | setApp(app: any) { 53 | this.setConfig.emit(app); 54 | this.onAppSelectChange.emit(app.appname); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /assets/css/app.component.css: -------------------------------------------------------------------------------- 1 | .loading { 2 | height: 100%; 3 | width: 100%; 4 | display: table; 5 | background: rgba(247, 247, 247, 0.9); 6 | position: fixed; 7 | z-index: 4; } 8 | .loading .vertical-cell { 9 | height: 100%; 10 | width: 100%; 11 | display: table-cell; 12 | vertical-align: middle; } 13 | 14 | .header { 15 | position: absolute; 16 | top: 0; 17 | left: 0; 18 | width: 100%; 19 | z-index: 9; 20 | background: #f7f7f7; 21 | border-bottom: 0; 22 | padding: 6px; 23 | max-height: 40px; 24 | margin: 0 auto; } 25 | .header .header-container { 26 | display: inline-block; } 27 | .header .header-container .img-container { 28 | max-width: 170px; 29 | display: inline-block; 30 | float: left; 31 | padding: 5px; 32 | left: 10px; } 33 | .header .header-container .tag-line { 34 | padding-left: 15px; 35 | line-height: 30px; 36 | font-size: 20px; } 37 | 38 | .app-container { 39 | position: relative; 40 | padding-top: 88px; 41 | padding-bottom: 0; 42 | height: 100%; } 43 | .app-container .applogin-component { 44 | position: relative; 45 | height: 100%; 46 | padding-top: 60px; 47 | padding-bottom: 36px; } 48 | .app-container .query-main-container { 49 | position: relative; 50 | min-height: 100%; 51 | height: auto; 52 | display: block; } 53 | .app-container.without-hf { 54 | padding: 0; } 55 | .app-container.without-hf .applogin-component { 56 | position: relative; 57 | height: 100%; 58 | padding-top: 0; 59 | padding-bottom: 0; } 60 | .app-container.without-hf .query-result-container.layoutApplied { 61 | padding-bottom: 15px; } 62 | .app-container.without-h { 63 | padding: 0; } 64 | .app-container.without-h .applogin-component { 65 | position: relative; 66 | height: 100%; 67 | padding-top: 0; } 68 | .app-container.without-f .applogin-component { 69 | position: relative; 70 | height: 100%; 71 | padding-bottom: 0; } 72 | -------------------------------------------------------------------------------- /app/queryBlocks/editable/editable.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, Input, AfterViewInit, ViewChild, Output, EventEmitter } from "@angular/core"; 2 | 3 | declare var $; 4 | 5 | @Component({ 6 | selector: 'editable', 7 | templateUrl: './app/queryBlocks/editable/editable.component.html', 8 | inputs: ['editPlaceholder', 'callback', 'selectOption', 'informationList', 'showInfoFlag', 'searchOff', 'setDocSample'] 9 | }) 10 | 11 | export class EditableComponent implements OnInit, OnChanges, AfterViewInit { 12 | @Input() editableField: any; 13 | @Input() editableInput: any; 14 | @Input() result: any; 15 | @Input() querySelector: any; 16 | @Input() selector: any; 17 | @Input() editableModal: any; 18 | @Input() passWithCallback: any; 19 | @Output() callback = new EventEmitter(); 20 | @Output() setDocSample = new EventEmitter < any >(); 21 | 22 | ngOnInit() { 23 | } 24 | ngOnChanges() { 25 | } 26 | 27 | ngAfterViewInit() { 28 | } 29 | 30 | // allow user to select field, or query 31 | // toggle between editable-front and editable-back 32 | // focus to select element 33 | editable_on($event: any) { 34 | $('.editable-pack').removeClass('on'); 35 | $($event.currentTarget).parents('.editable-pack').addClass('on'); 36 | if(this.editableInput == 'select2') { 37 | $($event.currentTarget).parents('.editable-pack').find('select').select2('open'); 38 | } 39 | if(this.editableInput == 'select') { 40 | $($event.currentTarget).parents('.editable-pack').find('select').focus().simulate('mousedown'); 41 | } 42 | } 43 | editable_off($event: any) { 44 | setTimeout(function() { 45 | $('.editable-pack').removeClass('on'); 46 | if(typeof this.passWithCallback != 'undefined') { 47 | var obj = { 48 | external: this.passWithCallback, 49 | value: this.editableModal 50 | }; 51 | this.callback.emit(obj); 52 | } else { 53 | this.callback.emit(this.editableModal); 54 | } 55 | }.bind(this), 300); 56 | } 57 | setDocSampleEve(link) { 58 | this.setDocSample.emit(link); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /assets/styles/main.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | html, body { 3 | height: 100%; 4 | } 5 | .p-l-15 { 6 | padding-left: 15px !important; 7 | } 8 | .pd-0 { 9 | padding: 0 !important; 10 | } 11 | .pd-r0 { 12 | padding-right: 0; 13 | } 14 | .pd-l0 { 15 | padding-left: 0; 16 | } 17 | .pd-r10 { 18 | padding-right: 10px; 19 | } 20 | .pr-5 { 21 | padding-right: 5px !important; 22 | } 23 | .m-r5 { 24 | margin-right: 5px; 25 | } 26 | .m-r10 { 27 | margin-right: 10px; 28 | } 29 | .m-0 { 30 | margin: 0; 31 | } 32 | .m-b0 { 33 | margin-bottom: 0; 34 | } 35 | .m-b15 { 36 | margin-bottom: 15px; 37 | } 38 | .mt-10 { 39 | margin-top: 10px; 40 | } 41 | .mt-5 { 42 | margin-top: 5px; 43 | } 44 | .m-tb-15 { 45 | margin-top: 15px; 46 | margin-bottom: 15px; 47 | } 48 | .clearfix { 49 | clear: both; 50 | } 51 | a { 52 | cursor: pointer; 53 | } 54 | .btn-primary { 55 | color: $contrast-color; 56 | background-color: $primary-color; 57 | border-color: darken($primary-color, 5%); 58 | &:hover, 59 | &:focus, 60 | &.active { 61 | background-color: darken($primary-color, 5%); 62 | } 63 | } 64 | .btn-grey { 65 | color: $grey-font; 66 | border-color: transparent; 67 | background: transparent; 68 | padding: 2px; 69 | &:hover { 70 | color: darken($grey-font, 5%); 71 | } 72 | } 73 | .btn-theme { 74 | color: #fff; 75 | background-color: $primary-color; 76 | border-color: $secondary-color; 77 | &:hover { 78 | color: #fff; 79 | background-color: $secondary-color; 80 | border-color: $secondary-color; 81 | } 82 | } 83 | .btn { 84 | border-radius: 0; 85 | border: 0; 86 | } 87 | html, 88 | body { 89 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 90 | font-size: 14px; 91 | line-height: 1.42857143; 92 | color: #333; 93 | } 94 | a { 95 | color: $link-color; 96 | } 97 | .popover { 98 | z-index: 99999; 99 | min-width: 350px; 100 | } 101 | .disableClick { 102 | pointer-events: none; 103 | } -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/exists.query.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, Input, Output, EventEmitter } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: 'exists-query', 5 | template: ` 6 | `, 7 | inputs: ['getQueryFormat', 'querySelector'] 8 | }) 9 | 10 | export class ExistsQuery implements OnInit, OnChanges { 11 | @Input() queryList; 12 | @Input() selectedField; 13 | @Input() appliedQuery; 14 | @Input() selectedQuery; 15 | @Output() getQueryFormat = new EventEmitter(); 16 | public current_query = 'exists'; 17 | public queryName = '*'; 18 | public fieldName = '*'; 19 | public information: any = { 20 | title: 'Exists', 21 | content: `Returns matches where the field value is not null. 22 | Read more` 23 | }; 24 | 25 | public queryFormat: any = {}; 26 | 27 | ngOnInit() { 28 | try { 29 | if(this.appliedQuery[this.current_query]['field']) { 30 | this.appliedQuery[this.current_query]['field'] = this.fieldName; 31 | } 32 | } catch(e) {} 33 | this.getFormat(); 34 | } 35 | 36 | ngOnChanges() { 37 | if(this.selectedField != '') { 38 | if(this.selectedField !== this.fieldName) { 39 | this.fieldName = this.selectedField; 40 | this.getFormat(); 41 | } 42 | } 43 | if(this.selectedQuery != '') { 44 | if(this.selectedQuery !== this.queryName) { 45 | this.queryName = this.selectedQuery; 46 | this.getFormat(); 47 | } 48 | } 49 | } 50 | 51 | // QUERY FORMAT 52 | /* 53 | Query Format for this query is 54 | @queryName: { 55 | @field: @fieldName 56 | } 57 | */ 58 | getFormat() { 59 | if (this.queryName === this.current_query) { 60 | this.queryFormat = this.setFormat(); 61 | this.getQueryFormat.emit(this.queryFormat); 62 | } 63 | } 64 | setFormat() { 65 | var queryFormat = {}; 66 | queryFormat[this.queryName] = { 67 | 'field': this.fieldName 68 | }; 69 | return queryFormat; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /assets/styles/features_sidebar.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | .feature-query-container { 3 | position: relative; 4 | .features-section { 5 | position: absolute; 6 | width: 250px; 7 | height: 100%; 8 | left: 0; 9 | top: 0; 10 | background: $grey-bg; 11 | border-right: 1px solid darken($grey-bg, 10%); 12 | padding: 15px 0; 13 | z-index: 2; 14 | transition: all 0.2s; 15 | .feature-section-container { 16 | overflow: auto; 17 | display: block; 18 | .feature-btns { 19 | padding: 0 15px; 20 | } 21 | .theme-list { 22 | list-style: none; 23 | padding: 0; 24 | margin-top: 0; 25 | li.list-item { 26 | display: block; 27 | border-bottom: 1px solid darken($grey-bg, 10%); 28 | padding: 10px 15px 10px 15px; 29 | cursor: pointer; 30 | .query-name { 31 | padding: 0; 32 | padding-bottom: 10px; 33 | } 34 | .query-time { 35 | font-size: 10px 36 | } 37 | &:hover { 38 | background: darken($grey-bg, 10%); 39 | .delete-query { 40 | display: inline-block; 41 | } 42 | } 43 | &.list-title { 44 | background: $primary-color; 45 | color: $contrast-color; 46 | } 47 | .delete-query { 48 | position: absolute; 49 | right: 5px; 50 | top: 5px; 51 | display: none; 52 | } 53 | } 54 | } 55 | } 56 | .sidebar-toggle { 57 | position: absolute; 58 | right: -27px; 59 | top: 40%; 60 | z-index: 3; 61 | padding: 13px 8px; 62 | background: $primary-color; 63 | color: $contrast-color; 64 | border: 0; 65 | border-top-left-radius: 0; 66 | border-bottom-left-radius: 0; 67 | border-left: 1px solid darken($primary-color, 10%); 68 | .sidebar-open { 69 | display: none; 70 | } 71 | } 72 | .btn-sort { 73 | background: #eee; 74 | color: #aaa; 75 | &.active { 76 | color: #555; 77 | } 78 | } 79 | } 80 | &.off { 81 | .features-section { 82 | width: 0; 83 | .feature-section-container { 84 | display: none; 85 | } 86 | .sidebar-open { 87 | display: inline-block; 88 | } 89 | .sidebar-close { 90 | display: none; 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mirage", 3 | "version": "0.11.0", 4 | "description": "🔎 GUI for Elasticsearch Queries", 5 | "author": "Appbase Inc.", 6 | "license": "Apache-2.0", 7 | "main": "index.js", 8 | "scripts": { 9 | "tsc": "tsc", 10 | "tsc:w": "tsc -w", 11 | "postinstall": "typings install", 12 | "typings": "typings", 13 | "lite": "lite-server", 14 | "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" \"gulp watch\" ", 15 | "test": "live-server --open=unit-tests.html", 16 | "build": "tsc && gulp build", 17 | "build_gh_pages": "npm run build && gulp build_gh_pages", 18 | "build_es_plugin": "npm run build && gulp build_es_plugin", 19 | "build_chrome_extension": "npm run build && gulp build_chrome_extension && sh chrome-build.sh", 20 | "build:all": "npm run build && gulp build_gh_pages && gulp build_es_plugin && gulp build_chrome_extension" 21 | }, 22 | "dependencies": { 23 | "@angular/common": "~2.0.2", 24 | "@angular/compiler": "~2.0.2", 25 | "@angular/core": "~2.0.2", 26 | "@angular/forms": "~2.0.2", 27 | "@angular/http": "~2.0.2", 28 | "@angular/platform-browser": "~2.0.2", 29 | "@angular/platform-browser-dynamic": "~2.0.2", 30 | "@angular/upgrade": "~2.0.2", 31 | "angular-in-memory-web-api": "~0.1.5", 32 | "appbase-js": "2.2.6", 33 | "bootstrap": "^3.4.1", 34 | "core-js": "^2.4.0", 35 | "gulp-sass": "^2.3.1", 36 | "moment": "^2.13.0", 37 | "node-sass": "^3.6.0", 38 | "reflect-metadata": "^0.1.3", 39 | "rxjs": "5.0.0-beta.6", 40 | "systemjs": "0.19.27", 41 | "zone.js": "^0.6.12" 42 | }, 43 | "devDependencies": { 44 | "browserify": "^13.0.1", 45 | "concurrently": "^2.0.0", 46 | "gulp": "^3.9.1", 47 | "gulp-browserify": "^0.5.1", 48 | "gulp-concat": "^2.6.0", 49 | "gulp-connect": "^2.2.0", 50 | "gulp-livereload": "^3.7.0", 51 | "gulp-minify-css": "^1.2.4", 52 | "gulp-rename": "^1.2.2", 53 | "gulp-uglify": "^1.5.3", 54 | "gulp-watch": "^4.3.5", 55 | "jasmine-core": "2.4.1", 56 | "lite-server": "^2.2.0", 57 | "live-server": "^1.2.1", 58 | "typescript": "^1.8.10", 59 | "typings": "^1.3.2", 60 | "uglifyjs": "^2.4.10" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/features/subscribe/subscribe.component.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 39 | 40 | -------------------------------------------------------------------------------- /assets/styles/features.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | .feature-query-container { 3 | position: relative; 4 | .features-section { 5 | position: absolute; 6 | width: 250px; 7 | height: 100%; 8 | left: 0; 9 | top: 0; 10 | background: $grey-bg; 11 | border-right: 1px solid darken($grey-bg, 10%); 12 | padding: 15px 0; 13 | z-index: 2; 14 | transition: all 0.2s; 15 | .feature-section-container { 16 | overflow: auto; 17 | display: block; 18 | .feature-btns { 19 | padding: 0 15px; 20 | } 21 | .theme-list { 22 | list-style: none; 23 | padding: 0; 24 | margin-top: 0; 25 | li.list-item { 26 | display: block; 27 | border-bottom: 1px solid darken($grey-bg, 10%); 28 | padding: 10px 15px 10px 15px; 29 | cursor: pointer; 30 | .query-name { 31 | padding: 0; 32 | padding-bottom: 10px; 33 | } 34 | .query-time { 35 | font-size: 10px 36 | } 37 | &:hover { 38 | background: darken($grey-bg, 10%); 39 | .delete-query { 40 | display: inline-block; 41 | } 42 | } 43 | &.list-title { 44 | background: $primary-color; 45 | color: $contrast-color; 46 | } 47 | .delete-query { 48 | position: absolute; 49 | right: 5px; 50 | top: 5px; 51 | display: none; 52 | } 53 | } 54 | } 55 | } 56 | .sidebar-toggle { 57 | position: absolute; 58 | right: -27px; 59 | top: 40%; 60 | z-index: 3; 61 | padding: 13px 8px; 62 | background: $primary-color; 63 | color: $contrast-color; 64 | border: 0; 65 | border-top-left-radius: 0; 66 | border-bottom-left-radius: 0; 67 | border-left: 1px solid darken($primary-color, 10%); 68 | .sidebar-open { 69 | display: none; 70 | } 71 | } 72 | .btn-sort { 73 | background: #eee; 74 | color: #aaa; 75 | &.active { 76 | color: #555; 77 | } 78 | } 79 | } 80 | .query-main-container { 81 | padding: 0 0 0 250px; 82 | transition: all 0.2s; 83 | .query-build { 84 | padding-left: 35px; 85 | } 86 | } 87 | &.off { 88 | .features-section { 89 | width: 0; 90 | .feature-section-container { 91 | display: none; 92 | } 93 | .sidebar-open { 94 | display: inline-block; 95 | } 96 | .sidebar-close { 97 | display: none; 98 | } 99 | } 100 | .query-main-container { 101 | padding-left: 0; 102 | } 103 | } 104 | .select2-container { 105 | width: 100% !important; 106 | } 107 | } -------------------------------------------------------------------------------- /app/features/learn/learn.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 38 | 39 | 40 | 54 | 55 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/terms.query.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, Input, Output, EventEmitter } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: 'terms-query', 5 | template: ` 6 |
7 | 11 |
12 |
`, 13 | inputs: ['getQueryFormat', 'querySelector'] 14 | }) 15 | 16 | export class TermsQuery implements OnInit, OnChanges { 17 | @Input() queryList; 18 | @Input() selectedField; 19 | @Input() appliedQuery; 20 | @Input() selectedQuery; 21 | @Output() getQueryFormat = new EventEmitter(); 22 | public queryName = '*'; 23 | public fieldName = '*'; 24 | public information: any = { 25 | title: 'Terms', 26 | content: `Returns matches with one of the exact values from the provided terms. 27 | Read more` 28 | }; 29 | 30 | public inputs: any = { 31 | input: { 32 | placeholder: 'Input', 33 | value: '' 34 | } 35 | }; 36 | public queryFormat: any = {}; 37 | 38 | ngOnInit() { 39 | try { 40 | if(this.appliedQuery['terms'][this.fieldName]) { 41 | try { 42 | this.inputs.input.value = this.appliedQuery['terms'][this.fieldName].join(' '); 43 | } catch(e) { 44 | this.inputs.input.value = this.appliedQuery['terms'][this.fieldName]; 45 | } 46 | } 47 | } catch(e) {} 48 | this.getFormat(); 49 | } 50 | ngOnChanges() { 51 | if(this.selectedField != '') { 52 | if(this.selectedField !== this.fieldName) { 53 | this.fieldName = this.selectedField; 54 | this.getFormat(); 55 | } 56 | } 57 | if(this.selectedQuery != '') { 58 | if(this.selectedQuery !== this.queryName) { 59 | this.queryName = this.selectedQuery; 60 | this.getFormat(); 61 | } 62 | } 63 | } 64 | 65 | // QUERY FORMAT 66 | /* 67 | Query Format for this query is 68 | @queryName: { 69 | @fieldName: @value 70 | } 71 | */ 72 | 73 | getFormat() { 74 | if (this.queryName === 'terms') { 75 | this.queryFormat = this.setFormat(); 76 | this.getQueryFormat.emit(this.queryFormat); 77 | } 78 | } 79 | setFormat() { 80 | var queryFormat = {}; 81 | queryFormat[this.queryName] = {}; 82 | try { 83 | queryFormat[this.queryName][this.fieldName] = this.inputs.input.value.split(','); 84 | } catch(e) { 85 | queryFormat[this.queryName][this.fieldName] = this.inputs.input.value.join(','); 86 | } 87 | return queryFormat; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/ids.query.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, Input, Output, EventEmitter } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: 'ids-query', 5 | template: ` 6 |
7 | 11 |
12 |
`, 13 | inputs: ['getQueryFormat', 'querySelector'] 14 | }) 15 | 16 | export class IdsQuery implements OnInit, OnChanges { 17 | @Input() queryList: any; 18 | @Input() selectedField: any; 19 | @Input() appliedQuery: any; 20 | @Input() selectedQuery: any; 21 | @Input() selectedTypes: any; 22 | @Output() getQueryFormat = new EventEmitter(); 23 | public queryName = '*'; 24 | public fieldName = '*'; 25 | public information: any = { 26 | title: 'Ids', 27 | content: `Returns matches that only have the provided ids (_id field). 28 | Read more` 29 | }; 30 | 31 | public inputs: any = { 32 | input: { 33 | placeholder: 'Input', 34 | value: '' 35 | } 36 | }; 37 | public queryFormat: any = {}; 38 | 39 | ngOnInit() { 40 | try { 41 | if(this.appliedQuery['ids']) { 42 | try { 43 | this.inputs.input.value = this.appliedQuery['ids'].values.join(','); 44 | } catch(e) { 45 | this.inputs.input.value = this.appliedQuery['ids'].values; 46 | } 47 | } 48 | } catch(e) {} 49 | this.getFormat(); 50 | } 51 | ngOnChanges() { 52 | if(this.selectedField != '') { 53 | if(this.selectedField !== this.fieldName) { 54 | this.fieldName = this.selectedField; 55 | this.getFormat(); 56 | } 57 | } 58 | if(this.selectedQuery != '') { 59 | if(this.selectedQuery !== this.queryName) { 60 | this.queryName = this.selectedQuery; 61 | this.getFormat(); 62 | } 63 | } 64 | } 65 | 66 | // QUERY FORMAT 67 | /* 68 | Query Format for this query is 69 | @queryName: { 70 | @fieldName: { 71 | type: @type, 72 | values: @value 73 | } 74 | } 75 | */ 76 | 77 | getFormat() { 78 | if (this.queryName === 'ids') { 79 | this.queryFormat = this.setFormat(); 80 | this.getQueryFormat.emit(this.queryFormat); 81 | } 82 | } 83 | setFormat() { 84 | var queryFormat = {}; 85 | queryFormat[this.queryName] = { 86 | values: [], 87 | type: this.selectedTypes 88 | }; 89 | try { 90 | queryFormat[this.queryName].values = this.inputs.input.value.split(','); 91 | } catch(e) { 92 | queryFormat[this.queryName].values = []; 93 | } 94 | return queryFormat; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /assets/css/modal.css: -------------------------------------------------------------------------------- 1 | .modal-backdrop { 2 | display: none; } 3 | 4 | .modal.in:before { 5 | content: ""; 6 | position: fixed; 7 | top: 0; 8 | right: 0; 9 | bottom: 0; 10 | left: 0; 11 | z-index: 1040; 12 | background-color: #000; 13 | opacity: 0.3; } 14 | 15 | .modal.in .modal-dialog { 16 | z-index: 1045; } 17 | 18 | .modal .modal-content { 19 | background: #fff; 20 | border-radius: 4px; 21 | border: 3px solid; 22 | border-color: #FCC829; 23 | background: #f7f7f7; } 24 | 25 | .modal .modal-header { 26 | border: 0; 27 | padding: 5px 15px 0 15px; 28 | color: #FCC829; } 29 | 30 | .modal .modal-footer { 31 | border: 0; } 32 | 33 | .modal .modal-header .close { 34 | width: 20px; 35 | height: 20px; 36 | border-radius: 100%; 37 | border: 1px solid; 38 | font-size: 14px; 39 | line-height: 0px; 40 | padding: 3px 0; 41 | text-align: center; 42 | position: absolute; 43 | right: 5px; 44 | top: 5px; 45 | margin-top: 0; 46 | background: transparent; 47 | opacity: 1; 48 | color: #FCC829; } 49 | 50 | .modal .btn-success { 51 | background: transparent; 52 | color: #FCC829; 53 | border-color: #FCC829; } 54 | 55 | .modal .btn-success:hover { 56 | background: #FCC829; 57 | color: #fff; } 58 | 59 | .modal .btn-info { 60 | background: transparent; 61 | color: #FCC829; 62 | border-color: #FCC829; } 63 | 64 | .modal .btn-info:hover { 65 | background: #FCC829; 66 | color: #fff; } 67 | 68 | .modal.modal-info .modal-content { 69 | border-color: #FCC829; } 70 | 71 | .modal.modal-warning .modal-content { 72 | border-color: #F5E79E; } 73 | 74 | .modal.modal-warning .modal-header { 75 | color: #F5E79E; } 76 | 77 | .modal.modal-warning .close { 78 | color: #F5E79E; } 79 | 80 | .modal .btn-warning { 81 | background: transparent; 82 | color: #F5E79E; 83 | border-color: #F5E79E; } 84 | 85 | .modal .btn-warning:hover { 86 | background: #F5E79E; 87 | color: #fff; } 88 | 89 | .modal .btn-danger { 90 | background: transparent; 91 | color: #FF8484; 92 | border-color: #FF8484; } 93 | 94 | .modal .btn-danger:hover { 95 | background: #FF8484; 96 | color: #fff; } 97 | 98 | .modal.modal-danger .modal-content { 99 | border-color: #FF8484; } 100 | 101 | .modal.modal-danger .modal-header { 102 | color: #FF8484; } 103 | 104 | .modal.modal-danger .close { 105 | color: #FF8484; } 106 | 107 | #resultModal .modal-dialog { 108 | width: 90%; 109 | position: relative; } 110 | #resultModal .modal-dialog .modal-body { 111 | height: 70%; 112 | position: relative; } 113 | #resultModal .modal-dialog .modal-body .CodeMirror { 114 | height: 100%; } 115 | #resultModal .modal-dialog .modal-body .tab-content { 116 | height: calc(100% - 30px); } 117 | -------------------------------------------------------------------------------- /app/result/result.component.html: -------------------------------------------------------------------------------- 1 | 2 | 86 | -------------------------------------------------------------------------------- /app/result/result.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, Input, Output } from "@angular/core"; 2 | import { SafeResourceUrl, DomSanitizer } from "@angular/platform-browser"; 3 | import { UrlShare } from "../shared/urlShare"; 4 | declare var $: any; 5 | 6 | @Component({ 7 | selector: "query-result", 8 | templateUrl: "./app/result/result.component.html", 9 | inputs: [ 10 | "mapping", 11 | "config", 12 | "editorHookHelp", 13 | "urlShare", 14 | "responseHookHelp", 15 | "result_time_taken", 16 | "result_random_token", 17 | "types", 18 | "result", 19 | "config", 20 | "responseHookHelp", 21 | "result_time_taken" 22 | ] 23 | }) 24 | export class ResultComponent implements OnInit, OnChanges { 25 | public mapping: any; 26 | public config: any; 27 | public responseHookHelp: any; 28 | public url: SafeResourceUrl; 29 | public urlShare: any; 30 | public editorHookHelp: any; 31 | public urlAvailable: boolean = false; 32 | @Input() selectedTypes: any; 33 | @Input() responseMode: string; 34 | // public dejavuDomain: string = 'http://localhost:1358/'; 35 | public dejavuDomain: string = "https://dejavu.appbase.io/"; 36 | 37 | constructor(private sanitizer: DomSanitizer) {} 38 | 39 | ngOnInit() { 40 | this.responseHookHelp.applyEditor({ readOnly: true }); 41 | } 42 | 43 | ngOnChanges(changes) { 44 | if (changes && changes["result_random_token"]) { 45 | var prev = changes["result_random_token"].previousValue; 46 | var current = changes["result_random_token"].currentValue; 47 | if (current && prev !== current && this.editorHookHelp) { 48 | var getQuery = this.editorHookHelp.getValue(); 49 | if (getQuery) { 50 | console.log(this.selectedTypes); 51 | getQuery = getQuery.trim(); 52 | getQuery = JSON.parse(getQuery); 53 | var queryObj = { 54 | query: getQuery, 55 | type: this.selectedTypes 56 | }; 57 | this.url = this.sanitizeUrl(this.dejavuDomain); 58 | setTimeout( 59 | function() { 60 | var url = 61 | this.dejavuDomain + 62 | "?mode=edit&appswitcher=false&sidebar=false&oldBanner=false&appname=" + 63 | this.urlShare.inputs.appname + 64 | "&url=" + 65 | this.urlShare.inputs.url; 66 | url = 67 | url + 68 | "&hf=false&sidebar=false&subscribe=false&query=" + 69 | JSON.stringify(queryObj); 70 | this.url = this.sanitizeUrl(url); 71 | console.log(this.url); 72 | }.bind(this), 73 | 300 74 | ); 75 | this.urlAvailable = true; 76 | } 77 | } 78 | } 79 | } 80 | 81 | sanitizeUrl(url) { 82 | return this.sanitizer.bypassSecurityTrustResourceUrl(url); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /assets/styles/modal.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | .modal-backdrop { 3 | display: none; 4 | } 5 | .modal.in:before { 6 | content: ""; 7 | position: fixed; 8 | top: 0; 9 | right: 0; 10 | bottom: 0; 11 | left: 0; 12 | z-index: 1040; 13 | background-color: #000; 14 | opacity: 0.3; 15 | } 16 | .modal.in .modal-dialog { 17 | z-index: 1045; 18 | } 19 | .modal .modal-content { 20 | background: #fff; 21 | border-radius: 4px; 22 | border: 3px solid; 23 | border-color: $primary-color; 24 | background: $grey-bg; 25 | } 26 | .modal .modal-header { 27 | border: 0; 28 | padding: 5px 15px 0 15px; 29 | color: $primary-color; 30 | } 31 | .modal .modal-footer { 32 | border: 0; 33 | } 34 | .modal .modal-header .close { 35 | width: 20px; 36 | height: 20px; 37 | border-radius: 100%; 38 | border: 1px solid; 39 | font-size: 14px; 40 | line-height: 0px; 41 | padding: 3px 0; 42 | text-align: center; 43 | position: absolute; 44 | right: 5px; 45 | top: 5px; 46 | margin-top: 0; 47 | background: transparent; 48 | opacity: 1; 49 | color: $primary-color; 50 | } 51 | .modal .btn-success { 52 | background: transparent; 53 | color: $primary-color; 54 | border-color: $primary-color; 55 | } 56 | .modal .btn-success:hover { 57 | background: $primary-color; 58 | color: #fff; 59 | } 60 | .modal .btn-info { 61 | background: transparent; 62 | color: $primary-color; 63 | border-color: $primary-color; 64 | } 65 | .modal .btn-info:hover { 66 | background: $primary-color; 67 | color: #fff; 68 | } 69 | .modal.modal-info .modal-content { 70 | border-color: $primary-color; 71 | } 72 | .modal.modal-warning .modal-content { 73 | border-color: #F5E79E; 74 | } 75 | .modal.modal-warning .modal-header { 76 | color: #F5E79E; 77 | } 78 | .modal.modal-warning .close { 79 | color: #F5E79E; 80 | } 81 | .modal .btn-warning { 82 | background: transparent; 83 | color: #F5E79E; 84 | border-color: #F5E79E; 85 | } 86 | .modal .btn-warning:hover { 87 | background: #F5E79E; 88 | color: #fff; 89 | } 90 | .modal .btn-danger { 91 | background: transparent; 92 | color: #FF8484; 93 | border-color: #FF8484; 94 | } 95 | .modal .btn-danger:hover { 96 | background: #FF8484; 97 | color: #fff; 98 | } 99 | .modal.modal-danger .modal-content { 100 | border-color: #FF8484; 101 | } 102 | .modal.modal-danger .modal-header { 103 | color: #FF8484; 104 | } 105 | .modal.modal-danger .close { 106 | color: #FF8484; 107 | } 108 | #resultModal { 109 | .modal-dialog { 110 | width: 90%; 111 | position: relative; 112 | .modal-body { 113 | height: 70%; 114 | position: relative; 115 | .CodeMirror { 116 | height: 100%; 117 | } 118 | .tab-content { 119 | height: calc(100% - 30px); 120 | } 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /app/features/share/share.url.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, SimpleChange, Input, Output, EventEmitter } from "@angular/core"; 2 | declare var $: any; 3 | 4 | @Component({ 5 | selector: 'share-url', 6 | templateUrl: './app/features/share/share.url.component.html' 7 | }) 8 | 9 | export class ShareUrlComponent implements OnInit, OnChanges { 10 | @Input() urlShare: any; 11 | ngOnInit() { 12 | var info = { 13 | title: 'Share Url', 14 | content: ``, 18 | html: true, 19 | trigger: 'click' 20 | }; 21 | $('.share-btn').popover(info); 22 | $('.share-btn').on('shown.bs.popover', function () { 23 | this.shareClick(); 24 | }.bind(this)); 25 | $('.share-btn').on('hidden.bs.popover', function () { 26 | $('.share_content .success-msg').hide(); 27 | }.bind(this)) 28 | } 29 | ngOnChanges() { 30 | 31 | } 32 | 33 | shareClick() { 34 | var link = this.urlShare.convertToUrl('gh-pages'); 35 | $('#for-share').val(link); 36 | var ele = document.getElementById('for-share'); 37 | var succeed = this.copyToClipboard(ele); 38 | if(succeed) { 39 | $('.share_content .success-msg').show(); 40 | } 41 | } 42 | copyToClipboard(elem) { 43 | // create hidden text element, if it doesn't already exist 44 | var targetId = "_hiddenCopyText_"; 45 | var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA"; 46 | var origSelectionStart, origSelectionEnd; 47 | var target: any; 48 | if (isInput) { 49 | // can just use the original source element for the selection and copy 50 | target = elem; 51 | origSelectionStart = elem.selectionStart; 52 | origSelectionEnd = elem.selectionEnd; 53 | } else { 54 | // must use a temporary form element for the selection and copy 55 | target = document.getElementById(targetId); 56 | if (!target) { 57 | target = document.createElement("textarea"); 58 | target.style.position = "absolute"; 59 | target.style.left = "-9999px"; 60 | target.style.top = "0"; 61 | target.id = targetId; 62 | document.body.appendChild(target); 63 | } 64 | target.textContent = elem.textContent; 65 | } 66 | // select the content 67 | var currentFocus: any = document.activeElement; 68 | target.focus(); 69 | target.setSelectionRange(0, target.value.length); 70 | 71 | // copy the selection 72 | var succeed; 73 | try { 74 | succeed = document.execCommand("copy"); 75 | } catch (e) { 76 | succeed = false; 77 | } 78 | // restore original focus 79 | if (currentFocus && typeof currentFocus.focus === "function") { 80 | currentFocus.focus(); 81 | } 82 | 83 | if (isInput) { 84 | // restore prior selection 85 | elem.setSelectionRange(origSelectionStart, origSelectionEnd); 86 | } else { 87 | // clear temporary content 88 | target.textContent = ""; 89 | } 90 | return succeed; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /assets/styles/result.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | .query-result-container.layoutApplied { 3 | background: $grey-bg; 4 | padding-bottom: 45px; 5 | .queryRight { 6 | padding: 32px 15px 15px 0; 7 | background: $grey-bg; 8 | border-left: 1px solid darken($grey-bg, 10%); 9 | height: 100%; 10 | position: relative; 11 | .rightRow { 12 | position: absolute; 13 | left: 0; 14 | width: 100%; 15 | margin: 0; 16 | padding: 0 15px; 17 | &.url-row { 18 | top: 0; 19 | } 20 | &.run-row { 21 | bottom: -23px; 22 | padding-bottom: 0; 23 | z-index: 10; 24 | } 25 | } 26 | .codeMirror-container { 27 | height: 95%; 28 | position: relative; 29 | padding: 0; 30 | overflow: auto; 31 | .CodeMirror { 32 | height: 100%; 33 | } 34 | .form-group { 35 | margin-bottom: 0; 36 | } 37 | } 38 | } 39 | @media screen and (max-width: 768px) { 40 | padding-bottom: 0; 41 | } 42 | } 43 | 44 | .codemirror { 45 | margin-bottom: 15px; 46 | } 47 | .streaming-response { 48 | -webkit-animation: streaming 2s ease-in-out; 49 | animation: streaming 2s ease-in-out; 50 | } 51 | .stream-signal { 52 | width: 2rem; 53 | height: 2rem; 54 | float: left; 55 | margin-right: 8px; 56 | display: inline-block; 57 | border-radius: 50%; 58 | border: 2px solid #888; 59 | position: relative; 60 | &:before { 61 | content: " "; 62 | position: absolute; 63 | width: 100%; 64 | height: 100%; 65 | background: transparent; 66 | left: 0; 67 | top: 0; 68 | border-radius: 50%; 69 | border: 2px solid #fff; 70 | } 71 | &.warning { 72 | background-color: #f0ad4e; 73 | } 74 | &.success { 75 | background-color: #5cb85c; 76 | } 77 | .spinner { 78 | width: 100%; 79 | height: 100%; 80 | display: block; 81 | background-color: rgba(0, 0, 0, 0.2); 82 | border-radius: 100%; 83 | &.active { 84 | background-color: #333; 85 | -webkit-animation: stream-signal 1s infinite ease-in-out; 86 | animation: stream-signal 1s infinite ease-in-out; 87 | } 88 | } 89 | } 90 | 91 | @-webkit-keyframes stream-signal { 92 | 0% { 93 | -webkit-transform: scale(0); 94 | } 95 | 100% { 96 | -webkit-transform: scale(1); 97 | opacity: 0; 98 | } 99 | } 100 | 101 | @keyframes stream-signal { 102 | 0% { 103 | -webkit-transform: scale(0); 104 | transform: scale(0); 105 | } 106 | 100% { 107 | -webkit-transform: scale(1); 108 | transform: scale(1); 109 | opacity: 0; 110 | } 111 | } 112 | 113 | @-webkit-keyframes streaming { 114 | 0% { 115 | background: #b6ef7e; 116 | } 117 | 100% { 118 | background: transparent; 119 | } 120 | } 121 | 122 | @keyframes streaming { 123 | 0% { 124 | background: #b6ef7e; 125 | } 126 | 100% { 127 | background: transparent; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /assets/css/result.css: -------------------------------------------------------------------------------- 1 | .query-result-container.layoutApplied { 2 | background: #f7f7f7; 3 | padding-bottom: 45px; } 4 | .query-result-container.layoutApplied .queryRight { 5 | padding: 32px 15px 15px 0; 6 | background: #f7f7f7; 7 | border-left: 1px solid #dedede; 8 | height: 100%; 9 | position: relative; } 10 | .query-result-container.layoutApplied .queryRight .rightRow { 11 | position: absolute; 12 | left: 0; 13 | width: 100%; 14 | margin: 0; 15 | padding: 0 15px; } 16 | .query-result-container.layoutApplied .queryRight .rightRow.url-row { 17 | top: 0; } 18 | .query-result-container.layoutApplied .queryRight .rightRow.run-row { 19 | bottom: -23px; 20 | padding-bottom: 0; 21 | z-index: 10; } 22 | .query-result-container.layoutApplied .queryRight .codeMirror-container { 23 | height: 95%; 24 | position: relative; 25 | padding: 0; 26 | overflow: auto; } 27 | .query-result-container.layoutApplied .queryRight .codeMirror-container .CodeMirror { 28 | height: 100%; } 29 | .query-result-container.layoutApplied .queryRight .codeMirror-container .form-group { 30 | margin-bottom: 0; } 31 | @media screen and (max-width: 768px) { 32 | .query-result-container.layoutApplied { 33 | padding-bottom: 0; } } 34 | 35 | .codemirror { 36 | margin-bottom: 15px; } 37 | 38 | .streaming-response { 39 | -webkit-animation: streaming 2s ease-in-out; 40 | animation: streaming 2s ease-in-out; } 41 | 42 | .stream-signal { 43 | width: 2rem; 44 | height: 2rem; 45 | float: left; 46 | margin-right: 8px; 47 | display: inline-block; 48 | border-radius: 50%; 49 | border: 2px solid #888; 50 | position: relative; } 51 | .stream-signal:before { 52 | content: " "; 53 | position: absolute; 54 | width: 100%; 55 | height: 100%; 56 | background: transparent; 57 | left: 0; 58 | top: 0; 59 | border-radius: 50%; 60 | border: 2px solid #fff; } 61 | .stream-signal.warning { 62 | background-color: #f0ad4e; } 63 | .stream-signal.success { 64 | background-color: #5cb85c; } 65 | .stream-signal .spinner { 66 | width: 100%; 67 | height: 100%; 68 | display: block; 69 | background-color: rgba(0, 0, 0, 0.2); 70 | border-radius: 100%; } 71 | .stream-signal .spinner.active { 72 | background-color: #333; 73 | -webkit-animation: stream-signal 1s infinite ease-in-out; 74 | animation: stream-signal 1s infinite ease-in-out; } 75 | 76 | @-webkit-keyframes stream-signal { 77 | 0% { 78 | -webkit-transform: scale(0); } 79 | 100% { 80 | -webkit-transform: scale(1); 81 | opacity: 0; } } 82 | 83 | @keyframes stream-signal { 84 | 0% { 85 | -webkit-transform: scale(0); 86 | transform: scale(0); } 87 | 100% { 88 | -webkit-transform: scale(1); 89 | transform: scale(1); 90 | opacity: 0; } } 91 | 92 | @-webkit-keyframes streaming { 93 | 0% { 94 | background: #b6ef7e; } 95 | 100% { 96 | background: transparent; } } 97 | 98 | @keyframes streaming { 99 | 0% { 100 | background: #b6ef7e; } 101 | 100% { 102 | background: transparent; } } 103 | -------------------------------------------------------------------------------- /assets/css/features_sidebar.css: -------------------------------------------------------------------------------- 1 | .feature-query-container { 2 | position: relative; } 3 | .feature-query-container .features-section { 4 | position: absolute; 5 | width: 250px; 6 | height: 100%; 7 | left: 0; 8 | top: 0; 9 | background: #f7f7f7; 10 | border-right: 1px solid #dedede; 11 | padding: 15px 0; 12 | z-index: 2; 13 | transition: all 0.2s; } 14 | .feature-query-container .features-section .feature-section-container { 15 | overflow: auto; 16 | display: block; } 17 | .feature-query-container .features-section .feature-section-container .feature-btns { 18 | padding: 0 15px; } 19 | .feature-query-container .features-section .feature-section-container .theme-list { 20 | list-style: none; 21 | padding: 0; 22 | margin-top: 0; } 23 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item { 24 | display: block; 25 | border-bottom: 1px solid #dedede; 26 | padding: 10px 15px 10px 15px; 27 | cursor: pointer; } 28 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item .query-name { 29 | padding: 0; 30 | padding-bottom: 10px; } 31 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item .query-time { 32 | font-size: 10px; } 33 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item:hover { 34 | background: #dedede; } 35 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item:hover .delete-query { 36 | display: inline-block; } 37 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item.list-title { 38 | background: #FCC829; 39 | color: #fff; } 40 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item .delete-query { 41 | position: absolute; 42 | right: 5px; 43 | top: 5px; 44 | display: none; } 45 | .feature-query-container .features-section .sidebar-toggle { 46 | position: absolute; 47 | right: -27px; 48 | top: 40%; 49 | z-index: 3; 50 | padding: 13px 8px; 51 | background: #FCC829; 52 | color: #fff; 53 | border: 0; 54 | border-top-left-radius: 0; 55 | border-bottom-left-radius: 0; 56 | border-left: 1px solid #efb503; } 57 | .feature-query-container .features-section .sidebar-toggle .sidebar-open { 58 | display: none; } 59 | .feature-query-container .features-section .btn-sort { 60 | background: #eee; 61 | color: #aaa; } 62 | .feature-query-container .features-section .btn-sort.active { 63 | color: #555; } 64 | .feature-query-container.off .features-section { 65 | width: 0; } 66 | .feature-query-container.off .features-section .feature-section-container { 67 | display: none; } 68 | .feature-query-container.off .features-section .sidebar-open { 69 | display: inline-block; } 70 | .feature-query-container.off .features-section .sidebar-close { 71 | display: none; } 72 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/exists.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { ExistsQuery } from './exists.query'; 2 | 3 | describe('exists query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: ExistsQuery; 8 | var expectedFormat = { 9 | 'exists': { 10 | 'field': 'name' 11 | } 12 | }; 13 | 14 | // instantiate query component and set the input fields 15 | beforeEach(function() { 16 | query = new ExistsQuery(); 17 | query.queryName = 'exists'; 18 | query.fieldName = 'name'; 19 | }); 20 | 21 | function isValidJson(str: string) { 22 | try { 23 | JSON.parse(str); 24 | } catch (e) { 25 | return false; 26 | } 27 | return true; 28 | } 29 | 30 | // Test to check if queryformat is valid json 31 | it('is valid json', () => { 32 | var format = query.setFormat(); 33 | var validJson = isValidJson(JSON.stringify(format)); 34 | expect(validJson).toEqual(true); 35 | }); 36 | 37 | // Test to check if result of setformat is equal to expected query format. 38 | it('Is setformat matches with expected query format', () => { 39 | var format = query.setFormat(); 40 | expect(format).toEqual(expectedFormat); 41 | }); 42 | 43 | }) 44 | 45 | 46 | declare var $; 47 | describe("xhr call (Exists)", function () { 48 | var returnedJSON: any = {}; 49 | var status = 0; 50 | 51 | beforeEach(function (done) { 52 | var query = new ExistsQuery(); 53 | query.queryName = 'exists'; 54 | query.fieldName = 'name'; 55 | var config = { 56 | url: 'https://scalr.api.appbase.io', 57 | appname: 'mirage_test', 58 | username: 'wvCmyBy3D', 59 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 60 | }; 61 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 62 | var query_data = query.setFormat(); 63 | var request_data = { 64 | "query": { 65 | "bool": { 66 | "must": [query_data] 67 | } 68 | } 69 | }; 70 | $.ajax({ 71 | type: 'POST', 72 | beforeSend: function(request) { 73 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 74 | }, 75 | url: url, 76 | contentType: 'application/json; charset=utf-8', 77 | dataType: 'json', 78 | data: JSON.stringify(request_data), 79 | xhrFields: { 80 | withCredentials: true 81 | }, 82 | success: function(res) { 83 | returnedJSON = res; 84 | status = 200; 85 | done(); 86 | }, 87 | error: function(xhr) { 88 | returnedJSON = xhr; 89 | status = xhr.status; 90 | done(); 91 | } 92 | }); 93 | }); 94 | 95 | it("Should have returned JSON and Should have atleast 1 record", function () { 96 | expect(returnedJSON).not.toEqual({}); 97 | expect(returnedJSON).not.toBeUndefined(); 98 | expect(status).toEqual(200); 99 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 100 | }); 101 | 102 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/missing.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { MissingQuery } from './missing.query'; 2 | 3 | describe('missing query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: MissingQuery; 8 | var expectedFormat = { 9 | 'missing': { 10 | 'field': 'name' 11 | } 12 | }; 13 | 14 | // instantiate query component and set the input fields 15 | beforeEach(function() { 16 | query = new MissingQuery(); 17 | query.queryName = 'missing'; 18 | query.fieldName = 'name'; 19 | }); 20 | 21 | function isValidJson(str: string) { 22 | try { 23 | JSON.parse(str); 24 | } catch (e) { 25 | return false; 26 | } 27 | return true; 28 | } 29 | 30 | // Test to check if queryformat is valid json 31 | it('is valid json', () => { 32 | var format = query.setFormat(); 33 | var validJson = isValidJson(JSON.stringify(format)); 34 | expect(validJson).toEqual(true); 35 | }); 36 | 37 | // Test to check if result of setformat is equal to expected query format. 38 | it('Is setformat matches with expected query format', () => { 39 | var format = query.setFormat(); 40 | expect(format).toEqual(expectedFormat); 41 | }); 42 | 43 | }) 44 | 45 | 46 | declare var $; 47 | describe("xhr call (missing)", function () { 48 | var returnedJSON: any = {}; 49 | var status = 0; 50 | 51 | beforeEach(function (done) { 52 | var query = new MissingQuery(); 53 | query.queryName = 'missing'; 54 | query.fieldName = 'address'; 55 | var config = { 56 | url: 'https://scalr.api.appbase.io', 57 | appname: 'mirage_test', 58 | username: 'wvCmyBy3D', 59 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 60 | }; 61 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 62 | var query_data = query.setFormat(); 63 | var request_data = { 64 | "query": { 65 | "bool": { 66 | "must": [query_data] 67 | } 68 | } 69 | }; 70 | $.ajax({ 71 | type: 'POST', 72 | beforeSend: function(request) { 73 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 74 | }, 75 | url: url, 76 | contentType: 'application/json; charset=utf-8', 77 | dataType: 'json', 78 | data: JSON.stringify(request_data), 79 | xhrFields: { 80 | withCredentials: true 81 | }, 82 | success: function(res) { 83 | returnedJSON = res; 84 | status = 200; 85 | done(); 86 | }, 87 | error: function(xhr) { 88 | returnedJSON = xhr; 89 | status = xhr.status; 90 | done(); 91 | } 92 | }); 93 | }); 94 | 95 | it("Should have returned JSON and Should have atleast 1 record", function () { 96 | expect(returnedJSON).not.toEqual({}); 97 | expect(returnedJSON).not.toBeUndefined(); 98 | expect(status).toEqual(200); 99 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 100 | }); 101 | 102 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/lt.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { LtQuery } from './lt.query'; 2 | 3 | describe('Lt query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: LtQuery; 8 | var expectedFormat = { 9 | 'range': { 10 | 'age': { 11 | 'lt': 35 12 | } 13 | } 14 | }; 15 | 16 | // instantiate query component and set the input fields 17 | beforeEach(function() { 18 | query = new LtQuery(); 19 | query.queryName = 'lt'; 20 | query.fieldName = 'age'; 21 | query.inputs = { 22 | lt: { 23 | value: 35 24 | } 25 | }; 26 | }); 27 | 28 | function isValidJson(str: string) { 29 | try { 30 | JSON.parse(str); 31 | } catch (e) { 32 | return false; 33 | } 34 | return true; 35 | } 36 | 37 | // Test to check if queryformat is valid json 38 | it('is valid json', () => { 39 | var format = query.setFormat(); 40 | var validJson = isValidJson(JSON.stringify(format)); 41 | expect(validJson).toEqual(true); 42 | }); 43 | 44 | // Test to check if result of setformat is equal to expected query format. 45 | it('Is setformat matches with expected query format', () => { 46 | var format = query.setFormat(); 47 | expect(format).toEqual(expectedFormat); 48 | }); 49 | 50 | }) 51 | 52 | declare var $; 53 | describe("xhr call (lt)", function () { 54 | var returnedJSON = {}; 55 | var status = 0; 56 | 57 | beforeEach(function (done) { 58 | var query = new LtQuery(); 59 | query.queryName = 'lt'; 60 | query.fieldName = 'age'; 61 | query.inputs = { 62 | lt: { 63 | value: 35 64 | } 65 | }; 66 | var config = { 67 | url: 'https://scalr.api.appbase.io', 68 | appname: 'mirage_test', 69 | username: 'wvCmyBy3D', 70 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 71 | }; 72 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 73 | var query_data = query.setFormat(); 74 | var request_data = { 75 | "query": { 76 | "bool": { 77 | "must": [query_data] 78 | } 79 | } 80 | }; 81 | $.ajax({ 82 | type: 'POST', 83 | beforeSend: function(request) { 84 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 85 | }, 86 | url: url, 87 | contentType: 'application/json; charset=utf-8', 88 | dataType: 'json', 89 | data: JSON.stringify(request_data), 90 | xhrFields: { 91 | withCredentials: true 92 | }, 93 | success: function(res) { 94 | returnedJSON = res; 95 | status = 200; 96 | done(); 97 | }, 98 | error: function(xhr) { 99 | returnedJSON = xhr; 100 | status = xhr.status; 101 | done(); 102 | } 103 | }); 104 | }); 105 | 106 | it("Should have returned JSON", function () { 107 | expect(returnedJSON).not.toEqual({}); 108 | expect(returnedJSON).not.toBeUndefined(); 109 | expect(status).toEqual(200); 110 | }); 111 | 112 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/gt.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { GtQuery } from './gt.query'; 2 | 3 | describe('Gt query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: GtQuery; 8 | var expectedFormat = { 9 | 'range': { 10 | 'age': { 11 | 'gt': 25 12 | } 13 | } 14 | }; 15 | 16 | // instantiate query component and set the input fields 17 | beforeEach(function() { 18 | query = new GtQuery(); 19 | query.queryName = 'gt'; 20 | query.fieldName = 'age'; 21 | query.inputs = { 22 | gt: { 23 | value: 25 24 | } 25 | }; 26 | }); 27 | 28 | function isValidJson(str: string) { 29 | try { 30 | JSON.parse(str); 31 | } catch (e) { 32 | return false; 33 | } 34 | return true; 35 | } 36 | 37 | // Test to check if queryformat is valid json 38 | it('is valid json', () => { 39 | var format = query.setFormat(); 40 | var validJson = isValidJson(JSON.stringify(format)); 41 | expect(validJson).toEqual(true); 42 | }); 43 | 44 | // Test to check if result of setformat is equal to expected query format. 45 | it('Is setformat matches with expected query format', () => { 46 | var format = query.setFormat(); 47 | expect(format).toEqual(expectedFormat); 48 | }); 49 | 50 | }) 51 | 52 | declare var $; 53 | describe("xhr call (Gt)", function () { 54 | var returnedJSON: any = {}; 55 | var status = 0; 56 | 57 | beforeEach(function (done) { 58 | var query = new GtQuery(); 59 | query.queryName = 'gt'; 60 | query.fieldName = 'age'; 61 | query.inputs = { 62 | gt: { 63 | value: 25 64 | } 65 | }; 66 | var config = { 67 | url: 'https://scalr.api.appbase.io', 68 | appname: 'mirage_test', 69 | username: 'wvCmyBy3D', 70 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 71 | }; 72 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 73 | var query_data = query.setFormat(); 74 | var request_data = { 75 | "query": { 76 | "bool": { 77 | "must": [query_data] 78 | } 79 | } 80 | }; 81 | $.ajax({ 82 | type: 'POST', 83 | beforeSend: function(request) { 84 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 85 | }, 86 | url: url, 87 | contentType: 'application/json; charset=utf-8', 88 | dataType: 'json', 89 | data: JSON.stringify(request_data), 90 | xhrFields: { 91 | withCredentials: true 92 | }, 93 | success: function(res) { 94 | returnedJSON = res; 95 | status = 200; 96 | done(); 97 | }, 98 | error: function(xhr) { 99 | returnedJSON = xhr; 100 | status = xhr.status; 101 | done(); 102 | } 103 | }); 104 | }); 105 | 106 | it("Should have returned JSON", function () { 107 | expect(returnedJSON).not.toEqual({}); 108 | expect(returnedJSON).not.toBeUndefined(); 109 | expect(status).toEqual(200); 110 | }); 111 | 112 | }); -------------------------------------------------------------------------------- /assets/styles/header.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | .init-ES, 3 | footer { 4 | position: absolute; 5 | top: 0px; 6 | left: 0; 7 | width: 100%; 8 | z-index: 6; 9 | background: $grey-bg; 10 | padding: 5px; 11 | padding-left: 165px; 12 | padding-right: 130px; 13 | border-bottom: 1px solid darken($grey-bg, 10%); 14 | .action-btns { 15 | position: absolute; 16 | left: 5px; 17 | display: inline-block; 18 | .share-btn { 19 | padding: 9px 12px; 20 | } 21 | .link { 22 | padding-left: 10px; 23 | } 24 | } 25 | .submit-btn { 26 | position: absolute; 27 | right: 5px; 28 | width: 125px; 29 | } 30 | } 31 | .init-ES { 32 | padding: 15px 130px 15px 165px; 33 | border-bottom: 1px solid #dedede; 34 | margin: 0; 35 | } 36 | .share_content { 37 | .share_content { 38 | display: none; 39 | } 40 | } 41 | .url-container { 42 | position: relative; 43 | .hide-url { 44 | position: absolute; 45 | width: auto; 46 | right: 0; 47 | top: 0; 48 | z-index: 2; 49 | height: 100%; 50 | display: block; 51 | text-align: right; 52 | border-radius: 4px; 53 | background: $grey-bg; 54 | border-bottom: 2px dashed #ccc; 55 | .btn { 56 | margin-top: -1px; 57 | padding: 9px 12px; 58 | } 59 | &.expand { 60 | width: 100%; 61 | } 62 | } 63 | } 64 | .header { 65 | position: absolute; 66 | top: 0; 67 | left: 0; 68 | width: 100%; 69 | z-index: 9; 70 | background: $grey-bg; 71 | border-bottom: 0; 72 | padding: 0; 73 | max-height: 100px; 74 | margin: 0 auto; 75 | position: absolute; 76 | height: auto; 77 | background: #fff; 78 | border-bottom: 2px solid #ccc; 79 | height: 88px; 80 | .img-container { 81 | margin-top: 10px; 82 | margin-bottom: 10px; 83 | img { 84 | max-width: 200px; 85 | margin: 15px auto; 86 | } 87 | } 88 | .tag-line { 89 | line-height: 22px; 90 | font-size: 20px; 91 | margin-bottom: 10px; 92 | font-weight: lighter; 93 | } 94 | .subscribe { 95 | position: absolute; 96 | right: 15px; 97 | top: 15px; 98 | width: 50px; 99 | height: 50px; 100 | line-height: 50px; 101 | font-size: 24px; 102 | color: $primary-font-color; 103 | img { 104 | border-radius: 50%; 105 | } 106 | } 107 | @media screen and (max-width: 768px) { 108 | .tag-line { 109 | line-height: 16px; 110 | font-size: 14px; 111 | } 112 | } 113 | @media screen and (max-width: 500px) { 114 | .header-container { 115 | height: 30px; 116 | .tag-line { 117 | display: none; 118 | } 119 | } 120 | } 121 | } 122 | #subscribeModal { 123 | .modal-content { 124 | padding-bottom: 45px; 125 | .single-option { 126 | text-align: left; 127 | margin-bottom: 5px; 128 | } 129 | } 130 | } 131 | footer { 132 | position: absolute; 133 | bottom: 0; 134 | top: auto; 135 | padding-right: 5px; 136 | border-top: 1px solid #ddd; 137 | border-bottom: 0; 138 | z-index: 99999999; 139 | height: 36px; 140 | padding-left: 5px; 141 | .powered_by { 142 | position: absolute; 143 | right: 5px; 144 | } 145 | .github-star { 146 | position: absolute; 147 | left: 5px; 148 | } 149 | @media screen and (max-width: 768px) { 150 | height: 56px; 151 | .powered_by, .github-star, .footer-center { 152 | font-size: 11px; 153 | line-height: 23px; 154 | } 155 | .footer-center 156 | { 157 | position: relative; 158 | display: block; 159 | width: 100%; 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/term.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { TermQuery } from './term.query'; 2 | 3 | describe('Term query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: TermQuery; 8 | var expectedFormat = { 9 | 'term': { 10 | 'name': 'test_foobar' 11 | } 12 | }; 13 | 14 | // instantiate query component and set the input fields 15 | beforeEach(function() { 16 | query = new TermQuery(); 17 | query.queryName = 'term'; 18 | query.fieldName = 'name'; 19 | query.inputs = { 20 | input: { 21 | value: 'test_foobar' 22 | } 23 | }; 24 | }); 25 | 26 | function isValidJson(str: string) { 27 | try { 28 | JSON.parse(str); 29 | } catch (e) { 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | // Test to check if queryformat is valid json 36 | it('is valid json', () => { 37 | var format = query.setFormat(); 38 | var validJson = isValidJson(JSON.stringify(format)); 39 | expect(validJson).toEqual(true); 40 | }); 41 | 42 | // Test to check if result of setformat is equal to expected query format. 43 | it('Is setformat matches with expected query format', () => { 44 | var format = query.setFormat(); 45 | expect(format).toEqual(expectedFormat); 46 | }); 47 | 48 | }) 49 | 50 | declare var $; 51 | describe("xhr test (Term)", function () { 52 | var returnedJSON: any = {}; 53 | var status = 0; 54 | 55 | beforeEach(function (done) { 56 | var query = new TermQuery(); 57 | query.queryName = 'term'; 58 | query.fieldName = 'name'; 59 | query.inputs = { 60 | input: { 61 | value: 'test_foobar' 62 | } 63 | }; 64 | var config = { 65 | url: 'https://scalr.api.appbase.io', 66 | appname: 'mirage_test', 67 | username: 'wvCmyBy3D', 68 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 69 | }; 70 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 71 | var query_data = query.setFormat(); 72 | var request_data = { 73 | "query": { 74 | "bool": { 75 | "must": [query_data] 76 | } 77 | } 78 | }; 79 | $.ajax({ 80 | type: 'POST', 81 | beforeSend: function(request) { 82 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 83 | }, 84 | url: url, 85 | contentType: 'application/json; charset=utf-8', 86 | dataType: 'json', 87 | data: JSON.stringify(request_data), 88 | xhrFields: { 89 | withCredentials: true 90 | }, 91 | success: function(res) { 92 | returnedJSON = res; 93 | status = 200; 94 | done(); 95 | }, 96 | error: function(xhr) { 97 | returnedJSON = xhr; 98 | status = xhr.status; 99 | done(); 100 | } 101 | }); 102 | }); 103 | 104 | it("Should have returned JSON and Should have atleast 1 record", function () { 105 | expect(returnedJSON).not.toEqual({}); 106 | expect(returnedJSON).not.toBeUndefined(); 107 | expect(status).toEqual(200); 108 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 109 | }); 110 | 111 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/fuzzy.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { FuzzyQuery } from './fuzzy.query'; 2 | 3 | describe('Prefix query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: FuzzyQuery; 8 | var expectedFormat = { 9 | 'fuzzy': { 10 | 'name': 'test_foobar' 11 | } 12 | }; 13 | 14 | // instantiate query component and set the input fields 15 | beforeEach(function() { 16 | query = new FuzzyQuery(); 17 | query.queryName = 'fuzzy'; 18 | query.fieldName = 'name'; 19 | query.inputs = { 20 | input: { 21 | value: 'test_foobar' 22 | } 23 | }; 24 | }); 25 | 26 | function isValidJson(str: string) { 27 | try { 28 | JSON.parse(str); 29 | } catch (e) { 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | // Test to check if queryformat is valid json 36 | it('is valid json', () => { 37 | var format = query.setFormat(); 38 | var validJson = isValidJson(JSON.stringify(format)); 39 | expect(validJson).toEqual(true); 40 | }); 41 | 42 | // Test to check if result of setformat is equal to expected query format. 43 | it('Is setformat matches with expected query format', () => { 44 | var format = query.setFormat(); 45 | expect(format).toEqual(expectedFormat); 46 | }); 47 | 48 | }) 49 | 50 | declare var $; 51 | describe("xhr call (fuzzy)", function () { 52 | var returnedJSON: any = {}; 53 | var status = 0; 54 | 55 | beforeEach(function (done) { 56 | var query = new FuzzyQuery(); 57 | query.queryName = 'fuzzy'; 58 | query.fieldName = 'name'; 59 | query.inputs = { 60 | input: { 61 | value: 'test_foobar' 62 | } 63 | }; 64 | var config = { 65 | url: 'https://scalr.api.appbase.io', 66 | appname: 'mirage_test', 67 | username: 'wvCmyBy3D', 68 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 69 | }; 70 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 71 | var query_data = query.setFormat(); 72 | var request_data = { 73 | "query": { 74 | "bool": { 75 | "must": [query_data] 76 | } 77 | } 78 | }; 79 | $.ajax({ 80 | type: 'POST', 81 | beforeSend: function(request) { 82 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 83 | }, 84 | url: url, 85 | contentType: 'application/json; charset=utf-8', 86 | dataType: 'json', 87 | data: JSON.stringify(request_data), 88 | xhrFields: { 89 | withCredentials: true 90 | }, 91 | success: function(res) { 92 | returnedJSON = res; 93 | status = 200; 94 | done(); 95 | }, 96 | error: function(xhr) { 97 | returnedJSON = xhr; 98 | status = xhr.status; 99 | done(); 100 | } 101 | }); 102 | }); 103 | 104 | it("Should have returned JSON and Should have atleast 1 record", function () { 105 | expect(returnedJSON).not.toEqual({}); 106 | expect(returnedJSON).not.toBeUndefined(); 107 | expect(status).toEqual(200); 108 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 109 | }); 110 | 111 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/prefix.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { PrefixQuery } from './prefix.query'; 2 | 3 | describe('Prefix query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: PrefixQuery; 8 | var expectedFormat = { 9 | 'prefix': { 10 | 'name': 'test_foobar' 11 | } 12 | }; 13 | 14 | // instantiate query component and set the input fields 15 | beforeEach(function() { 16 | query = new PrefixQuery(); 17 | query.queryName = 'prefix'; 18 | query.fieldName = 'name'; 19 | query.inputs = { 20 | input: { 21 | value: 'test_foobar' 22 | } 23 | }; 24 | }); 25 | 26 | function isValidJson(str: string) { 27 | try { 28 | JSON.parse(str); 29 | } catch (e) { 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | // Test to check if queryformat is valid json 36 | it('is valid json', () => { 37 | var format = query.setFormat(); 38 | var validJson = isValidJson(JSON.stringify(format)); 39 | expect(validJson).toEqual(true); 40 | }); 41 | 42 | // Test to check if result of setformat is equal to expected query format. 43 | it('Is setformat matches with expected query format', () => { 44 | var format = query.setFormat(); 45 | expect(format).toEqual(expectedFormat); 46 | }); 47 | 48 | }) 49 | 50 | declare var $; 51 | describe("xhr call (prefix)", function () { 52 | var returnedJSON: any = {}; 53 | var status = 0; 54 | 55 | beforeEach(function (done) { 56 | var query = new PrefixQuery(); 57 | query.queryName = 'prefix'; 58 | query.fieldName = 'name'; 59 | query.inputs = { 60 | input: { 61 | value: 'test_foobar' 62 | } 63 | }; 64 | var config = { 65 | url: 'https://scalr.api.appbase.io', 66 | appname: 'mirage_test', 67 | username: 'wvCmyBy3D', 68 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 69 | }; 70 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 71 | var query_data = query.setFormat(); 72 | var request_data = { 73 | "query": { 74 | "bool": { 75 | "must": [query_data] 76 | } 77 | } 78 | }; 79 | $.ajax({ 80 | type: 'POST', 81 | beforeSend: function(request) { 82 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 83 | }, 84 | url: url, 85 | contentType: 'application/json; charset=utf-8', 86 | dataType: 'json', 87 | data: JSON.stringify(request_data), 88 | xhrFields: { 89 | withCredentials: true 90 | }, 91 | success: function(res) { 92 | returnedJSON = res; 93 | status = 200; 94 | done(); 95 | }, 96 | error: function(xhr) { 97 | returnedJSON = xhr; 98 | status = xhr.status; 99 | done(); 100 | } 101 | }); 102 | }); 103 | 104 | it("Should have returned JSON and Should have atleast 1 record", function () { 105 | expect(returnedJSON).not.toEqual({}); 106 | expect(returnedJSON).not.toBeUndefined(); 107 | expect(status).toEqual(200); 108 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 109 | }); 110 | 111 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/range.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { RangeQuery } from './range.query'; 2 | 3 | describe('Range query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: RangeQuery; 8 | var expectedFormat = { 9 | 'range': { 10 | 'age': { 11 | 'gte': 25, 12 | 'lte': 35 13 | } 14 | } 15 | }; 16 | 17 | // instantiate query component and set the input fields 18 | beforeEach(function() { 19 | query = new RangeQuery(); 20 | query.queryName = 'range'; 21 | query.fieldName = 'age'; 22 | query.inputs = { 23 | gte: { 24 | value: 25 25 | }, lte: { 26 | value: 35 27 | } 28 | }; 29 | }); 30 | 31 | function isValidJson(str: string) { 32 | try { 33 | JSON.parse(str); 34 | } catch (e) { 35 | return false; 36 | } 37 | return true; 38 | } 39 | 40 | // Test to check if queryformat is valid json 41 | it('is valid json', () => { 42 | var format = query.setFormat(); 43 | var validJson = isValidJson(JSON.stringify(format)); 44 | expect(validJson).toEqual(true); 45 | }); 46 | 47 | // Test to check if result of setformat is equal to expected query format. 48 | it('Is setformat matches with expected query format', () => { 49 | var format = query.setFormat(); 50 | expect(format).toEqual(expectedFormat); 51 | }); 52 | 53 | }) 54 | 55 | declare var $; 56 | describe("xhr call (range)", function () { 57 | var returnedJSON = {}; 58 | var status = 0; 59 | 60 | beforeEach(function (done) { 61 | var query = new RangeQuery(); 62 | query.queryName = 'range'; 63 | query.fieldName = 'age'; 64 | query.inputs = { 65 | gte: { 66 | value: 25 67 | }, lte: { 68 | value: 35 69 | } 70 | }; 71 | var config = { 72 | url: 'https://scalr.api.appbase.io', 73 | appname: 'mirage_test', 74 | username: 'wvCmyBy3D', 75 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 76 | }; 77 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 78 | var query_data = query.setFormat(); 79 | var request_data = { 80 | "query": { 81 | "bool": { 82 | "must": [query_data] 83 | } 84 | } 85 | }; 86 | $.ajax({ 87 | type: 'POST', 88 | beforeSend: function(request) { 89 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 90 | }, 91 | url: url, 92 | contentType: 'application/json; charset=utf-8', 93 | dataType: 'json', 94 | data: JSON.stringify(request_data), 95 | xhrFields: { 96 | withCredentials: true 97 | }, 98 | success: function(res) { 99 | returnedJSON = res; 100 | status = 200; 101 | done(); 102 | }, 103 | error: function(xhr) { 104 | returnedJSON = xhr; 105 | status = xhr.status; 106 | done(); 107 | } 108 | }); 109 | }); 110 | 111 | it("Should have returned JSON", function () { 112 | expect(returnedJSON).not.toEqual({}); 113 | expect(returnedJSON).not.toBeUndefined(); 114 | expect(status).toEqual(200); 115 | }); 116 | 117 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/regexp.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { RegexpQuery } from './regexp.query'; 2 | 3 | describe('Prefix query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: RegexpQuery; 8 | var expectedFormat = { 9 | 'regexp': { 10 | 'name': 'test_foobar' 11 | } 12 | }; 13 | 14 | // instantiate query component and set the input fields 15 | beforeEach(function() { 16 | query = new RegexpQuery(); 17 | query.queryName = 'regexp'; 18 | query.fieldName = 'name'; 19 | query.inputs = { 20 | input: { 21 | value: 'test_foobar' 22 | } 23 | }; 24 | }); 25 | 26 | function isValidJson(str: string) { 27 | try { 28 | JSON.parse(str); 29 | } catch (e) { 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | // Test to check if queryformat is valid json 36 | it('is valid json', () => { 37 | var format = query.setFormat(); 38 | var validJson = isValidJson(JSON.stringify(format)); 39 | expect(validJson).toEqual(true); 40 | }); 41 | 42 | // Test to check if result of setformat is equal to expected query format. 43 | it('Is setformat matches with expected query format', () => { 44 | var format = query.setFormat(); 45 | expect(format).toEqual(expectedFormat); 46 | }); 47 | 48 | }) 49 | 50 | declare var $; 51 | describe("xhr call (regexp)", function () { 52 | var returnedJSON: any = {}; 53 | var status = 0; 54 | 55 | beforeEach(function (done) { 56 | var query = new RegexpQuery(); 57 | query.queryName = 'regexp'; 58 | query.fieldName = 'name'; 59 | query.inputs = { 60 | input: { 61 | value: 'test_foobar' 62 | } 63 | }; 64 | var config = { 65 | url: 'https://scalr.api.appbase.io', 66 | appname: 'mirage_test', 67 | username: 'wvCmyBy3D', 68 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 69 | }; 70 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 71 | var query_data = query.setFormat(); 72 | var request_data = { 73 | "query": { 74 | "bool": { 75 | "must": [query_data] 76 | } 77 | } 78 | }; 79 | $.ajax({ 80 | type: 'POST', 81 | beforeSend: function(request) { 82 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 83 | }, 84 | url: url, 85 | contentType: 'application/json; charset=utf-8', 86 | dataType: 'json', 87 | data: JSON.stringify(request_data), 88 | xhrFields: { 89 | withCredentials: true 90 | }, 91 | success: function(res) { 92 | returnedJSON = res; 93 | status = 200; 94 | done(); 95 | }, 96 | error: function(xhr) { 97 | returnedJSON = xhr; 98 | status = xhr.status; 99 | done(); 100 | } 101 | }); 102 | }); 103 | 104 | it("Should have returned JSON and Should have atleast 1 record", function () { 105 | expect(returnedJSON).not.toEqual({}); 106 | expect(returnedJSON).not.toBeUndefined(); 107 | expect(status).toEqual(200); 108 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 109 | }); 110 | 111 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/terms.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { TermsQuery } from './terms.query'; 2 | 3 | describe('terms query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: TermsQuery; 8 | var expectedFormat = { 9 | 'terms': { 10 | 'name': ['test_foobar'] 11 | } 12 | }; 13 | 14 | // instantiate query component and set the input fields 15 | beforeEach(function() { 16 | query = new TermsQuery(); 17 | query.queryName = 'terms'; 18 | query.fieldName = 'name'; 19 | query.inputs = { 20 | input: { 21 | value: 'test_foobar' 22 | } 23 | }; 24 | }); 25 | 26 | function isValidJson(str: string) { 27 | try { 28 | JSON.parse(str); 29 | } catch (e) { 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | // Test to check if queryformat is valid json 36 | it('is valid json', () => { 37 | var format = query.setFormat(); 38 | var validJson = isValidJson(JSON.stringify(format)); 39 | expect(validJson).toEqual(true); 40 | }); 41 | 42 | // Test to check if result of setformat is equal to expected query format. 43 | it('Is setformat matches with expected query format', () => { 44 | var format = query.setFormat(); 45 | expect(format).toEqual(expectedFormat); 46 | }); 47 | 48 | }) 49 | 50 | 51 | declare var $; 52 | describe("xhr test (Terms)", function () { 53 | var returnedJSON: any = {}; 54 | var status = 0; 55 | 56 | beforeEach(function (done) { 57 | var query = new TermsQuery(); 58 | query.queryName = 'terms'; 59 | query.fieldName = 'name'; 60 | query.inputs = { 61 | input: { 62 | value: 'test_foobar' 63 | } 64 | }; 65 | var config = { 66 | url: 'https://scalr.api.appbase.io', 67 | appname: 'mirage_test', 68 | username: 'wvCmyBy3D', 69 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 70 | }; 71 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 72 | var query_data = query.setFormat(); 73 | var request_data = { 74 | "query": { 75 | "bool": { 76 | "must": [query_data] 77 | } 78 | } 79 | }; 80 | $.ajax({ 81 | type: 'POST', 82 | beforeSend: function(request) { 83 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 84 | }, 85 | url: url, 86 | contentType: 'application/json; charset=utf-8', 87 | dataType: 'json', 88 | data: JSON.stringify(request_data), 89 | xhrFields: { 90 | withCredentials: true 91 | }, 92 | success: function(res) { 93 | returnedJSON = res; 94 | status = 200; 95 | done(); 96 | }, 97 | error: function(xhr) { 98 | returnedJSON = xhr; 99 | status = xhr.status; 100 | done(); 101 | } 102 | }); 103 | }); 104 | 105 | it("Should have returned JSON and Should have atleast 1 record", function () { 106 | expect(returnedJSON).not.toEqual({}); 107 | expect(returnedJSON).not.toBeUndefined(); 108 | expect(status).toEqual(200); 109 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 110 | }); 111 | 112 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/wildcard.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { WildcardQuery } from './wildcard.query'; 2 | 3 | describe('Prefix query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: WildcardQuery; 8 | var expectedFormat = { 9 | 'wildcard': { 10 | 'name': 'test_foobar' 11 | } 12 | }; 13 | 14 | // instantiate query component and set the input fields 15 | beforeEach(function() { 16 | query = new WildcardQuery(); 17 | query.queryName = 'wildcard'; 18 | query.fieldName = 'name'; 19 | query.inputs = { 20 | input: { 21 | value: 'test_foobar' 22 | } 23 | }; 24 | }); 25 | 26 | function isValidJson(str: string) { 27 | try { 28 | JSON.parse(str); 29 | } catch (e) { 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | // Test to check if queryformat is valid json 36 | it('is valid json', () => { 37 | var format = query.setFormat(); 38 | var validJson = isValidJson(JSON.stringify(format)); 39 | expect(validJson).toEqual(true); 40 | }); 41 | 42 | // Test to check if result of setformat is equal to expected query format. 43 | it('Is setformat matches with expected query format', () => { 44 | var format = query.setFormat(); 45 | expect(format).toEqual(expectedFormat); 46 | }); 47 | 48 | }) 49 | 50 | declare var $; 51 | describe("xhr call (wildcard)", function () { 52 | var returnedJSON: any = {}; 53 | var status = 0; 54 | 55 | beforeEach(function (done) { 56 | var query = new WildcardQuery(); 57 | query.queryName = 'wildcard'; 58 | query.fieldName = 'name'; 59 | query.inputs = { 60 | input: { 61 | value: 'test_foobar' 62 | } 63 | }; 64 | var config = { 65 | url: 'https://scalr.api.appbase.io', 66 | appname: 'mirage_test', 67 | username: 'wvCmyBy3D', 68 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 69 | }; 70 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 71 | var query_data = query.setFormat(); 72 | var request_data = { 73 | "query": { 74 | "bool": { 75 | "must": [query_data] 76 | } 77 | } 78 | }; 79 | $.ajax({ 80 | type: 'POST', 81 | beforeSend: function(request) { 82 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 83 | }, 84 | url: url, 85 | contentType: 'application/json; charset=utf-8', 86 | dataType: 'json', 87 | data: JSON.stringify(request_data), 88 | xhrFields: { 89 | withCredentials: true 90 | }, 91 | success: function(res) { 92 | returnedJSON = res; 93 | status = 200; 94 | done(); 95 | }, 96 | error: function(xhr) { 97 | returnedJSON = xhr; 98 | status = xhr.status; 99 | done(); 100 | } 101 | }); 102 | }); 103 | 104 | it("Should have returned JSON and Should have atleast 1 record", function () { 105 | expect(returnedJSON).not.toEqual({}); 106 | expect(returnedJSON).not.toBeUndefined(); 107 | expect(status).toEqual(200); 108 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 109 | }); 110 | 111 | }); -------------------------------------------------------------------------------- /assets/css/features.css: -------------------------------------------------------------------------------- 1 | .feature-query-container { 2 | position: relative; } 3 | .feature-query-container .features-section { 4 | position: absolute; 5 | width: 250px; 6 | height: 100%; 7 | left: 0; 8 | top: 0; 9 | background: #f7f7f7; 10 | border-right: 1px solid #dedede; 11 | padding: 15px 0; 12 | z-index: 2; 13 | transition: all 0.2s; } 14 | .feature-query-container .features-section .feature-section-container { 15 | overflow: auto; 16 | display: block; } 17 | .feature-query-container .features-section .feature-section-container .feature-btns { 18 | padding: 0 15px; } 19 | .feature-query-container .features-section .feature-section-container .theme-list { 20 | list-style: none; 21 | padding: 0; 22 | margin-top: 0; } 23 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item { 24 | display: block; 25 | border-bottom: 1px solid #dedede; 26 | padding: 10px 15px 10px 15px; 27 | cursor: pointer; } 28 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item .query-name { 29 | padding: 0; 30 | padding-bottom: 10px; } 31 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item .query-time { 32 | font-size: 10px; } 33 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item:hover { 34 | background: #dedede; } 35 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item:hover .delete-query { 36 | display: inline-block; } 37 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item.list-title { 38 | background: #FCC829; 39 | color: #fff; } 40 | .feature-query-container .features-section .feature-section-container .theme-list li.list-item .delete-query { 41 | position: absolute; 42 | right: 5px; 43 | top: 5px; 44 | display: none; } 45 | .feature-query-container .features-section .sidebar-toggle { 46 | position: absolute; 47 | right: -27px; 48 | top: 40%; 49 | z-index: 3; 50 | padding: 13px 8px; 51 | background: #FCC829; 52 | color: #fff; 53 | border: 0; 54 | border-top-left-radius: 0; 55 | border-bottom-left-radius: 0; 56 | border-left: 1px solid #efb503; } 57 | .feature-query-container .features-section .sidebar-toggle .sidebar-open { 58 | display: none; } 59 | .feature-query-container .features-section .btn-sort { 60 | background: #eee; 61 | color: #aaa; } 62 | .feature-query-container .features-section .btn-sort.active { 63 | color: #555; } 64 | .feature-query-container .query-main-container { 65 | padding: 0 0 0 250px; 66 | transition: all 0.2s; } 67 | .feature-query-container .query-main-container .query-build { 68 | padding-left: 35px; } 69 | .feature-query-container.off .features-section { 70 | width: 0; } 71 | .feature-query-container.off .features-section .feature-section-container { 72 | display: none; } 73 | .feature-query-container.off .features-section .sidebar-open { 74 | display: inline-block; } 75 | .feature-query-container.off .features-section .sidebar-close { 76 | display: none; } 77 | .feature-query-container.off .query-main-container { 78 | padding-left: 0; } 79 | .feature-query-container .select2-container { 80 | width: 100% !important; } 81 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/match_phrase.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { Match_phraseQuery } from './match_phrase.query'; 2 | 3 | describe('Match_phrase query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: Match_phraseQuery; 8 | var expectedFormat = { 9 | 'match_phrase': { 10 | 'name': 'test_foobar' 11 | } 12 | }; 13 | 14 | // instantiate query component and set the input fields 15 | beforeEach(function() { 16 | query = new Match_phraseQuery(); 17 | query.queryName = 'match_phrase'; 18 | query.fieldName = 'name'; 19 | query.inputs = { 20 | input: { 21 | value: 'test_foobar' 22 | } 23 | }; 24 | }); 25 | 26 | function isValidJson(str: string) { 27 | try { 28 | JSON.parse(str); 29 | } catch (e) { 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | // Test to check if queryformat is valid json 36 | it('is valid json', () => { 37 | var format = query.setFormat(); 38 | var validJson = isValidJson(JSON.stringify(format)); 39 | expect(validJson).toEqual(true); 40 | }); 41 | 42 | // Test to check if result of setformat is equal to expected query format. 43 | it('Is setformat matches with expected query format', () => { 44 | var format = query.setFormat(); 45 | expect(format).toEqual(expectedFormat); 46 | }); 47 | 48 | }) 49 | 50 | declare var $; 51 | describe("xhr test (Match Phrase)", function () { 52 | var returnedJSON: any = {}; 53 | var status = 0; 54 | 55 | beforeEach(function (done) { 56 | var query = new Match_phraseQuery(); 57 | query.queryName = 'match_phrase'; 58 | query.fieldName = 'name'; 59 | query.inputs = { 60 | input: { 61 | value: 'test_foobar' 62 | } 63 | }; 64 | var config = { 65 | url: 'https://scalr.api.appbase.io', 66 | appname: 'mirage_test', 67 | username: 'wvCmyBy3D', 68 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 69 | }; 70 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 71 | var query_data = query.setFormat(); 72 | var request_data = { 73 | "query": { 74 | "bool": { 75 | "must": [query_data] 76 | } 77 | } 78 | }; 79 | $.ajax({ 80 | type: 'POST', 81 | beforeSend: function(request) { 82 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 83 | }, 84 | url: url, 85 | contentType: 'application/json; charset=utf-8', 86 | dataType: 'json', 87 | data: JSON.stringify(request_data), 88 | xhrFields: { 89 | withCredentials: true 90 | }, 91 | success: function(res) { 92 | returnedJSON = res; 93 | status = 200; 94 | done(); 95 | }, 96 | error: function(xhr) { 97 | returnedJSON = xhr; 98 | status = xhr.status; 99 | done(); 100 | } 101 | }); 102 | }); 103 | 104 | it("Should have returned JSON and Should have atleast 1 record", function () { 105 | expect(returnedJSON).not.toEqual({}); 106 | expect(returnedJSON).not.toBeUndefined(); 107 | expect(status).toEqual(200); 108 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 109 | }); 110 | 111 | }); 112 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/common.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { CommonQuery } from './common.query'; 2 | 3 | describe('Common query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: CommonQuery; 8 | var expectedFormat = { 9 | 'common': { 10 | 'name': { 11 | 'query': 'test_foobar', 12 | 'cutoff_frequency': 0.001 13 | } 14 | } 15 | }; 16 | 17 | // instantiate query component and set the input fields 18 | beforeEach(function() { 19 | query = new CommonQuery(); 20 | query.queryName = 'common'; 21 | query.fieldName = 'name'; 22 | query.inputs = { 23 | query: { 24 | value: 'test_foobar' 25 | }, cutoff_frequency: { 26 | value: 0.001 27 | } 28 | }; 29 | }); 30 | 31 | function isValidJson(str: string) { 32 | try { 33 | JSON.parse(str); 34 | } catch (e) { 35 | return false; 36 | } 37 | return true; 38 | } 39 | 40 | // Test to check if queryformat is valid json 41 | it('is valid json', () => { 42 | var format = query.setFormat(); 43 | var validJson = isValidJson(JSON.stringify(format)); 44 | expect(validJson).toEqual(true); 45 | }); 46 | 47 | // Test to check if result of setformat is equal to expected query format. 48 | it('Is setformat matches with expected query format', () => { 49 | var format = query.setFormat(); 50 | expect(format).toEqual(expectedFormat); 51 | }); 52 | 53 | }) 54 | 55 | declare var $; 56 | describe("xhr call (common)", function () { 57 | var returnedJSON = {}; 58 | var status = 0; 59 | 60 | beforeEach(function (done) { 61 | var query = new CommonQuery(); 62 | query.queryName = 'common'; 63 | query.fieldName = 'name'; 64 | query.inputs = { 65 | query: { 66 | value: 'test_foobar' 67 | }, cutoff_frequency: { 68 | value: 0.001 69 | } 70 | }; 71 | var config = { 72 | url: 'https://scalr.api.appbase.io', 73 | appname: 'mirage_test', 74 | username: 'wvCmyBy3D', 75 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 76 | }; 77 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 78 | var query_data = query.setFormat(); 79 | var request_data = { 80 | "query": { 81 | "bool": { 82 | "must": [query_data] 83 | } 84 | } 85 | }; 86 | $.ajax({ 87 | type: 'POST', 88 | beforeSend: function(request) { 89 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 90 | }, 91 | url: url, 92 | contentType: 'application/json; charset=utf-8', 93 | dataType: 'json', 94 | data: JSON.stringify(request_data), 95 | xhrFields: { 96 | withCredentials: true 97 | }, 98 | success: function(res) { 99 | returnedJSON = res; 100 | status = 200; 101 | done(); 102 | }, 103 | error: function(xhr) { 104 | returnedJSON = xhr; 105 | status = xhr.status; 106 | done(); 107 | } 108 | }); 109 | }); 110 | 111 | it("Should have returned JSON", function () { 112 | expect(returnedJSON).not.toEqual({}); 113 | expect(returnedJSON).not.toBeUndefined(); 114 | expect(status).toEqual(200); 115 | }); 116 | 117 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/ids.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { IdsQuery } from './ids.query'; 2 | 3 | describe('ids query format', () => { 4 | 5 | // Set initial things 6 | // set expected query format 7 | var query: IdsQuery; 8 | var expectedFormat = { 9 | 'ids': { 10 | 'values': ['AVV7O_hNLozDpnHtfPQL'], 11 | 'type': ['test'] 12 | } 13 | }; 14 | 15 | // instantiate query component and set the input fields 16 | beforeEach(function() { 17 | query = new IdsQuery(); 18 | query.queryName = 'ids'; 19 | query.fieldName = ''; 20 | query.selectedTypes = ['test']; 21 | query.inputs = { 22 | input: { 23 | value: 'AVV7O_hNLozDpnHtfPQL' 24 | } 25 | }; 26 | }); 27 | 28 | function isValidJson(str: string) { 29 | try { 30 | JSON.parse(str); 31 | } catch (e) { 32 | return false; 33 | } 34 | return true; 35 | } 36 | 37 | // Test to check if queryformat is valid json 38 | it('is valid json', () => { 39 | var format = query.setFormat(); 40 | var validJson = isValidJson(JSON.stringify(format)); 41 | expect(validJson).toEqual(true); 42 | }); 43 | 44 | // Test to check if result of setformat is equal to expected query format. 45 | it('Is setformat matches with expected query format', () => { 46 | var format = query.setFormat(); 47 | expect(format).toEqual(expectedFormat); 48 | }); 49 | 50 | }) 51 | 52 | 53 | declare var $; 54 | describe("xhr test (ids)", function () { 55 | var returnedJSON: any = {}; 56 | var status = 0; 57 | 58 | beforeEach(function (done) { 59 | var query = new IdsQuery(); 60 | query = new IdsQuery(); 61 | query.queryName = 'ids'; 62 | query.fieldName = ''; 63 | query.selectedTypes = ['test']; 64 | query.inputs = { 65 | input: { 66 | value: 'AVV7O_hNLozDpnHtfPQL' 67 | } 68 | }; 69 | var config = { 70 | url: 'https://scalr.api.appbase.io', 71 | appname: 'mirage_test', 72 | username: 'wvCmyBy3D', 73 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 74 | }; 75 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 76 | var query_data = query.setFormat(); 77 | var request_data = { 78 | "query": { 79 | "bool": { 80 | "must": [query_data] 81 | } 82 | } 83 | }; 84 | $.ajax({ 85 | type: 'POST', 86 | beforeSend: function(request) { 87 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 88 | }, 89 | url: url, 90 | contentType: 'application/json; charset=utf-8', 91 | dataType: 'json', 92 | data: JSON.stringify(request_data), 93 | xhrFields: { 94 | withCredentials: true 95 | }, 96 | success: function(res) { 97 | returnedJSON = res; 98 | status = 200; 99 | done(); 100 | }, 101 | error: function(xhr) { 102 | returnedJSON = xhr; 103 | status = xhr.status; 104 | done(); 105 | } 106 | }); 107 | }); 108 | 109 | it("Should have returned JSON and Should have atleast 1 record", function () { 110 | expect(returnedJSON).not.toEqual({}); 111 | expect(returnedJSON).not.toBeUndefined(); 112 | expect(status).toEqual(200); 113 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 114 | }); 115 | 116 | }); -------------------------------------------------------------------------------- /assets/css/header.css: -------------------------------------------------------------------------------- 1 | .init-ES, 2 | footer { 3 | position: absolute; 4 | top: 0px; 5 | left: 0; 6 | width: 100%; 7 | z-index: 6; 8 | background: #f7f7f7; 9 | padding: 5px; 10 | padding-left: 165px; 11 | padding-right: 130px; 12 | border-bottom: 1px solid #dedede; } 13 | .init-ES .action-btns, 14 | footer .action-btns { 15 | position: absolute; 16 | left: 5px; 17 | display: inline-block; } 18 | .init-ES .action-btns .share-btn, 19 | footer .action-btns .share-btn { 20 | padding: 9px 12px; } 21 | .init-ES .action-btns .link, 22 | footer .action-btns .link { 23 | padding-left: 10px; } 24 | .init-ES .submit-btn, 25 | footer .submit-btn { 26 | position: absolute; 27 | right: 5px; 28 | width: 125px; } 29 | 30 | .init-ES { 31 | padding: 15px 130px 15px 165px; 32 | border-bottom: 1px solid #dedede; 33 | margin: 0; } 34 | 35 | .share_content .share_content { 36 | display: none; } 37 | 38 | .url-container { 39 | position: relative; } 40 | .url-container .hide-url { 41 | position: absolute; 42 | width: auto; 43 | right: 0; 44 | top: 0; 45 | z-index: 2; 46 | height: 100%; 47 | display: block; 48 | text-align: right; 49 | border-radius: 4px; 50 | background: #f7f7f7; 51 | border-bottom: 2px dashed #ccc; } 52 | .url-container .hide-url .btn { 53 | margin-top: -1px; 54 | padding: 9px 12px; } 55 | .url-container .hide-url.expand { 56 | width: 100%; } 57 | 58 | .header { 59 | position: absolute; 60 | top: 0; 61 | left: 0; 62 | width: 100%; 63 | z-index: 9; 64 | background: #f7f7f7; 65 | border-bottom: 0; 66 | padding: 0; 67 | max-height: 100px; 68 | margin: 0 auto; 69 | position: absolute; 70 | height: auto; 71 | background: #fff; 72 | border-bottom: 2px solid #ccc; 73 | height: 88px; } 74 | .header .img-container { 75 | margin-top: 10px; 76 | margin-bottom: 10px; } 77 | .header .img-container img { 78 | max-width: 200px; 79 | margin: 15px auto; } 80 | .header .tag-line { 81 | line-height: 22px; 82 | font-size: 20px; 83 | margin-bottom: 10px; 84 | font-weight: lighter; } 85 | .header .subscribe { 86 | position: absolute; 87 | right: 15px; 88 | top: 15px; 89 | width: 50px; 90 | height: 50px; 91 | line-height: 50px; 92 | font-size: 24px; 93 | color: #555; } 94 | .header .subscribe img { 95 | border-radius: 50%; } 96 | @media screen and (max-width: 768px) { 97 | .header .tag-line { 98 | line-height: 16px; 99 | font-size: 14px; } } 100 | @media screen and (max-width: 500px) { 101 | .header .header-container { 102 | height: 30px; } 103 | .header .header-container .tag-line { 104 | display: none; } } 105 | 106 | #subscribeModal .modal-content { 107 | padding-bottom: 45px; } 108 | #subscribeModal .modal-content .single-option { 109 | text-align: left; 110 | margin-bottom: 5px; } 111 | 112 | footer { 113 | position: absolute; 114 | bottom: 0; 115 | top: auto; 116 | padding-right: 5px; 117 | border-top: 1px solid #ddd; 118 | border-bottom: 0; 119 | z-index: 99999999; 120 | height: 36px; 121 | padding-left: 5px; } 122 | footer .powered_by { 123 | position: absolute; 124 | right: 5px; } 125 | footer .github-star { 126 | position: absolute; 127 | left: 5px; } 128 | @media screen and (max-width: 768px) { 129 | footer { 130 | height: 56px; } 131 | footer .powered_by, footer .github-star, footer .footer-center { 132 | font-size: 11px; 133 | line-height: 23px; } 134 | footer .footer-center { 135 | position: relative; 136 | display: block; 137 | width: 100%; } } 138 | -------------------------------------------------------------------------------- /app/queryBlocks/select2/select2.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnChanges, SimpleChange, Input, Output, AfterContentInit, EventEmitter } from "@angular/core"; 2 | import { GlobalShare } from "../../shared/globalshare.service"; 3 | import { DocService } from "../../shared/docService"; 4 | 5 | declare var $: any; 6 | 7 | @Component({ 8 | selector: 'select2', 9 | templateUrl: './app/queryBlocks/select2/select2.component.html', 10 | inputs: ["selectModal", "selectOptions", "setDocSample"], 11 | providers: [GlobalShare, DocService] 12 | }) 13 | 14 | export class select2Component implements OnChanges, AfterContentInit { 15 | @Input() querySelector; 16 | @Input() selector; 17 | @Input() showInfoFlag; 18 | @Input() passWithCallback: any; 19 | @Input() searchOff: boolean; 20 | @Input() informationList; 21 | @Output() callback = new EventEmitter(); 22 | @Output() setDocSample = new EventEmitter(); 23 | public select2Selector; 24 | constructor(private globalShare: GlobalShare, public docService: DocService) {} 25 | 26 | ngOnChanges() {} 27 | 28 | ngAfterContentInit() { 29 | setTimeout(function() { 30 | var select2Selector; 31 | if(this.querySelector && this.selector) { 32 | select2Selector = $(this.querySelector).find('.' + this.selector).find('select'); 33 | } 34 | else { 35 | select2Selector = $('.' + this.selector).find('select'); 36 | } 37 | if(typeof this.passWithCallback != 'undefined') { 38 | if(this.querySelector && this.selector) { 39 | select2Selector = $(this.querySelector).find('.' + this.selector+'-'+this.passWithCallback).find('select'); 40 | } else if (this.selector) { 41 | select2Selector = $('.' + this.selector+'-'+this.passWithCallback).find('select'); 42 | } 43 | } 44 | this.setSelect2(select2Selector, function(val) { 45 | var obj: any = { 46 | val: val, 47 | selector: select2Selector 48 | }; 49 | if(typeof this.passWithCallback != 'undefined') { 50 | obj.external = this.passWithCallback; 51 | } 52 | this.callback.emit(obj); 53 | }.bind(this)); 54 | }.bind(this), 300); 55 | } 56 | 57 | setSelect2(field_select, callback) { 58 | var select2Option: any = { 59 | placeholder: "Select from the option" 60 | }; 61 | if(this.searchOff) { 62 | select2Option.minimumResultsForSearch = -1; 63 | } 64 | field_select.select2(select2Option); 65 | field_select.on("change", function(e) { 66 | callback(field_select.val()); 67 | }.bind(this)); 68 | if (this.showInfoFlag) { 69 | field_select.on("select2:open", function() { 70 | this.setPopover.apply(this); 71 | $('.select2-search__field').keyup(function() { 72 | this.setPopover.apply(this); 73 | }.bind(this)); 74 | $('.select2-search__field').keydown(function() { 75 | this.setPopover.apply(this); 76 | }.bind(this)); 77 | }.bind(this)); 78 | } 79 | } 80 | 81 | setPopover() { 82 | setTimeout(function() { 83 | var selector = $('li.select2-results__option'); 84 | selector.each(function(i, item) { 85 | var val = $(item).html(); 86 | var info = this.getInformation(val); 87 | $(item).popover(info); 88 | $(item).on('shown.bs.popover', this.setLink.bind(this)) 89 | this.setLink(); 90 | }.bind(this)) 91 | }.bind(this), 300); 92 | } 93 | 94 | getInformation(query: any) { 95 | var query = this.informationList[query]; 96 | query['html'] = true; 97 | query['trigger'] = 'click hover'; 98 | query['placement'] = 'right'; 99 | query['delay'] = {'show': 50, 'hide': 50}; 100 | return query; 101 | } 102 | 103 | setLink() { 104 | var self = this; 105 | setTimeout(function() { 106 | $('.popover a').unbind('click').on('click',function(event) { 107 | event.preventDefault(); 108 | var link = event.target.href; 109 | self.setDocSample.emit(link); 110 | // self.docService.emitNavChangeEvent(link); 111 | // window.open(link, '_blank'); 112 | }); 113 | }.bind(this), 500); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/span_first.query.spec.ts: -------------------------------------------------------------------------------- 1 | import {SpanFirstQuery} from './span_first.query'; 2 | 3 | describe('SpanFirst query format', () => { 4 | // Set initial things 5 | // set expected query format 6 | var query: SpanFirstQuery; 7 | var expectedFormat = { 8 | 'span_first': { 9 | 'match': { 10 | 'span_term': { 11 | 'gender': { 12 | 'value': 'female' 13 | } 14 | } 15 | }, 16 | 'end': '3' 17 | } 18 | }; 19 | 20 | 21 | // instantiate query component and set the input fields 22 | beforeEach(function() { 23 | query = new SpanFirstQuery(); 24 | query.queryName = 'span_first'; 25 | query.fieldName = 'gender'; 26 | query.inputs = { 27 | input: { 28 | value: 'female' 29 | }, 30 | end: { 31 | value: '3' 32 | } 33 | }; 34 | }); 35 | 36 | function isValidJson(str: string) { 37 | try { 38 | JSON.parse(str); 39 | } catch (e) { 40 | return false; 41 | } 42 | return true; 43 | } 44 | 45 | // Test to check if queryformat is valid json 46 | it('is valid json', () => { 47 | var format = query.setFormat(); 48 | var validJson = isValidJson(JSON.stringify(format)); 49 | expect(validJson).toEqual(true); 50 | }); 51 | 52 | // Test to check if result of setformat is equal to expected query format. 53 | it('Is setformat matches with expected query format', () => { 54 | var format = query.setFormat(); 55 | expect(format).toEqual(expectedFormat); 56 | }); 57 | 58 | }) 59 | 60 | declare var $; 61 | describe("xhr test (SpanFirst)", function () { 62 | var returnedJSON: any = {}; 63 | var status = 0; 64 | 65 | beforeEach(function (done) { 66 | var query = new SpanFirstQuery(); 67 | query.queryName = 'span_first'; 68 | query.fieldName = 'gender'; 69 | query.inputs = { 70 | input: { 71 | value: 'female' 72 | }, 73 | end: { 74 | value: '3' 75 | } 76 | }; 77 | var config = { 78 | url: 'https://scalr.api.appbase.io', 79 | appname: 'mirage_test', 80 | username: 'wvCmyBy3D', 81 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 82 | }; 83 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 84 | var query_data = query.setFormat(); 85 | var request_data = { 86 | "query": { 87 | "bool": { 88 | "must": [query_data] 89 | } 90 | } 91 | }; 92 | $.ajax({ 93 | type: 'POST', 94 | beforeSend: function(request) { 95 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 96 | }, 97 | url: url, 98 | contentType: 'application/json; charset=utf-8', 99 | dataType: 'json', 100 | data: JSON.stringify(request_data), 101 | xhrFields: { 102 | withCredentials: true 103 | }, 104 | success: function(res) { 105 | returnedJSON = res; 106 | status = 200; 107 | done(); 108 | }, 109 | error: function(xhr) { 110 | returnedJSON = xhr; 111 | status = xhr.status; 112 | done(); 113 | } 114 | }); 115 | }); 116 | 117 | it("Should have returned JSON and Should have atleast 1 record", function () { 118 | expect(returnedJSON).not.toEqual({}); 119 | expect(returnedJSON).not.toBeUndefined(); 120 | expect(status).toEqual(200); 121 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 122 | }); 123 | 124 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/span_term.query.spec.ts: -------------------------------------------------------------------------------- 1 | import {SpanTermQuery} from './span_term.query'; 2 | 3 | describe('SpanTerm query format', () => { 4 | // Set initial things 5 | // set expected query format 6 | var query: SpanTermQuery; 7 | var expectedFormat = { 8 | 'span_term': { 9 | 'gender': { 10 | 'value': 'female' 11 | } 12 | } 13 | }; 14 | var expectedFormatWithOption = { 15 | 'span_term': { 16 | 'gender': { 17 | 'value': 'female', 18 | 'boost': '2' 19 | } 20 | } 21 | }; 22 | 23 | // instantiate query component and set the input fields 24 | beforeEach(function() { 25 | query = new SpanTermQuery(); 26 | query.queryName = 'span_term'; 27 | query.fieldName = 'gender'; 28 | query.inputs = { 29 | input: { 30 | value: 'female' 31 | } 32 | }; 33 | }); 34 | 35 | function isValidJson(str: string) { 36 | try { 37 | JSON.parse(str); 38 | } catch (e) { 39 | return false; 40 | } 41 | return true; 42 | } 43 | 44 | // Test to check if queryformat is valid json 45 | it('is valid json', () => { 46 | var format = query.setFormat(); 47 | var validJson = isValidJson(JSON.stringify(format)); 48 | expect(validJson).toEqual(true); 49 | }); 50 | 51 | // Test to check if result of setformat is equal to expected query format. 52 | it('Is setformat matches with expected query format', () => { 53 | var format = query.setFormat(); 54 | expect(format).toEqual(expectedFormat); 55 | }); 56 | 57 | 58 | // Test to check if result of setformat is equal to expected query format with option. 59 | it('Is setformat matches with expected query format when pass options with query', () => { 60 | query.optionRows = [{ 61 | name: 'boost', 62 | value: '2' 63 | }]; 64 | var format = query.setFormat(); 65 | expect(format).toEqual(expectedFormatWithOption); 66 | }); 67 | }) 68 | 69 | declare var $; 70 | describe("xhr test (SpanTerm)", function () { 71 | var returnedJSON: any = {}; 72 | var status = 0; 73 | 74 | beforeEach(function (done) { 75 | var query = new SpanTermQuery(); 76 | query.queryName = 'span_term'; 77 | query.fieldName = 'gender'; 78 | query.inputs = { 79 | input: { 80 | value: 'female' 81 | } 82 | }; 83 | var config = { 84 | url: 'https://scalr.api.appbase.io', 85 | appname: 'mirage_test', 86 | username: 'wvCmyBy3D', 87 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 88 | }; 89 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 90 | var query_data = query.setFormat(); 91 | var request_data = { 92 | "query": { 93 | "bool": { 94 | "must": [query_data] 95 | } 96 | } 97 | }; 98 | $.ajax({ 99 | type: 'POST', 100 | beforeSend: function(request) { 101 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 102 | }, 103 | url: url, 104 | contentType: 'application/json; charset=utf-8', 105 | dataType: 'json', 106 | data: JSON.stringify(request_data), 107 | xhrFields: { 108 | withCredentials: true 109 | }, 110 | success: function(res) { 111 | returnedJSON = res; 112 | status = 200; 113 | done(); 114 | }, 115 | error: function(xhr) { 116 | returnedJSON = xhr; 117 | status = xhr.status; 118 | done(); 119 | } 120 | }); 121 | }); 122 | 123 | it("Should have returned JSON and Should have atleast 1 record", function () { 124 | expect(returnedJSON).not.toEqual({}); 125 | expect(returnedJSON).not.toBeUndefined(); 126 | expect(status).toEqual(200); 127 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 128 | }); 129 | 130 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/multi-match.query.spec.ts: -------------------------------------------------------------------------------- 1 | import { MultiMatchQuery } from './multi-match.query'; 2 | 3 | describe('Match query format', () => { 4 | // Set initial things 5 | // set expected query format 6 | var query: MultiMatchQuery; 7 | var expectedFormat = { 8 | 'multi_match': { 9 | 'query': 'test_foobar', 10 | 'fields': ['name'] 11 | } 12 | }; 13 | var expectedFormatWithOption = { 14 | 'multi_match': { 15 | 'query': 'test_foobar', 16 | 'fields': ['name', 'gender', 'eyeColor'] 17 | } 18 | }; 19 | 20 | // instantiate query component and set the input fields 21 | beforeEach(function() { 22 | query = new MultiMatchQuery(); 23 | query.queryName = 'multi_match'; 24 | query.fieldName = 'name'; 25 | query.inputs = { 26 | input: { 27 | value: 'test_foobar' 28 | } 29 | }; 30 | }); 31 | 32 | function isValidJson(str: string) { 33 | try { 34 | JSON.parse(str); 35 | } catch (e) { 36 | return false; 37 | } 38 | return true; 39 | } 40 | 41 | // Test to check if queryformat is valid json 42 | it('is valid json', () => { 43 | var format = query.setFormat(); 44 | var validJson = isValidJson(JSON.stringify(format)); 45 | expect(validJson).toEqual(true); 46 | }); 47 | 48 | // Test to check if result of setformat is equal to expected query format. 49 | it('Is setformat matches with expected query format', () => { 50 | var format = query.setFormat(); 51 | expect(format).toEqual(expectedFormat); 52 | }); 53 | 54 | 55 | // Test to check if result of setformat is equal to expected query format with option. 56 | it('Is setformat matches with expected query format when pass options with query', () => { 57 | query.optionRows = [{ 58 | name: 'fields', 59 | value: 'gender,eyeColor' 60 | }]; 61 | var format = query.setFormat(); 62 | expect(format).toEqual(expectedFormatWithOption); 63 | }); 64 | }) 65 | 66 | declare var $; 67 | describe("xhr test (multi_match)", function () { 68 | var returnedJSON: any = {}; 69 | var status = 0; 70 | 71 | beforeEach(function (done) { 72 | var query = new MultiMatchQuery(); 73 | query.queryName = 'multi_match'; 74 | query.fieldName = 'name'; 75 | query.inputs = { 76 | input: { 77 | value: 'test_foobar' 78 | } 79 | }; 80 | var config = { 81 | url: 'https://scalr.api.appbase.io', 82 | appname: 'mirage_test', 83 | username: 'wvCmyBy3D', 84 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 85 | }; 86 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 87 | var query_data = query.setFormat(); 88 | var request_data = { 89 | "query": { 90 | "bool": { 91 | "must": [query_data] 92 | } 93 | } 94 | }; 95 | $.ajax({ 96 | type: 'POST', 97 | beforeSend: function(request) { 98 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 99 | }, 100 | url: url, 101 | contentType: 'application/json; charset=utf-8', 102 | dataType: 'json', 103 | data: JSON.stringify(request_data), 104 | xhrFields: { 105 | withCredentials: true 106 | }, 107 | success: function(res) { 108 | returnedJSON = res; 109 | status = 200; 110 | done(); 111 | }, 112 | error: function(xhr) { 113 | returnedJSON = xhr; 114 | status = xhr.status; 115 | done(); 116 | } 117 | }); 118 | }); 119 | 120 | it("Should have returned JSON and Should have atleast 1 record", function () { 121 | expect(returnedJSON).not.toEqual({}); 122 | expect(returnedJSON).not.toBeUndefined(); 123 | expect(status).toEqual(200); 124 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 125 | }); 126 | 127 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/query_string.query.spec.ts: -------------------------------------------------------------------------------- 1 | import {QueryStringQuery} from './query_string.query'; 2 | 3 | describe('Query string format', () => { 4 | // Set initial things 5 | // set expected query format 6 | var query: QueryStringQuery; 7 | var expectedFormat = { 8 | 'query_string': { 9 | 'query': 'test_foobar', 10 | 'fields': ['name'] 11 | } 12 | }; 13 | var expectedFormatWithOption = { 14 | 'query_string': { 15 | 'query': 'test_foobar', 16 | 'fields': ['name', 'gender', 'eyeColor'] 17 | } 18 | }; 19 | 20 | // instantiate query component and set the input fields 21 | beforeEach(function() { 22 | query = new QueryStringQuery(); 23 | query.queryName = 'query_string'; 24 | query.fieldName = 'name'; 25 | query.inputs = { 26 | input: { 27 | value: 'test_foobar' 28 | } 29 | }; 30 | }); 31 | 32 | function isValidJson(str: string) { 33 | try { 34 | JSON.parse(str); 35 | } catch (e) { 36 | return false; 37 | } 38 | return true; 39 | } 40 | 41 | // Test to check if queryformat is valid json 42 | it('is valid json', () => { 43 | var format = query.setFormat(); 44 | var validJson = isValidJson(JSON.stringify(format)); 45 | expect(validJson).toEqual(true); 46 | }); 47 | 48 | // Test to check if result of setformat is equal to expected query format. 49 | it('Is setformat matches with expected query format', () => { 50 | var format = query.setFormat(); 51 | expect(format).toEqual(expectedFormat); 52 | }); 53 | 54 | 55 | // Test to check if result of setformat is equal to expected query format with option. 56 | it('Is setformat matches with expected query format when pass options with query', () => { 57 | query.optionRows = [{ 58 | name: 'fields', 59 | value: 'gender,eyeColor' 60 | }]; 61 | var format = query.setFormat(); 62 | expect(format).toEqual(expectedFormatWithOption); 63 | }); 64 | }) 65 | 66 | declare var $; 67 | describe("xhr test (query_string)", function () { 68 | var returnedJSON: any = {}; 69 | var status = 0; 70 | 71 | beforeEach(function (done) { 72 | var query = new QueryStringQuery(); 73 | query.queryName = 'query_string'; 74 | query.fieldName = 'name'; 75 | query.inputs = { 76 | input: { 77 | value: 'test_foobar' 78 | } 79 | }; 80 | var config = { 81 | url: 'https://scalr.api.appbase.io', 82 | appname: 'mirage_test', 83 | username: 'wvCmyBy3D', 84 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 85 | }; 86 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 87 | var query_data = query.setFormat(); 88 | var request_data = { 89 | "query": { 90 | "bool": { 91 | "must": [query_data] 92 | } 93 | } 94 | }; 95 | $.ajax({ 96 | type: 'POST', 97 | beforeSend: function(request) { 98 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 99 | }, 100 | url: url, 101 | contentType: 'application/json; charset=utf-8', 102 | dataType: 'json', 103 | data: JSON.stringify(request_data), 104 | xhrFields: { 105 | withCredentials: true 106 | }, 107 | success: function(res) { 108 | returnedJSON = res; 109 | status = 200; 110 | done(); 111 | }, 112 | error: function(xhr) { 113 | returnedJSON = xhr; 114 | status = xhr.status; 115 | done(); 116 | } 117 | }); 118 | }); 119 | 120 | it("Should have returned JSON and Should have atleast 1 record", function () { 121 | expect(returnedJSON).not.toEqual({}); 122 | expect(returnedJSON).not.toBeUndefined(); 123 | expect(status).toEqual(200); 124 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 125 | }); 126 | 127 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/match.query.spec.ts: -------------------------------------------------------------------------------- 1 | import {MatchQuery} from './match.query'; 2 | 3 | describe('Match query format', () => { 4 | // Set initial things 5 | // set expected query format 6 | var query: MatchQuery; 7 | var expectedFormat = { 8 | 'match': { 9 | 'name': 'test_foobar' 10 | } 11 | }; 12 | var expectedFormatWithOption = { 13 | 'match': { 14 | 'name': { 15 | "query": "test_foobar", 16 | "operator" : "and", 17 | "zero_terms_query": "all" 18 | } 19 | } 20 | }; 21 | 22 | // instantiate query component and set the input fields 23 | beforeEach(function() { 24 | query = new MatchQuery(); 25 | query.queryName = 'match'; 26 | query.fieldName = 'name'; 27 | query.inputs = { 28 | input: { 29 | value: 'test_foobar' 30 | } 31 | }; 32 | }); 33 | 34 | function isValidJson(str: string) { 35 | try { 36 | JSON.parse(str); 37 | } catch (e) { 38 | return false; 39 | } 40 | return true; 41 | } 42 | 43 | // Test to check if queryformat is valid json 44 | it('is valid json', () => { 45 | var format = query.setFormat(); 46 | var validJson = isValidJson(JSON.stringify(format)); 47 | expect(validJson).toEqual(true); 48 | }); 49 | 50 | // Test to check if result of setformat is equal to expected query format. 51 | it('Is setformat matches with expected query format', () => { 52 | var format = query.setFormat(); 53 | expect(format).toEqual(expectedFormat); 54 | }); 55 | 56 | 57 | // Test to check if result of setformat is equal to expected query format with option. 58 | it('Is setformat matches with expected query format when pass options with query', () => { 59 | query.optionRows = [{ 60 | name: 'operator', 61 | value: 'and' 62 | }, { 63 | name: 'zero_terms_query', 64 | value: 'all' 65 | }]; 66 | var format = query.setFormat(); 67 | expect(format).toEqual(expectedFormatWithOption); 68 | }); 69 | }) 70 | 71 | declare var $; 72 | describe("xhr test (Match)", function () { 73 | var returnedJSON: any = {}; 74 | var status = 0; 75 | 76 | beforeEach(function (done) { 77 | var query = new MatchQuery(); 78 | query.queryName = 'match'; 79 | query.fieldName = 'name'; 80 | query.inputs = { 81 | input: { 82 | value: 'test_foobar' 83 | } 84 | }; 85 | var config = { 86 | url: 'https://scalr.api.appbase.io', 87 | appname: 'mirage_test', 88 | username: 'wvCmyBy3D', 89 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 90 | }; 91 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 92 | var query_data = query.setFormat(); 93 | var request_data = { 94 | "query": { 95 | "bool": { 96 | "must": [query_data] 97 | } 98 | } 99 | }; 100 | $.ajax({ 101 | type: 'POST', 102 | beforeSend: function(request) { 103 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 104 | }, 105 | url: url, 106 | contentType: 'application/json; charset=utf-8', 107 | dataType: 'json', 108 | data: JSON.stringify(request_data), 109 | xhrFields: { 110 | withCredentials: true 111 | }, 112 | success: function(res) { 113 | returnedJSON = res; 114 | status = 200; 115 | done(); 116 | }, 117 | error: function(xhr) { 118 | returnedJSON = xhr; 119 | status = xhr.status; 120 | done(); 121 | } 122 | }); 123 | }); 124 | 125 | it("Should have returned JSON and Should have atleast 1 record", function () { 126 | expect(returnedJSON).not.toEqual({}); 127 | expect(returnedJSON).not.toBeUndefined(); 128 | expect(status).toEqual(200); 129 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 130 | }); 131 | 132 | }); -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/simple_query_string.query.spec.ts: -------------------------------------------------------------------------------- 1 | import {SimpleQueryStringQuery} from './simple_query_string.query'; 2 | 3 | describe('Query string format', () => { 4 | // Set initial things 5 | // set expected query format 6 | var query: SimpleQueryStringQuery; 7 | var expectedFormat = { 8 | 'simple_query_string': { 9 | 'query': 'test_foobar', 10 | 'fields': ['name'] 11 | } 12 | }; 13 | var expectedFormatWithOption = { 14 | 'simple_query_string': { 15 | 'query': 'test_foobar', 16 | 'fields': ['name', 'gender', 'eyeColor'] 17 | } 18 | }; 19 | 20 | // instantiate query component and set the input fields 21 | beforeEach(function() { 22 | query = new SimpleQueryStringQuery(); 23 | query.queryName = 'simple_query_string'; 24 | query.fieldName = 'name'; 25 | query.inputs = { 26 | input: { 27 | value: 'test_foobar' 28 | } 29 | }; 30 | }); 31 | 32 | function isValidJson(str: string) { 33 | try { 34 | JSON.parse(str); 35 | } catch (e) { 36 | return false; 37 | } 38 | return true; 39 | } 40 | 41 | // Test to check if queryformat is valid json 42 | it('is valid json', () => { 43 | var format = query.setFormat(); 44 | var validJson = isValidJson(JSON.stringify(format)); 45 | expect(validJson).toEqual(true); 46 | }); 47 | 48 | // Test to check if result of setformat is equal to expected query format. 49 | it('Is setformat matches with expected query format', () => { 50 | var format = query.setFormat(); 51 | expect(format).toEqual(expectedFormat); 52 | }); 53 | 54 | 55 | // Test to check if result of setformat is equal to expected query format with option. 56 | it('Is setformat matches with expected query format when pass options with query', () => { 57 | query.optionRows = [{ 58 | name: 'fields', 59 | value: 'gender,eyeColor' 60 | }]; 61 | var format = query.setFormat(); 62 | expect(format).toEqual(expectedFormatWithOption); 63 | }); 64 | }) 65 | 66 | declare var $; 67 | describe("xhr test (simple_query_string)", function () { 68 | var returnedJSON: any = {}; 69 | var status = 0; 70 | 71 | beforeEach(function (done) { 72 | var query = new SimpleQueryStringQuery(); 73 | query.queryName = 'simple_query_string'; 74 | query.fieldName = 'name'; 75 | query.inputs = { 76 | input: { 77 | value: 'test_foobar' 78 | } 79 | }; 80 | var config = { 81 | url: 'https://scalr.api.appbase.io', 82 | appname: 'mirage_test', 83 | username: 'wvCmyBy3D', 84 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 85 | }; 86 | var url = 'https://scalr.api.appbase.io/mirage_test/test/_search'; 87 | var query_data = query.setFormat(); 88 | var request_data = { 89 | "query": { 90 | "bool": { 91 | "must": [query_data] 92 | } 93 | } 94 | }; 95 | $.ajax({ 96 | type: 'POST', 97 | beforeSend: function(request) { 98 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 99 | }, 100 | url: url, 101 | contentType: 'application/json; charset=utf-8', 102 | dataType: 'json', 103 | data: JSON.stringify(request_data), 104 | xhrFields: { 105 | withCredentials: true 106 | }, 107 | success: function(res) { 108 | returnedJSON = res; 109 | status = 200; 110 | done(); 111 | }, 112 | error: function(xhr) { 113 | returnedJSON = xhr; 114 | status = xhr.status; 115 | done(); 116 | } 117 | }); 118 | }); 119 | 120 | it("Should have returned JSON and Should have atleast 1 record", function () { 121 | expect(returnedJSON).not.toEqual({}); 122 | expect(returnedJSON).not.toBeUndefined(); 123 | expect(status).toEqual(200); 124 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 125 | }); 126 | 127 | }); -------------------------------------------------------------------------------- /app/queryBlocks/queryBlocks.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 17 | 18 |
19 |
20 |
21 | 53 |
54 | 61 | 68 | 69 |
70 |
71 |
72 | 96 | 97 |
98 |
99 |
100 | 123 | 124 |
125 |
126 |
127 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/geopolygon.query.spec.ts: -------------------------------------------------------------------------------- 1 | import {GeoPolygonQuery} from './geopolygon.query'; 2 | 3 | describe('geo_polygon query format', () => { 4 | // Set initial things 5 | // set expected query format 6 | var query: GeoPolygonQuery; 7 | var expectedFormat = { 8 | 'geo_polygon': { 9 | 'location': { 10 | "points" : [[5,5], [15,10], [10, 15]] 11 | } 12 | } 13 | }; 14 | var expectedFormatWithOption = { 15 | 'geo_polygon': { 16 | 'location': { 17 | "points" : [[5,5], [15,10], [10, 15]] 18 | }, 19 | "_name": "place", 20 | "ignore_malformed": "true" 21 | } 22 | }; 23 | 24 | // instantiate query component and set the input fields 25 | beforeEach(function() { 26 | query = new GeoPolygonQuery(); 27 | query.queryName = 'geo_polygon'; 28 | query.fieldName = 'location'; 29 | query.inputs = { 30 | points: { 31 | value: [[5,5], [15,10], [10, 15]] 32 | } 33 | }; 34 | }); 35 | 36 | function isValidJson(str: string) { 37 | try { 38 | JSON.parse(str); 39 | } catch (e) { 40 | return false; 41 | } 42 | return true; 43 | } 44 | 45 | // Test to check if queryformat is valid json 46 | it('is valid json', () => { 47 | var format = query.setFormat(); 48 | var validJson = isValidJson(JSON.stringify(format)); 49 | expect(validJson).toEqual(true); 50 | }); 51 | 52 | // Test to check if result of setformat is equal to expected query format. 53 | it('Is setformat matches with expected query format', () => { 54 | var format = query.setFormat(); 55 | expect(format).toEqual(expectedFormat); 56 | }); 57 | 58 | // Test to check if result of setformat is equal to expected query format with option. 59 | it('Is setformat matches with expected query format when pass options with query', () => { 60 | query.optionRows = [{ 61 | name: '_name', 62 | value: 'place' 63 | }, { 64 | name: 'ignore_malformed', 65 | value: 'true' 66 | }]; 67 | var format = query.setFormat(); 68 | expect(format).toEqual(expectedFormatWithOption); 69 | }); 70 | }); 71 | 72 | declare var $; 73 | describe("xhr test (geo_polygon)", function () { 74 | var returnedJSON: any = {}; 75 | var status = 0; 76 | 77 | beforeEach(function (done) { 78 | var query = new GeoPolygonQuery(); 79 | query.queryName = 'geo_polygon'; 80 | query.fieldName = 'place'; 81 | query.inputs = { 82 | points: { 83 | value: [[5,5], [15,10], [10, 15]] 84 | } 85 | }; 86 | var config = { 87 | url: 'https://scalr.api.appbase.io', 88 | appname: 'mirage_test', 89 | username: 'wvCmyBy3D', 90 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 91 | }; 92 | var url = 'https://scalr.api.appbase.io/mirage_test/geo/_search'; 93 | var query_data = query.setFormat(); 94 | var request_data = { 95 | "query": { 96 | "bool": { 97 | "must": [query_data] 98 | } 99 | } 100 | }; 101 | $.ajax({ 102 | type: 'POST', 103 | beforeSend: function(request) { 104 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 105 | }, 106 | url: url, 107 | contentType: 'application/json; charset=utf-8', 108 | dataType: 'json', 109 | data: JSON.stringify(request_data), 110 | xhrFields: { 111 | withCredentials: true 112 | }, 113 | success: function(res) { 114 | returnedJSON = res; 115 | status = 200; 116 | done(); 117 | }, 118 | error: function(xhr) { 119 | returnedJSON = xhr; 120 | status = xhr.status; 121 | done(); 122 | } 123 | }); 124 | }); 125 | 126 | it("Should have returned JSON and Should have atleast 1 record", function () { 127 | expect(returnedJSON).not.toEqual({}); 128 | expect(returnedJSON).not.toBeUndefined(); 129 | expect(status).toEqual(200); 130 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 131 | }); 132 | 133 | }); -------------------------------------------------------------------------------- /app/queryBlocks/boolquery/boolquery.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnChanges, Input, Output, EventEmitter } from "@angular/core"; 2 | declare var $: any; 3 | 4 | @Component({ 5 | selector: 'bool-query', 6 | templateUrl: './app/queryBlocks/boolquery/boolquery.component.html', 7 | inputs: ['config', 'query', 'queryList', 'addQuery', 'removeQuery', 'addBoolQuery', 'queryFormat', 'buildQuery', 'buildInsideQuery', 'buildSubQuery', 'createQuery', 'setQueryFormat', 'editorHookHelp', 'urlShare', 'setDocSample'] 8 | }) 9 | 10 | export class BoolqueryComponent implements OnInit, OnChanges { 11 | public config: Object; 12 | public queryList: any = this.queryList; 13 | public addQuery: any; 14 | public addBoolQuery: any; 15 | public removeQuery: any; 16 | public removeArray: any = []; 17 | public query: any = this.query; 18 | public buildQuery: any; 19 | public allFields: any; 20 | public informationList: any = { 21 | 'nested': { 22 | title: 'nested', 23 | content: `Nested query allows you to run a query against the nested documents and filter parent docs by those that have at least one nested document matching the query. 24 | Read more` 25 | }, 26 | 'has_child': { 27 | title: 'has_child', 28 | content: `has_child filter accepts a query and the child type to run against, and results in parent documents that have child docs matching the query. 29 | Read more` 30 | }, 31 | 'has_parent': { 32 | title: 'has_parent', 33 | content: `has_parent query accepts a query and a parent type. The query is executed in the parent document space, which is specified by the parent type, and returns child documents which associated parents have matched. 34 | Read more` 35 | }, 36 | 'parent_id': { 37 | title: 'parent_id', 38 | content: `parent_id query can be used to find child documents which belong to a particular parent. 39 | Read more` 40 | } 41 | }; 42 | @Input() mapping: any; 43 | @Input() types: any; 44 | @Input() selectedTypes: any; 45 | @Input() result: any; 46 | @Input() joiningQuery: any = ['']; 47 | @Input() joiningQueryParam: any; 48 | @Output() setJoiningQuery = new EventEmitter < any >(); 49 | @Output() setDocSample = new EventEmitter < any >(); 50 | 51 | ngOnInit() { 52 | this.allFields = this.result.resultQuery.availableFields; 53 | this.exeBuild(); 54 | } 55 | 56 | ngOnChanges() { 57 | this.allFields = this.result.resultQuery.availableFields; 58 | } 59 | 60 | addSubQuery(id: number) { 61 | this.addBoolQuery(id); 62 | } 63 | removeInQuery(id: number) { 64 | var resulQueries = this.result.resultQuery.result; 65 | this.removeArray.push(id); 66 | var removeFlag = true; 67 | resulQueries.forEach(function(v: any, i: number) { 68 | if (v.parent_id == id) { 69 | this.removeInQuery(v.id); 70 | removeFlag = false; 71 | } 72 | }.bind(this)); 73 | 74 | if (removeFlag) { 75 | this.removeArray.forEach(function(remove_q: number) { 76 | resulQueries.forEach(function(v: any, i: number) { 77 | if (v.id == remove_q) { 78 | resulQueries.splice(i, 1); 79 | } 80 | }.bind(this)); 81 | }.bind(this)); 82 | } 83 | this.buildQuery(); 84 | } 85 | exeBuild() { 86 | setTimeout(() => this.buildQuery(), 300); 87 | } 88 | booleanChange(boolVal: any) { 89 | this.query.boolparam = boolVal; 90 | this.exeBuild(); 91 | } 92 | joiningQueryChange(val: any) { 93 | if (val.val) { 94 | val = this.joiningQuery.indexOf(val.val); 95 | } 96 | this.joiningQueryParam = val; 97 | this.setJoiningQuery.emit({ 98 | param: val, 99 | allFields: this.allFields 100 | }); 101 | this.exeBuild(); 102 | } 103 | show_hidden_btns(event: any) { 104 | $('.bool_query').removeClass('show_hidden'); 105 | $(event.currentTarget).addClass('show_hidden'); 106 | event.stopPropagation(); 107 | } 108 | hide_hidden_btns() { 109 | $('.bool_query').removeClass('show_hidden'); 110 | } 111 | setDocSampleEve(link) { 112 | this.setDocSample.emit(link); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/geodistancerange.query.spec.ts: -------------------------------------------------------------------------------- 1 | import {GeoDistanceRangeQuery} from './geodistancerange.query'; 2 | 3 | describe('geo_distance_range query format', () => { 4 | // Set initial things 5 | // set expected query format 6 | var query: GeoDistanceRangeQuery; 7 | var expectedFormat = { 8 | 'geo_distance_range': { 9 | 'from': '0km', 10 | 'to': '1000km', 11 | 'location': { 12 | 'lat': '10', 13 | 'lon': '10' 14 | } 15 | } 16 | }; 17 | var expectedFormatWithOption = { 18 | 'geo_distance_range': { 19 | 'from': '0km', 20 | 'to': '1000km', 21 | 'location': { 22 | 'lat': '10', 23 | 'lon': '10' 24 | } 25 | } 26 | }; 27 | 28 | // instantiate query component and set the input fields 29 | beforeEach(function() { 30 | query = new GeoDistanceRangeQuery(); 31 | query.queryName = 'geo_distance_range'; 32 | query.fieldName = 'location'; 33 | query.inputs = { 34 | lat: { 35 | value: '10' 36 | }, 37 | lon: { 38 | value: '10' 39 | }, 40 | from: { 41 | value: '0km' 42 | }, 43 | to: { 44 | value: '1000km' 45 | } 46 | }; 47 | }); 48 | 49 | function isValidJson(str: string) { 50 | try { 51 | JSON.parse(str); 52 | } catch (e) { 53 | return false; 54 | } 55 | return true; 56 | } 57 | 58 | // Test to check if queryformat is valid json 59 | it('is valid json', () => { 60 | var format = query.setFormat(); 61 | var validJson = isValidJson(JSON.stringify(format)); 62 | expect(validJson).toEqual(true); 63 | }); 64 | 65 | // Test to check if result of setformat is equal to expected query format. 66 | it('Is setformat matches with expected query format', () => { 67 | var format = query.setFormat(); 68 | expect(format).toEqual(expectedFormat); 69 | }); 70 | }); 71 | 72 | declare var $; 73 | describe("xhr test (geo_distance_range)", function () { 74 | var returnedJSON: any = {}; 75 | var status = 0; 76 | 77 | beforeEach(function (done) { 78 | var query = new GeoDistanceRangeQuery(); 79 | query.queryName = 'geo_distance_range'; 80 | query.fieldName = 'place'; 81 | query.inputs = { 82 | lat: { 83 | value: '10' 84 | }, 85 | lon: { 86 | value: '10' 87 | }, 88 | from: { 89 | value: '0km' 90 | }, 91 | to: { 92 | value: '1000km' 93 | } 94 | }; 95 | var config = { 96 | url: 'https://scalr.api.appbase.io', 97 | appname: 'mirage_test', 98 | username: 'wvCmyBy3D', 99 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 100 | }; 101 | var url = 'https://scalr.api.appbase.io/mirage_test/geo/_search'; 102 | var query_data = query.setFormat(); 103 | var request_data = { 104 | "query": { 105 | "bool": { 106 | "must": [query_data] 107 | } 108 | } 109 | }; 110 | $.ajax({ 111 | type: 'POST', 112 | beforeSend: function(request) { 113 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 114 | }, 115 | url: url, 116 | contentType: 'application/json; charset=utf-8', 117 | dataType: 'json', 118 | data: JSON.stringify(request_data), 119 | xhrFields: { 120 | withCredentials: true 121 | }, 122 | success: function(res) { 123 | returnedJSON = res; 124 | status = 200; 125 | done(); 126 | }, 127 | error: function(xhr) { 128 | returnedJSON = xhr; 129 | status = xhr.status; 130 | done(); 131 | } 132 | }); 133 | }); 134 | 135 | it("Should have returned JSON and Should have atleast 1 record", function () { 136 | expect(returnedJSON).not.toEqual({}); 137 | expect(returnedJSON).not.toBeUndefined(); 138 | expect(status).toEqual(200); 139 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 140 | }); 141 | 142 | }); -------------------------------------------------------------------------------- /app/features/subscribe/AuthOperation.ts: -------------------------------------------------------------------------------- 1 | import { 2 | OnInit, 3 | OnChanges, 4 | Component, 5 | Input, 6 | Output, 7 | EventEmitter, 8 | AfterViewInit 9 | } from "@angular/core"; 10 | import { Headers, Http } from "@angular/http"; 11 | import { StorageService } from "../../shared/storage.service"; 12 | 13 | declare var $: any, Auth0: any, location: any; 14 | 15 | @Component({ 16 | selector: "auth-operation", 17 | template: "" 18 | }) 19 | export class AuthOperation implements OnInit { 20 | @Output() updateStatus = new EventEmitter(); 21 | public auth0: any; 22 | public serverAddress: string = "https://ossauth.appbase.io"; 23 | public token: any; 24 | public access_token_applied: boolean = false; 25 | 26 | constructor(private http: Http, public storageService: StorageService) {} 27 | ngOnInit() { 28 | var authConfig = { 29 | domain: "appbaseio.auth0.com", 30 | clientID: "tCy6GxnrsyKec3UxXCuYLhU6XWFCMgRD", 31 | callbackURL: location.href, 32 | callbackOnLocationHash: true 33 | }; 34 | this.auth0 = new Auth0(authConfig); 35 | // check if already logged in 36 | this.init.call(this); 37 | } 38 | init() { 39 | var self = this; 40 | this.parseHash.call(this); 41 | var parseHash = this.parseHash.bind(this); 42 | setTimeout(function() { 43 | window.onhashchange = function() { 44 | if ( 45 | !self.access_token_applied && 46 | location.hash.indexOf("access_token") > -1 47 | ) { 48 | console.log("access_token found!"); 49 | parseHash(); 50 | } 51 | }; 52 | }, 300); 53 | } 54 | isTokenExpired(token) { 55 | var decoded = this.auth0.decodeJwt(token); 56 | var now = new Date().getTime() / 1000; 57 | return decoded.exp < now; 58 | } 59 | login(subscribeOption) { 60 | let savedState = window.location.hash; 61 | this.storageService.set("subscribeOption", subscribeOption); 62 | if (savedState.indexOf("access_token") < 0) { 63 | this.storageService.set("savedState", savedState); 64 | } 65 | this.auth0.login( 66 | { 67 | connection: "github" 68 | }, 69 | function(err) { 70 | if (err) console.log("something went wrong: " + err.message); 71 | } 72 | ); 73 | } 74 | show_logged_in(token) { 75 | this.token = token; 76 | if (window.location.hash.indexOf("access_token") > -1) { 77 | this.access_token_applied = true; 78 | this.restoreStates(); 79 | } else { 80 | this.getUserProfile(); 81 | } 82 | } 83 | show_sign_in() {} 84 | restoreStates() { 85 | let domain = location.href.split("#")[0]; 86 | let savedState = this.storageService.get("savedState"); 87 | let finalPath = domain; 88 | if (savedState && savedState.indexOf("access_token") < 0) { 89 | finalPath += savedState; 90 | } else { 91 | finalPath += "#"; 92 | } 93 | window.location.href = finalPath; 94 | location.reload(); 95 | } 96 | getUserProfile() { 97 | var url = this.serverAddress + "/api/getUserProfile"; 98 | let subscribeOption = 99 | this.storageService.get("subscribeOption") && 100 | this.storageService.get("subscribeOption") !== "null" 101 | ? this.storageService.get("subscribeOption") 102 | : null; 103 | var request = { 104 | token: this.storageService.get("mirage_id_token"), 105 | origin_app: "MIRAGE", 106 | email_preference: subscribeOption 107 | }; 108 | $.ajax({ 109 | type: "POST", 110 | url: url, 111 | contentType: "application/json; charset=utf-8", 112 | dataType: "json", 113 | data: JSON.stringify(request) 114 | }) 115 | .done( 116 | function(res) { 117 | this.storageService.set("subscribeOption", null); 118 | this.updateStatus.emit({ profile: res.message }); 119 | }.bind(this) 120 | ) 121 | .fail(function(err) { 122 | console.error(err); 123 | }); 124 | } 125 | parseHash() { 126 | var token = this.storageService.get("mirage_id_token"); 127 | if (token !== null && !this.isTokenExpired(token)) { 128 | this.show_logged_in(token); 129 | } else { 130 | var result = this.auth0.parseHash(window.location.hash); 131 | if (result && result.idToken) { 132 | this.storageService.set("mirage_id_token", result.idToken); 133 | this.show_logged_in(result.idToken); 134 | } else if (result && result.error) { 135 | console.log("error: " + result.error); 136 | this.show_sign_in(); 137 | } else { 138 | this.show_sign_in(); 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /app/queryBlocks/singlequery/queries/geoshape.query.spec.ts: -------------------------------------------------------------------------------- 1 | import {GeoShapeQuery} from './geoshape.query'; 2 | 3 | describe('geo_shape query format', () => { 4 | // Set initial things 5 | // set expected query format 6 | var query: GeoShapeQuery; 7 | var expectedFormat = { 8 | 'geo_shape': { 9 | 'location': { 10 | "shape" : { 11 | "type" : "Point", 12 | "coordinates" : [25, 25] 13 | } 14 | } 15 | } 16 | }; 17 | var expectedFormatWithOption = { 18 | 'geo_shape': { 19 | 'location': { 20 | "shape" : { 21 | "type" : "Point", 22 | "coordinates" : [25, 25] 23 | }, 24 | "relation": "within" 25 | } 26 | } 27 | }; 28 | 29 | // instantiate query component and set the input fields 30 | beforeEach(function() { 31 | query = new GeoShapeQuery(); 32 | query.queryName = 'geo_shape'; 33 | query.fieldName = 'location'; 34 | query.inputs = { 35 | type: { 36 | value: 'Point' 37 | }, 38 | coordinates: { 39 | value: [25, 25] 40 | } 41 | }; 42 | }); 43 | 44 | function isValidJson(str: string) { 45 | try { 46 | JSON.parse(str); 47 | } catch (e) { 48 | return false; 49 | } 50 | return true; 51 | } 52 | 53 | // Test to check if queryformat is valid json 54 | it('is valid json', () => { 55 | var format = query.setFormat(); 56 | var validJson = isValidJson(JSON.stringify(format)); 57 | expect(validJson).toEqual(true); 58 | }); 59 | 60 | // Test to check if result of setformat is equal to expected query format. 61 | it('Is setformat matches with expected query format', () => { 62 | var format = query.setFormat(); 63 | expect(format).toEqual(expectedFormat); 64 | }); 65 | 66 | // Test to check if result of setformat is equal to expected query format with option. 67 | it('Is setformat matches with expected query format when pass options with query', () => { 68 | query.optionRows = [{ 69 | name: 'relation', 70 | value: 'within' 71 | }]; 72 | var format = query.setFormat(); 73 | expect(format).toEqual(expectedFormatWithOption); 74 | }); 75 | }); 76 | 77 | declare var $; 78 | describe("xhr test (geo_shape)", function () { 79 | var returnedJSON: any = {}; 80 | var status = 0; 81 | 82 | beforeEach(function (done) { 83 | var query = new GeoShapeQuery(); 84 | query.queryName = 'geo_shape'; 85 | query.fieldName = 'location_shape'; 86 | query.inputs = { 87 | type: { 88 | value: 'Point' 89 | }, 90 | coordinates: { 91 | value: [25, 25] 92 | } 93 | }; 94 | var config = { 95 | url: 'https://scalr.api.appbase.io', 96 | appname: 'mirage_test', 97 | username: 'wvCmyBy3D', 98 | password: '7a7078e0-0204-4ccf-9715-c720f24754f2' 99 | }; 100 | var url = 'https://scalr.api.appbase.io/mirage_test/geo/_search'; 101 | var query_data = query.setFormat(); 102 | var request_data = { 103 | "query": { 104 | "bool": { 105 | "must": [query_data] 106 | } 107 | } 108 | }; 109 | $.ajax({ 110 | type: 'POST', 111 | beforeSend: function(request) { 112 | request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ':' + config.password)); 113 | }, 114 | url: url, 115 | contentType: 'application/json; charset=utf-8', 116 | dataType: 'json', 117 | data: JSON.stringify(request_data), 118 | xhrFields: { 119 | withCredentials: true 120 | }, 121 | success: function(res) { 122 | returnedJSON = res; 123 | status = 200; 124 | done(); 125 | }, 126 | error: function(xhr) { 127 | returnedJSON = xhr; 128 | status = xhr.status; 129 | done(); 130 | } 131 | }); 132 | }); 133 | 134 | it("Should have returned JSON and Should have atleast 1 record", function () { 135 | expect(returnedJSON).not.toEqual({}); 136 | expect(returnedJSON).not.toBeUndefined(); 137 | expect(status).toEqual(200); 138 | expect(returnedJSON.hits.hits.length).toBeGreaterThan(0); 139 | }); 140 | 141 | }); 142 | --------------------------------------------------------------------------------