Last active
February 8, 2023 02:52
-
-
Save gistlyn/f0349678d7f09f38c66bb1ecd89b09a5 to your computer and use it in GitHub Desktop.
Northwind SharpData UI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{ | |
var AppSvgs = { | |
'action/home.svg': 'home', | |
'device/storage.svg': 'db', | |
'action/list.svg': 'table', | |
'navigation/first_page.svg': 'chevron-first', | |
'navigation/last_page.svg': 'chevron-last', | |
'navigation/expand_more.svg': 'chevron-down', | |
'navigation/chevron_left.svg': 'chevron-left', | |
'navigation/chevron_right.svg': 'chevron-right', | |
'navigation/expand_less.svg': 'chevron-up', | |
'content/clear.svg': 'clear', | |
'content/filter_list.svg': 'filter', | |
} | |
}} | |
{{#each AppSvgs}} | |
{{`/lib/svg/material/${it.Key}` |> svgAddFile(it.Value,'app')}} | |
{{/each}} | |
{{#svg fields app}} | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="black" width="48px" height="48px"> | |
<path d="M0 0h24v24H0V0z" fill="none"/> | |
<path d="M4 5v13h17V5H4zm10 2v9h-3V7h3zM6 7h3v9H6V7zm13 9h-3V7h3v9z" fill="#ffffff"/> | |
</svg> | |
{{/svg}} | |
{{#svg external-link app}} | |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/> | |
<polyline points="15 3 21 3 21 9"/> | |
<line x1="10" y1="14" x2="21" y2="3"/> | |
</svg> | |
{{/svg}} | |
{{#svg loading app}} | |
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24px" height="30px" viewBox="0 0 24 30" style="enable-background:new 0 0 50 50"> | |
<rect x="0" y="10" width="4" height="10" fill="#333" opacity="0.2"> | |
<animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0s" dur="0.6s" repeatCount="indefinite" /> | |
<animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0s" dur="0.6s" repeatCount="indefinite" /> | |
<animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0s" dur="0.6s" repeatCount="indefinite" /> | |
</rect> | |
<rect x="8" y="10" width="4" height="10" fill="#333" opacity="0.2"> | |
<animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0.15s" dur="0.6s" repeatCount="indefinite" /> | |
<animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0.15s" dur="0.6s" repeatCount="indefinite" /> | |
<animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0.15s" dur="0.6s" repeatCount="indefinite" /> | |
</rect> | |
<rect x="16" y="10" width="4" height="10" fill="#333" opacity="0.2"> | |
<animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0.3s" dur="0.6s" repeatCount="indefinite" /> | |
<animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0.3s" dur="0.6s" repeatCount="indefinite" /> | |
<animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0.3s" dur="0.6s" repeatCount="indefinite" /> | |
</rect> | |
</svg> | |
{{/svg}} | |
{{#svg logo app}} | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#ffffff" width="48px" height="48px"> | |
<path d="M18 4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4h-4z"/> | |
<path d="M0 0h24v24H0z" fill="none"/> | |
</svg> | |
{{/svg}} | |
{{#svg excel app}} | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"> | |
<path fill="#4CAF50" d="M41,10H25v28h16c0.553,0,1-0.447,1-1V11C42,10.447,41.553,10,41,10z"/> | |
<path fill="#FFF" d="M32 15H39V18H32zM32 25H39V28H32zM32 30H39V33H32zM32 20H39V23H32zM25 15H30V18H25zM25 25H30V28H25zM25 30H30V33H25zM25 20H30V23H25z"/> | |
<path fill="#2E7D32" d="M27 42L6 38 6 10 27 6z"/> | |
<path fill="#FFF" d="M19.129,31l-2.411-4.561c-0.092-0.171-0.186-0.483-0.284-0.938h-0.037c-0.046,0.215-0.154,0.541-0.324,0.979L13.652,31H9.895l4.462-7.001L10.274,17h3.837l2.001,4.196c0.156,0.331,0.296,0.725,0.42,1.179h0.04c0.078-0.271,0.224-0.68,0.439-1.22L19.237,17h3.515l-4.199,6.939l4.316,7.059h-3.74V31z"/> | |
</svg> | |
{{/svg}} | |
{{htmlError}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<link href="/favicon.png" rel="icon"> | |
<link rel="stylesheet" href="/lib/css/bootstrap/bootstrap.css"> | |
<title>{{ title ?? 'Sharp Data' }}</title> | |
</head> | |
<body> | |
{{ 'buttons,buttons-svg' |> cssIncludes }} | |
{{ 'app' |> cssIncludes |> svgFill('#444') }} | |
{{#if fileExists('/bundle.css') }} | |
<link rel="stylesheet" href="/bundle.css"> | |
{{else}} | |
{{ 'content:/src/css/' |> bundleCss({ minify:false, cache:false, out:'/app.bundle.css' }) }} | |
{{/if}} | |
<style> | |
{{ { | |
'.home-link': ['home','#4183B8'], | |
'.first-link': ['chevron-first','#4183B8'], | |
'.left-link': ['chevron-left','#4183B8'], | |
'.right-link': ['chevron-right','#4183B8'], | |
'.last-link': ['chevron-last','#4183B8'], | |
} |> toList |> map => `${it.Key} { ${it.Value[0].svgBackgroundImageCss(it.Value[1])} }` |> joinln |> raw }} | |
.text-close::after { content:'\00D7'; } | |
</style> | |
<i hidden>{{ '/js/hot-fileloader.js' |> ifDebugIncludeScript }}</i> | |
<script> | |
CONFIG = { | |
debug: {{ debugMode |> json }}, | |
desktop: {{ desktopInfo |> json }}, | |
hasExcel: {{ (isWin ? typeofProgId('Excel.Application') != null : false) |> json }}, | |
namedDbs: {{ dbNamedConnections |> json }}, | |
tables: {} | |
} | |
{{#if resolveArg('tables')}} | |
CONFIG.tables.main = {{ resolveArg('tables').split(',') |> json }}; | |
{{else}} | |
CONFIG.tables.main = {{ dbTableNames |> json }}; | |
{{/if}} | |
{{#each dbNamedConnections}} | |
{{#if resolveArg(`tables_${it}`) }} | |
CONFIG.tables['{{it}}'] = {{ resolveArg(`tables_${it}`).split(',') |> json }}; | |
{{else}} | |
CONFIG.tables['{{it}}'] = {{ {} |> dbTableNames({ namedConnection:it }) |> json }}; | |
{{/if}} | |
{{/each}} | |
</script> | |
<noscript>You need to enable JavaScript to run this app.</noscript> | |
{{page}} | |
{{ [ | |
`/lib/js/vue/vue.min.js`, | |
`/lib/js/vue-router/vue-router.min.js`, | |
`/lib/js/vue-class-component/vue-class-component.min.js`, | |
`/lib/js/vue-property-decorator/vue-property-decorator.min.js`, | |
`/lib/js/@servicestack/desktop/servicestack-desktop.min.js`, | |
`/lib/js/@servicestack/client/servicestack-client.min.js`, | |
`/lib/js/@servicestack/vue/servicestack-vue.min.js`, | |
] |> map => `<script src="${it}"></script>` |> joinln |> raw }} | |
<script> | |
var ALIASES = { | |
'vue': { default: Vue }, | |
'vue-router': { default: VueRouter }, | |
'vue-class-component': VueClassComponent, | |
'vue-property-decorator': VuePropertyDecorator, | |
'@servicestack/vue': ServiceStackVue | |
}; | |
var global = window; | |
window.exports = {}; | |
window.require = function(name) { | |
return ALIASES[name] || exports[name] || window[name] || exports; | |
}; | |
Object.assign(window, window["@servicestack/desktop"], window["@servicestack/client"]); | |
</script> | |
{{#if fileExists('/bundle.js') }} | |
<script src="/bundle.js"></script> | |
{{else}} | |
{{ [ | |
'content:/src/components/', | |
'content:/src/shared/', | |
'content:/src/', | |
] |> bundleJs({ minify:false, cache:false, iife:true, out:`/app.bundle.js` }) }} | |
{{/if}} | |
{{ ['custom/'] |> bundleJs({ minify:false, bundle:false }) }} | |
{{ scripts |> raw }} | |
{{initError |> htmlError}} | |
{{htmlError}} | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
debug false | |
name Northwind SharpData UI | |
appName sharpdata | |
# Configure below. Supported dialects: sqlite, mysql, postgres, sqlserver | |
db.connections[northwind] { db:sqlite, connection: 'northwind.sqlite' } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.grid-layout{display:grid;width:100vw;height:100vh;grid-column-gap:5px;grid-template-columns:250px auto;grid-template-rows:80px auto;grid-template-areas:"head head" "nav main"}header{background:#fff;grid-area:head;display:grid;grid-template-columns:auto auto;grid-template-areas:"breadcrumb auth"}.site-breadcrumbs{padding-left:0;height:80px}nav{background:#fff;grid-area:nav;padding:0 2px 0 10px;overflow-x:hidden;overflow-y:auto;display:grid;grid-template-rows:40px auto;grid-template-areas:"filter" "sidebar"}#nav-filter{grid-area:filter;margin:2px 0 0 0}#sidebar{grid-area:sidebar;overflow-x:hidden;overflow-y:scroll}main{background:#fff;grid-area:main;padding:2px;grid-row-gap:5px;overflow:auto;display:grid}.main-query,.loading-query{height:38px;font-size:20px;padding-top:1px}.main-container{overflow-y:scroll} | |
::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background-color:#f1f1f1}.navbar{border-radius:0;background:#4183b8!important}a{color:#4183b8}a:hover{text-decoration:none}.form-check input[type=checkbox],.form-check input[type=radio]{margin-top:7px}.breadcrumb{background:none}.result{margin:10px;color:#349268}.stacktrace{background:#f1f1f1;padding:1em;margin:1em 0 .5em 0;border-radius:5px;border:1px solid #ccc;white-space:pre-wrap}.results-none{color:#6c757d}table.results{border:1px solid #eee;background:#fefefe}table.results thead tr{background:#eee}table.results th{text-align:left;color:#757575;font-size:13px;line-height:18px;border-bottom:1px solid #e0e0e0;padding:5px;overflow:hidden;white-space:nowrap}table.results td{color:#212121;font-size:12px;padding:5px;max-width:300px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}table.results td.row-component{max-width:900px}table.results tr.filters td{text-overflow:unset}th .modal-content,td .modal-content{font-size:1rem}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.svg-btn,.btn-link,.th-link{cursor:pointer;user-select:none}.btn-link{text-decoration:none}#sidebar .selected{font-weight:bold}.datamodel{white-space:nowrap}.close,.text-close{user-select:none}.text-close{cursor:pointer;font-size:1.5em;color:#999}.text-close:hover{color:#666}.results-label{color:#666;vertical-align:bottom;line-height:36px}table.results .filters td{padding:0 1px;margin:0}.filters input{min-width:50px;width:100%;font-size:11px}.btn-compact.btn-sm{padding:.1rem .4rem}.jsonviewer .ib{display:inline-block}.jsonviewer table{border-collapse:collapse;border:solid 1px #ccc;clear:left}.jsonviewer th{text-align:left;padding:4px 8px;text-shadow:#fff 1px 1px -1px;background:#f1f1f1;white-space:nowrap;font-weight:bold}.jsonviewer td{padding:8px 8px 0 8px;vertical-align:top;line-height:18px}.jsonviewer dl{margin:0;clear:left}.jsonviewer dt{font-weight:bold;width:160px;clear:left;float:left;display:block;white-space:nowrap;line-height:26px}.jsonviewer dd{display:block;float:left;line-height:26px;max-width:600px;margin:0}.jsonviewer dl dl dt{font-weight:bold}.jsonviewer hr{display:none}.jsonviewer td dl HR{display:block;padding:0;clear:left;border:0}.jsonviewer td dl{padding:4px;margin:0;height:100%;max-width:700px}.jsonviewer dl td dl dt{padding:2px;margin:0 10px 0 0;font-weight:bold;width:120px;overflow:hidden;clear:left;float:left;display:block}.jsonviewer dl td dl dd{margin:0;padding:2px;display:block;float:left} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(){ | |
"use strict"; | |
var __extends = (this && this.__extends) || (function () { | |
var extendStatics = Object.setPrototypeOf || | |
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | |
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | |
return function (d, b) { | |
extendStatics(d, b); | |
function __() { this.constructor = d; } | |
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | |
}; | |
})(); | |
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | |
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; | |
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); | |
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | |
return c > 3 && r && Object.defineProperty(target, key, r), r; | |
}; | |
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | |
return new (P || (P = Promise))(function (resolve, reject) { | |
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | |
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | |
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | |
step((generator = generator.apply(thisArg, _arguments || [])).next()); | |
}); | |
}; | |
var __generator = (this && this.__generator) || function (thisArg, body) { | |
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | |
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | |
function verb(n) { return function (v) { return step([n, v]); }; } | |
function step(op) { | |
if (f) throw new TypeError("Generator is already executing."); | |
while (_) try { | |
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; | |
if (y = 0, t) op = [0, t.value]; | |
switch (op[0]) { | |
case 0: case 1: t = op; break; | |
case 4: _.label++; return { value: op[1], done: false }; | |
case 5: _.label++; y = op[1]; op = [0]; continue; | |
case 7: op = _.ops.pop(); _.trys.pop(); continue; | |
default: | |
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | |
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | |
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | |
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | |
if (t[2]) _.ops.pop(); | |
_.trys.pop(); continue; | |
} | |
op = body.call(thisArg, _); | |
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | |
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | |
} | |
}; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
var vue_1 = require("vue"); | |
var vue_property_decorator_1 = require("vue-property-decorator"); | |
var shared_1 = require("../../shared"); | |
var client_1 = require("@servicestack/client"); | |
var desktop_1 = require("@servicestack/desktop"); | |
var FormatString = /** @class */ (function (_super) { | |
__extends(FormatString, _super); | |
function FormatString() { | |
return _super !== null && _super.apply(this, arguments) || this; | |
} | |
Object.defineProperty(FormatString.prototype, "lower", { | |
get: function () { return ("" + this.value).toLowerCase(); }, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(FormatString.prototype, "isUrl", { | |
get: function () { return typeof this.value == "string" && this.value.startsWith('http'); }, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(FormatString.prototype, "url", { | |
get: function () { return typeof this.value == "string" && this.value.substring(this.value.indexOf('://') + 3); }, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(FormatString.prototype, "format", { | |
get: function () { return typeof this.value == "string" && this.value.startsWith('/Date(') ? client_1.toDateFmt(this.value) : this.value; }, | |
enumerable: true, | |
configurable: true | |
}); | |
__decorate([ | |
vue_property_decorator_1.Prop({ default: '' }) | |
], FormatString.prototype, "value", void 0); | |
__decorate([ | |
vue_property_decorator_1.Prop({ default: '' }) | |
], FormatString.prototype, "href", void 0); | |
FormatString = __decorate([ | |
vue_property_decorator_1.Component({ template: "<a v-if=\"isUrl\" :href=\"value\" target=\"_blank\">{{url}}</a>\n <i v-else-if=\"lower == 'false'\" class=\"svg svg-md bool-off-muted\"></i>\n <i v-else-if=\"lower == 'true'\" class=\"svg svg-md bool-on-muted\"></i>\n <a v-else-if=\"href\" :href=\"href\">{{format}}</a>\n <span v-else>{{format}}</span>\n" }) | |
], FormatString); | |
return FormatString; | |
}(vue_1.default)); | |
vue_1.default.component('format', FormatString); | |
var Results = /** @class */ (function (_super) { | |
__extends(Results, _super); | |
function Results() { | |
var _this = _super !== null && _super.apply(this, arguments) || this; | |
_this.showSelectColumns = false; | |
_this.skip = 0; | |
_this.take = 100; | |
_this.total = null; | |
_this.orderBy = ''; | |
_this.filters = {}; | |
_this.fields = []; | |
_this.results = []; | |
_this.openComponents = []; | |
_this.loading = false; | |
_this.responseStatus = null; | |
return _this; | |
} | |
Object.defineProperty(Results.prototype, "store", { | |
get: function () { return shared_1.store; }, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(Results.prototype, "columns", { | |
get: function () { return shared_1.store.getColumnSchemas(this.db, this.table); }, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(Results.prototype, "dirty", { | |
get: function () { return this.skip || this.orderBy || Object.keys(this.filters).length > 0 || this.fields.length > 0; }, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(Results.prototype, "rowComponent", { | |
get: function () { return shared_1.getRowComponent(this.db, this.table); }, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(Results.prototype, "fieldNames", { | |
get: function () { | |
var _this = this; | |
var ret = this.columns ? .map(function (x) { return x.columnName; }) : ; | |
if (this.fields.length > 0) { | |
ret = ret.filter(function (x) { return _this.fields.indexOf(x) >= 0; }); | |
} | |
return ret; | |
}, | |
enumerable: true, | |
configurable: true | |
}); | |
Results.prototype.showRowComponent = function (rowIndex) { return this.openComponents.indexOf(rowIndex) >= 0; }; | |
Results.prototype.toggleRowComponent = function (rowIndex) { | |
if (this.showRowComponent(rowIndex)) | |
this.openComponents = this.openComponents.filter(function (x) { return x != rowIndex; }); | |
else | |
this.openComponents.push(rowIndex); | |
}; | |
Results.prototype.rowComponentClass = function (rowIndex) { | |
return "svg svg-chevron-" + (this.showRowComponent(rowIndex) ? 'down' : 'right') + " svg-md btn-link align-top"; | |
}; | |
Results.prototype.min = function (num1, num2) { return Math.min(num1, num2); }; | |
Results.prototype.onUrlChange = function (newVal) { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: return [4 /*yield*/, this.reset()]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Results.prototype.clear = function () { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
if (this.$route.query.filter) { | |
this.$router.push(this.$route.path); | |
} | |
return [4 /*yield*/, shared_1.saveTableSettings(this.db, this.table, null)]; | |
case 1: | |
_a.sent(); | |
return [4 /*yield*/, this.reset()]; | |
case 2: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Results.prototype.reset = function () { | |
return __awaiter(this, void 0, void 0, function () { | |
var settings, parts, _a; | |
return __generator(this, function (_b) { | |
switch (_b.label) { | |
case 0: | |
settings = shared_1.getTableSettings(this.db, this.table) || {}; | |
this.skip = settings.skip || 0; | |
this.orderBy = settings.orderBy || ''; | |
this.filters = settings.filters || {}; | |
this.fields = settings.fields || []; | |
if (this.$route.query.filter) { | |
parts = client_1.splitOnFirst(this.$route.query.filter, ':'); | |
this.filters = (_a = {}, _a[parts[0]] = parts[1], _a); | |
} | |
this.results = []; | |
return [4 /*yield*/, shared_1.loadTable(this, this.db, this.table)]; | |
case 1: | |
_b.sent(); | |
return [4 /*yield*/, this.search()]; | |
case 2: | |
_b.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Results.prototype.handleSelectColumns = function (e) { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
this.showSelectColumns = false; | |
return [4 /*yield*/, this.search()]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Results.prototype.viewNext = function (skip) { | |
return __awaiter(this, void 0, void 0, function () { | |
var lastPage; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
this.skip += skip; | |
if (typeof this.total != 'number') | |
return [2 /*return*/]; | |
lastPage = Math.floor(this.total / 100) * 100; | |
if (this.skip > lastPage) { | |
this.skip = lastPage; | |
} | |
if (this.skip < 0) { | |
this.skip = 0; | |
} | |
return [4 /*yield*/, this.search()]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Object.defineProperty(Results.prototype, "filterQuery", { | |
get: function () { | |
var _this = this; | |
var url = ''; | |
Object.keys(this.filters).forEach(function (k) { | |
if (_this.filters[k]) { | |
url += '&'; | |
url += encodeURIComponent(k) + '=' + encodeURIComponent(_this.filters[k]); | |
} | |
}); | |
return url; | |
}, | |
enumerable: true, | |
configurable: true | |
}); | |
Results.prototype.filterSearch = function () { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
this.skip = 0; | |
return [4 /*yield*/, this.search()]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Results.prototype.createFilteredUrl = function (format) { | |
if (format === void 0) { format = "json"; } | |
var url = "/db/" + this.db + "/" + this.table + "?format=" + format; | |
url += this.filterQuery; | |
if (this.fields.length > 0) { | |
url += '&fields=' + encodeURIComponent(this.fields.join(',')); | |
} | |
if (this.orderBy) { | |
url += '&orderBy=' + encodeURIComponent(this.orderBy); | |
} | |
return url; | |
}; | |
Results.prototype.createUrl = function (format) { | |
if (format === void 0) { format = "json"; } | |
var url = this.createFilteredUrl(format); | |
if (this.skip > 0) { | |
url += '&skip=' + this.skip; | |
} | |
if (this.take) { | |
url += '&take=' + this.take; | |
} | |
//log('createUrl, filters', this.filters, 'orderBy', this.orderBy, 'take', this.take, 'URL', url); | |
return url; | |
}; | |
Results.prototype.search = function () { | |
return __awaiter(this, void 0, void 0, function () { | |
var _this = this; | |
var _a, _b; | |
return __generator(this, function (_c) { | |
switch (_c.label) { | |
case 0: | |
this.openComponents = []; | |
_a = this; | |
return [4 /*yield*/, shared_1.exec(this, function () { return __awaiter(_this, void 0, void 0, function () { | |
var url, r, json; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
url = this.createUrl(); | |
return [4 /*yield*/, fetch(url)]; | |
case 1: | |
r = _a.sent(); | |
return [4 /*yield*/, r.text()]; | |
case 2: | |
json = _a.sent(); | |
return [2 /*return*/, json && JSON.parse(json) || []]; | |
} | |
}); | |
}); })]; | |
case 1: | |
_a.results = _c.sent(); | |
if (this.rowComponent && this.results.length == 1) { | |
this.openComponents.push(0); | |
} | |
_b = this; | |
return [4 /*yield*/, shared_1.exec(this, function () { return __awaiter(_this, void 0, void 0, function () { | |
var url, r, txtTotal; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
url = "/db/" + this.db + "/" + this.table + "/total?format=json"; | |
url += this.filterQuery; | |
return [4 /*yield*/, fetch(url)]; | |
case 1: | |
r = _a.sent(); | |
return [4 /*yield*/, r.text()]; | |
case 2: | |
txtTotal = _a.sent(); | |
return [2 /*return*/, parseInt(txtTotal) || null]; | |
} | |
}); | |
}); })]; | |
case 2: | |
_b.total = _c.sent(); | |
return [4 /*yield*/, shared_1.saveTableSettings(this.db, this.table, { | |
skip: this.skip, | |
filters: this.filters, | |
orderBy: this.orderBy, | |
fields: this.fields, | |
})]; | |
case 3: | |
_c.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Results.prototype.openCsv = function () { | |
return __awaiter(this, void 0, void 0, function () { | |
var url, downloadUrl; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
url = this.createFilteredUrl("csv"); | |
downloadUrl = desktop_1.desktopSaveDownloadUrl(this.db + "-" + this.table + "-" + shared_1.dateFmtHMS() + ".csv", url) + "?open=true"; | |
if (shared_1.store.hasExcel) { | |
downloadUrl += '&start=excel'; | |
} | |
return [4 /*yield*/, fetch(downloadUrl)]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Results.prototype.open = function (format) { | |
return __awaiter(this, void 0, void 0, function () { | |
var url; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
url = this.createUrl(format); | |
return [4 /*yield*/, shared_1.openUrl(url)]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Results.prototype.mounted = function () { | |
return __awaiter(this, void 0, void 0, function () { | |
var _this = this; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
shared_1.bus.$on('settings', function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: return [4 /*yield*/, this.reset()]; | |
case 1: return [2 /*return*/, _a.sent()]; | |
} | |
}); }); }); | |
return [4 /*yield*/, this.reset()]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Results.prototype.humanize = function (s) { return client_1.humanize(s); }; | |
Results.prototype.renderValue = function (o) { | |
return Array.isArray(o) | |
? o.join(', ') | |
: typeof o == "undefined" | |
? "" | |
: typeof o == "object" | |
? JSON.stringify(o) | |
: o + ""; | |
}; | |
Results.prototype.getField = function (o, name) { return client_1.getField(o, name); }; | |
Results.prototype.getLink = function (o, name) { | |
var config = shared_1.store.dbConfigs[this.db]; | |
var fnLink = config && config.links && config.links[this.table] && config.links[this.table][name]; | |
return fnLink && fnLink(client_1.getField(o, name)); | |
}; | |
Results.prototype.setOrderBy = function (field) { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
if (this.orderBy == field) { | |
this.orderBy = '-' + field; | |
} | |
else if (this.orderBy == '-' + field) { | |
this.orderBy = ''; | |
} | |
else { | |
this.orderBy = field; | |
} | |
return [4 /*yield*/, this.search()]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
}; | |
Results.prototype.helpFilters = function () { | |
return "Search Filters:\n Use '=null' or '!=null' to search NULL columns\n Use '<= < > >= <> !=' prefix to search with that operator\n Use ',' suffix to perform an IN(values) search on integers\n Use '%' prefix or suffix to perform a LIKE wildcard search\n Use '=' prefix to perform an exact coerced search\nOtherwise a 'string equality' search is performed"; | |
}; | |
__decorate([ | |
vue_property_decorator_1.Prop() | |
], Results.prototype, "db", void 0); | |
__decorate([ | |
vue_property_decorator_1.Prop() | |
], Results.prototype, "table", void 0); | |
__decorate([ | |
vue_property_decorator_1.Watch('$route', { immediate: true, deep: true }) | |
], Results.prototype, "onUrlChange", null); | |
Results = __decorate([ | |
vue_property_decorator_1.Component({ template: "<div>\n <div v-if=\"!loading\" class=\"main-query text-nowrap\">\n <span class=\"btn svg svg-fields svg-2x\" title=\"View Columns\" @click=\"showSelectColumns=!showSelectColumns\"></span>\n <button class=\"btn first-link svg-2x\" :disabled=\"skip==0\" title=\"<< first\" @click=\"viewNext(-total)\"></button>\n <button class=\"btn left-link svg-2x\" :disabled=\"skip==0\" title=\"< previous\" @click=\"viewNext(-100)\"></button>\n <button class=\"btn right-link svg-2x\" :disabled=\"results.length < take\" title=\"next >\" @click=\"viewNext(100)\"></button>\n <button class=\"btn last-link svg-2x\" :disabled=\"results.length < take\" title=\"last >>\" @click=\"viewNext(total)\"></button>\n <span class=\"px-1 results-label\">Showing Results {{skip+1}} - {{min(skip + results.length,total)}} <span v-if=\"total!=null\">of {{total}}</span></span>\n <button v-if=\"dirty\" class=\"btn svg-clear svg-lg\" @click=\"clear()\" title=\"reset query\"></button>\n <button v-if=\"store.hasExcel\" class=\"btn btn-outline-success btn-sm btn-compact\" @click=\"openCsv()\" \n :title=\"store.hasExcel ? 'Open in Excel' : 'Open CSV'\"><i class=\"svg-md svg-excel\"></i>{{store.hasExcel ? 'excel' : 'csv' }}</button>\n <span class=\"btn btn-sm px-1\" @click=\"open('html')\"><i class=\"svg-md svg-external-link\"></i> html</span>\n <span class=\"btn btn-sm px-0\" @click=\"open('csv')\"><i class=\"svg-md svg-external-link\"></i> csv</span>\n <span class=\"btn btn-sm pl-1\" @click=\"open('json')\"><i class=\"svg-md svg-external-link\"></i> json</span>\n </div>\n <div v-else class=\"loading-query\">\n <span class=\"svg svg-loading svg-2x ml-1\"></span>Loading {{ this.columns?.length ? 'results' : 'schema' }}... \n </div>\n <div v-if=\"showSelectColumns\">\n <select-columns :columns=\"columns\" v-model=\"fields\" @done=\"handleSelectColumns($event)\" />\n </div>\n <table class=\"results\">\n <thead><tr class=\"noselect\">\n <th v-for=\"f in fieldNames\" :key=\"f\" @click=\"setOrderBy(f)\" class=\"th-link\">\n <div class=\"text-nowrap\">\n {{ humanize(f) }}\n <span v-if=\"orderBy==f\" class=\"svg svg-chevron-up svg-md align-top\"></span>\n <span v-else-if=\"orderBy=='-'+f\" class=\"svg svg-chevron-down svg-md align-top\"></span>\n </div>\n </th>\n </tr></thead>\n <tbody>\n <tr class=\"filters\">\n <td v-for=\"(f,j) in fieldNames\">\n <input type=\"text\" v-model=\"filters[f]\" @keydown.enter.stop=\"filterSearch()\">\n <span v-if=\"j==fieldNames.length-1\" style=\"margin:0 0 0 -23px;\"><i class=\"svg svg-btn svg-filter svg-md\" :title=\"helpFilters()\" /></span>\n </td>\n </tr>\n <template v-for=\"(r,i) in results\">\n <tr :key=\"i\">\n <td v-for=\"(f,j) in fieldNames\" :key=\"j\" :title=\"renderValue(getField(r,f))\">\n <span v-if=\"j == 0 && rowComponent\" :class=\"rowComponentClass(i)\" @click=\"toggleRowComponent(i)\"></span>\n <format :value=\"getField(r,f)\" :href=\"getLink(r,f)\" />\n </td>\n </tr>\n <tr v-if=\"showRowComponent(i)\">\n <td class=\"row-component\" :colspan=\"fieldNames.length\">\n <component :is=\"rowComponent\" :db=\"db\" :table=\"table\" :row=\"r\" :columns=\"columns\"></component>\n </td> \n </tr>\n </template>\n </tbody>\n </table>\n <error-view :responseStatus=\"responseStatus\" />\n</div>", | |
}) | |
], Results); | |
return Results; | |
}(vue_1.default)); | |
exports.Results = Results; | |
exports.default = Results; | |
vue_1.default.component('results', Results); | |
; | |
})(); | |
(function(){ | |
"use strict"; | |
var __extends = (this && this.__extends) || (function () { | |
var extendStatics = Object.setPrototypeOf || | |
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | |
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | |
return function (d, b) { | |
extendStatics(d, b); | |
function __() { this.constructor = d; } | |
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | |
}; | |
})(); | |
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | |
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; | |
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); | |
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | |
return c > 3 && r && Object.defineProperty(target, key, r), r; | |
}; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
var vue_1 = require("vue"); | |
var vue_property_decorator_1 = require("vue-property-decorator"); | |
var SelectColumns = /** @class */ (function (_super) { | |
__extends(SelectColumns, _super); | |
function SelectColumns() { | |
var _this = _super !== null && _super.apply(this, arguments) || this; | |
_this.selectedColumns = []; | |
return _this; | |
} | |
SelectColumns.prototype.mounted = function () { | |
this.selectedColumns = this.value; | |
this.$nextTick(function () { return document.querySelector('.modal') ? .focus() : ; }); | |
}; | |
SelectColumns.prototype.onInputValues = function (e) { | |
return this.selectedColumns; | |
}; | |
__decorate([ | |
vue_property_decorator_1.Prop() | |
], SelectColumns.prototype, "columns", void 0); | |
__decorate([ | |
vue_property_decorator_1.Prop({ default: function () { return ([]); } }) | |
], SelectColumns.prototype, "value", void 0); | |
__decorate([ | |
vue_property_decorator_1.Emit('input') | |
], SelectColumns.prototype, "onInputValues", null); | |
SelectColumns = __decorate([ | |
vue_property_decorator_1.Component({ template: "<div class=\"modal\" tabindex=\"-1\" role=\"dialog\" @keyup.esc=\"$emit('done')\" style=\"display:block;background:rgba(0,0,0,.25)\">\n <div class=\"modal-dialog\" role=\"document\" style=\"margin-top:120px\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title noselect\">\n Column Preferences\n </h5>\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\" @click=\"$emit('done')\">\n <span aria-hidden=\"true\">×</span>\n </button>\n </div>\n <div class=\"modal-body ml-2\">\n <div class=\"form-check\">\n <input class=\"form-check-input\" type=\"radio\" name=\"exampleRadios\" id=\"allColumns\" :checked=\"selectedColumns.length==0\" \n @click=\"selectedColumns=[]\" @change=\"onInputValues\">\n <label class=\"form-check-label noselect\" for=\"allColumns\">View all columns</label>\n </div>\n <hr>\n <div v-for=\"c in columns\" :key=\"c.columnName\" class=\"form-check\">\n <input class=\"form-check-input\" type=\"checkbox\" :id=\"c.columnName\" :value=\"c.columnName\" v-model=\"selectedColumns\" @change=\"onInputValues\">\n <label class=\"form-check-label noselect\" :for=\"c.columnName\">{{c.columnName}}</label>\n </div>\n <div class=\"form-group text-right\">\n <span class=\"btn btn-link\" @click=\"$emit('done')\">Close</span>\n <button class=\"btn btn-primary\" @click=\"$emit('done')\">Done</button>\n </div>\n </div>\n </div>\n </div>\n</div>", | |
}) | |
], SelectColumns); | |
return SelectColumns; | |
}(vue_1.default)); | |
vue_1.default.component('select-columns', SelectColumns); | |
; | |
})(); | |
(function(){ | |
"use strict"; | |
var __extends = (this && this.__extends) || (function () { | |
var extendStatics = Object.setPrototypeOf || | |
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | |
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | |
return function (d, b) { | |
extendStatics(d, b); | |
function __() { this.constructor = d; } | |
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | |
}; | |
})(); | |
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | |
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; | |
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); | |
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | |
return c > 3 && r && Object.defineProperty(target, key, r), r; | |
}; | |
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | |
return new (P || (P = Promise))(function (resolve, reject) { | |
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | |
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | |
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | |
step((generator = generator.apply(thisArg, _arguments || [])).next()); | |
}); | |
}; | |
var __generator = (this && this.__generator) || function (thisArg, body) { | |
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | |
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | |
function verb(n) { return function (v) { return step([n, v]); }; } | |
function step(op) { | |
if (f) throw new TypeError("Generator is already executing."); | |
while (_) try { | |
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; | |
if (y = 0, t) op = [0, t.value]; | |
switch (op[0]) { | |
case 0: case 1: t = op; break; | |
case 4: _.label++; return { value: op[1], done: false }; | |
case 5: _.label++; y = op[1]; op = [0]; continue; | |
case 7: op = _.ops.pop(); _.trys.pop(); continue; | |
default: | |
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | |
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | |
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | |
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | |
if (t[2]) _.ops.pop(); | |
_.trys.pop(); continue; | |
} | |
op = body.call(thisArg, _); | |
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | |
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | |
} | |
}; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
var vue_property_decorator_1 = require("vue-property-decorator"); | |
var shared_1 = require("../../shared"); | |
var Viewer = /** @class */ (function (_super) { | |
__extends(Viewer, _super); | |
function Viewer() { | |
var _this = _super !== null && _super.apply(this, arguments) || this; | |
_this.txtFilter = ''; | |
_this.results = []; | |
_this.loading = false; | |
_this.responseStatus = null; | |
return _this; | |
} | |
Object.defineProperty(Viewer.prototype, "store", { | |
get: function () { return shared_1.store; }, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(Viewer.prototype, "db", { | |
get: function () { return this.$route.params.db; }, | |
enumerable: true, | |
configurable: true | |
}); | |
Object.defineProperty(Viewer.prototype, "table", { | |
get: function () { return this.$route.params.table; }, | |
enumerable: true, | |
configurable: true | |
}); | |
Viewer.prototype.filtered = function (tables) { | |
var _this = this; | |
return this.txtFilter | |
? tables.filter(function (x) { return x.toLowerCase().indexOf(_this.txtFilter.toLowerCase()) >= 0; }) | |
: tables; | |
}; | |
Viewer.prototype.link = function (d, t) { return "/" + d + "/" + t; }; | |
Viewer.prototype.tableName = function (db, table) { | |
var config = shared_1.store.dbConfigs[db]; | |
return config && config.tableName ? config.tableName(table) ? ? table : table : : ; | |
}; | |
Viewer.prototype.mounted = function () { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
return [2 /*return*/]; | |
}); | |
}); | |
}; | |
Viewer.prototype.submit = function () { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
return [2 /*return*/]; | |
}); | |
}); | |
}; | |
__decorate([ | |
vue_property_decorator_1.Prop({ default: '' }) | |
], Viewer.prototype, "name", void 0); | |
Viewer = __decorate([ | |
vue_property_decorator_1.Component({ template: "<section id=\"home\" class=\"grid-layout\">\n <header id=\"header\">\n <h1>\n <nav class=\"site-breadcrumbs\">\n <ol class=\"breadcrumb\">\n <li class=\"breadcrumb-item\">\n <router-link to=\"/\"><i class=\"home-link svg-3x mb-1\" title=\"home\" /></router-link>\n </li>\n <li v-if=\"db\" class=\"breadcrumb-item\">{{db}}</li>\n <li v-if=\"table\" class=\"breadcrumb-item active\">{{table}}</li>\n <li v-if=\"!db && !table\" class=\"breadcrumb-item\">Select Table</li>\n <li v-if=\"loading\"><i class=\"svg-loading svg-lg ml-2 mb-1\" title=\"loading...\" /></li>\n </ol>\n </nav>\n </h1>\n <h1 v-else-if=\"loading\">\n <i class=\"fab fa-loading\"></i>\n Loading...\n </h1>\n <div v-else-if=\"responseStatus\">\n <error-summary :responseStatus=\"responseStatus\" />\n </div>\n </header>\n \n <nav id=\"left\">\n <div id=\"nav-filter\">\n <i v-if=\"txtFilter\" class=\"text-close\" style=\"position:absolute;margin:0 0 0 215px;\" title=\"clear\" @click=\"txtFilter=''\"></i>\n <v-input v-model=\"txtFilter\" id=\"txtFilter\" placeholder=\"filter\" inputClass=\"form-control\" />\n </div>\n <div id=\"sidebar\" class=\"\">\n <div>\n <template v-for=\"(tables,d) in store.tables\">\n <div v-if=\"filtered(tables).length > 0\" class=\"ml-1 mt-2\">\n <h4>\n <i class=\"svg-db svg-2x\"></i>\n {{d}}\n </h4>\n <div v-for=\"t in filtered(tables)\" :key=\"t\" :class=\"['datamodel',{selected:t==table}]\" :title=\"t\">\n <router-link class=\"ml-3\" :to=\"link(d,t)\">{{tableName(d,t)}}</router-link>\n <span v-if=\"store.getColumnTotal(d,t) != null\" class=\"text-muted\">({{store.getColumnTotal(d,t)}})</span>\n </div>\n </div>\n </template> \n </div>\n </div>\n </nav>\n \n <main v-if=\"db && table\">\n <div v-if=\"!responseStatus\" class=\"main-container\">\n <results :db=\"db\" :table=\"table\" />\n </div>\n <div v-else><error-view :responseStatus=\"responseStatus\" class=\"mt-5\" /></div>\n </main>\n \n </section>", | |
}) | |
], Viewer); | |
return Viewer; | |
}(vue_property_decorator_1.Vue)); | |
exports.Viewer = Viewer; | |
exports.default = Viewer; | |
vue_property_decorator_1.Vue.component('viewer', Viewer); | |
; | |
})(); | |
(function(){ | |
"use strict"; | |
var __extends = (this && this.__extends) || (function () { | |
var extendStatics = Object.setPrototypeOf || | |
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | |
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | |
return function (d, b) { | |
extendStatics(d, b); | |
function __() { this.constructor = d; } | |
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | |
}; | |
})(); | |
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | |
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; | |
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); | |
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | |
return c > 3 && r && Object.defineProperty(target, key, r), r; | |
}; | |
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | |
return new (P || (P = Promise))(function (resolve, reject) { | |
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | |
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | |
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | |
step((generator = generator.apply(thisArg, _arguments || [])).next()); | |
}); | |
}; | |
var __generator = (this && this.__generator) || function (thisArg, body) { | |
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | |
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | |
function verb(n) { return function (v) { return step([n, v]); }; } | |
function step(op) { | |
if (f) throw new TypeError("Generator is already executing."); | |
while (_) try { | |
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; | |
if (y = 0, t) op = [0, t.value]; | |
switch (op[0]) { | |
case 0: case 1: t = op; break; | |
case 4: _.label++; return { value: op[1], done: false }; | |
case 5: _.label++; y = op[1]; op = [0]; continue; | |
case 7: op = _.ops.pop(); _.trys.pop(); continue; | |
default: | |
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | |
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | |
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | |
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | |
if (t[2]) _.ops.pop(); | |
_.trys.pop(); continue; | |
} | |
op = body.call(thisArg, _); | |
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | |
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | |
} | |
}; | |
var _this = this; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
var vue_1 = require("vue"); | |
var client_1 = require("@servicestack/client"); | |
exports.client = new client_1.JsonServiceClient('/'); | |
var desktop_1 = require("@servicestack/desktop"); | |
var vue_property_decorator_1 = require("vue-property-decorator"); | |
var RowComponent = /** @class */ (function (_super) { | |
__extends(RowComponent, _super); | |
function RowComponent() { | |
return _super !== null && _super.apply(this, arguments) || this; | |
} | |
__decorate([ | |
vue_property_decorator_1.Prop() | |
], RowComponent.prototype, "db", void 0); | |
__decorate([ | |
vue_property_decorator_1.Prop() | |
], RowComponent.prototype, "table", void 0); | |
__decorate([ | |
vue_property_decorator_1.Prop() | |
], RowComponent.prototype, "row", void 0); | |
__decorate([ | |
vue_property_decorator_1.Prop() | |
], RowComponent.prototype, "columns", void 0); | |
return RowComponent; | |
}(vue_1.default)); | |
exports.RowComponent = RowComponent; | |
var rowComponents = {}; | |
function getRowComponent(db, table) { | |
db = db.toLowerCase(); | |
table = table.toLowerCase(); | |
return rowComponents[db] && rowComponents[db][table] || null; | |
} | |
exports.getRowComponent = getRowComponent; | |
function registerRowComponent(db, table, constructor, component) { | |
vue_1.default.component(component, constructor); | |
db = db.toLowerCase(); | |
table = table.toLowerCase(); | |
if (!rowComponents[db]) | |
rowComponents[db] = {}; | |
rowComponents[db][table] = component; | |
} | |
exports.registerRowComponent = registerRowComponent; | |
var Roles; | |
(function (Roles) { | |
Roles["Admin"] = "Admin"; | |
})(Roles = exports.Roles || (exports.Roles = {})); | |
exports.store = { | |
debug: global.CONFIG.debug, | |
desktop: global.CONFIG.desktop, | |
hasExcel: global.CONFIG.hasExcel, | |
namedDbs: global.CONFIG.namedDbs, | |
tables: global.CONFIG.tables, | |
totals: {}, | |
columns: {}, | |
getColumnTotal: function (db, table) { | |
var ret = this.totals[db] && this.totals[db][table]; | |
return ret != null ? ret : null; | |
}, | |
getColumnSchemas: function (db, table) { | |
return this.columns[db] && this.columns[db][table] || []; | |
}, | |
dbConfigs: {}, | |
}; | |
function dbConfig(db, config) { | |
if (db != 'main' && exports.store.namedDbs.indexOf(db) < 0) | |
return; | |
if (config.showTables && config.showTables.length > 0) { | |
vue_1.default.set(exports.store.tables, db, config.showTables); | |
} | |
if (config.rowComponents) { | |
for (var _i = 0, _a = Object.keys(config.rowComponents); _i < _a.length; _i++) { | |
var table = _a[_i]; | |
registerRowComponent(db, table, config.rowComponents[table], table); | |
} | |
} | |
vue_1.default.set(exports.store.dbConfigs, db, config); | |
} | |
exports.dbConfig = dbConfig; | |
exports.splitPascalCase = function (table) { | |
return client_1.humanize(table).split(' ').map(client_1.toPascalCase).join(' '); | |
}; | |
var EventBus = /** @class */ (function (_super) { | |
__extends(EventBus, _super); | |
function EventBus() { | |
var _this = _super !== null && _super.apply(this, arguments) || this; | |
_this.store = exports.store; | |
return _this; | |
} | |
return EventBus; | |
}(vue_1.default)); | |
exports.bus = new EventBus({ data: exports.store }); | |
var settings = {}; | |
var settingsLoaded = false; | |
function loadSettings() { | |
return __awaiter(this, void 0, void 0, function () { | |
var settingsJson, _a, e_1; | |
return __generator(this, function (_b) { | |
switch (_b.label) { | |
case 0: | |
_b.trys.push([0, 4, 5, 6]); | |
if (!exports.store.desktop) return [3 /*break*/, 2]; | |
return [4 /*yield*/, desktop_1.desktopTextFile('settings.json')]; | |
case 1: | |
_a = _b.sent(); | |
return [3 /*break*/, 3]; | |
case 2: | |
_a = localStorage.getItem('settings.json'); | |
_b.label = 3; | |
case 3: | |
settingsJson = _a; | |
if (settingsJson) { | |
settings = JSON.parse(settingsJson) || {}; | |
log('loaded', settings); | |
exports.bus.$emit('settings'); | |
} | |
return [3 /*break*/, 6]; | |
case 4: | |
e_1 = _b.sent(); | |
log("Could not retrieve desktopTextFile 'settings.json'", e_1); | |
return [3 /*break*/, 6]; | |
case 5: | |
settingsLoaded = true; | |
return [7 /*endfinally*/]; | |
case 6: return [2 /*return*/]; | |
} | |
}); | |
}); | |
} | |
exports.loadSettings = loadSettings; | |
function saveSettings() { | |
return __awaiter(this, void 0, void 0, function () { | |
var settingsJson, e_2; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
_a.trys.push([0, 4, , 5]); | |
settingsJson = JSON.stringify(settings); | |
if (!exports.store.desktop) return [3 /*break*/, 2]; | |
return [4 /*yield*/, desktop_1.desktopSaveTextFile('settings.json', settingsJson)]; | |
case 1: | |
_a.sent(); | |
return [3 /*break*/, 3]; | |
case 2: | |
localStorage.setItem('settings.json', settingsJson); | |
_a.label = 3; | |
case 3: return [3 /*break*/, 5]; | |
case 4: | |
e_2 = _a.sent(); | |
log("Could not retrieve saveDesktopTextFile 'settings.json'", e_2); | |
return [3 /*break*/, 5]; | |
case 5: return [2 /*return*/]; | |
} | |
}); | |
}); | |
} | |
exports.saveSettings = saveSettings; | |
function getTableSettings(db, table) { | |
return settings[db] && settings[db][table] || null; | |
} | |
exports.getTableSettings = getTableSettings; | |
function saveTableSettings(db, table, tableSettings) { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
if (!settingsLoaded) | |
return [2 /*return*/]; | |
if (!settings[db]) { | |
settings[db] = {}; | |
} | |
if (tableSettings) { | |
settings[db][table] = tableSettings; | |
} | |
else { | |
delete settings[db][table]; | |
} | |
return [4 /*yield*/, saveSettings()]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
} | |
exports.saveTableSettings = saveTableSettings; | |
function log() { | |
var o = []; | |
for (var _i = 0; _i < arguments.length; _i++) { | |
o[_i] = arguments[_i]; | |
} | |
if (exports.store.debug) | |
console.log.apply(console, arguments); | |
return o; | |
} | |
exports.log = log; | |
exports.dateFmtHMS = function (d) { | |
if (d === void 0) { d = new Date(); } | |
return "" + (d.getFullYear() - 2000) + client_1.padInt(d.getMonth() + 1) + client_1.padInt(d.getDate()) + "-" + client_1.padInt(d.getHours()) + client_1.padInt(d.getMinutes()) + client_1.padInt(d.getSeconds()); | |
}; | |
function openUrl(url) { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
if (!exports.store.desktop) return [3 /*break*/, 2]; | |
return [4 /*yield*/, desktop_1.evaluateCode("openUrl('" + url + "')")]; | |
case 1: | |
_a.sent(); | |
return [3 /*break*/, 3]; | |
case 2: | |
window.open(url); | |
_a.label = 3; | |
case 3: return [2 /*return*/]; | |
} | |
}); | |
}); | |
} | |
exports.openUrl = openUrl; | |
function exec(c, fn) { | |
return __awaiter(this, void 0, void 0, function () { | |
var e_3; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
_a.trys.push([0, 2, 3, 4]); | |
c.loading = true; | |
c.responseStatus = null; | |
return [4 /*yield*/, fn()]; | |
case 1: return [2 /*return*/, _a.sent()]; | |
case 2: | |
e_3 = _a.sent(); | |
log(e_3); | |
c.responseStatus = e_3.responseStatus || (typeof e_3 == 'string' ? { errorCode: 'Error', message: e_3 } : null) || e_3; | |
c.$emit('error', c.responseStatus); | |
return [3 /*break*/, 4]; | |
case 3: | |
c.loading = false; | |
return [7 /*endfinally*/]; | |
case 4: return [2 /*return*/]; | |
} | |
}); | |
}); | |
} | |
exports.exec = exec; | |
function loadTable(c, db, table) { | |
return __awaiter(this, void 0, void 0, function () { | |
var _this = this; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
if (exports.store.getColumnSchemas(db, table).length > 0) | |
return [2 /*return*/]; | |
return [4 /*yield*/, exec(c, function () { return __awaiter(_this, void 0, void 0, function () { | |
var r, json, obj; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: return [4 /*yield*/, fetch("/db/" + db + "/" + table + "/meta?format=json")]; | |
case 1: | |
r = _a.sent(); | |
return [4 /*yield*/, r.text()]; | |
case 2: | |
json = _a.sent(); | |
if (json) { | |
obj = JSON.parse(json); | |
if (!exports.store.columns[db]) | |
vue_1.default.set(exports.store.columns, db, {}); | |
vue_1.default.set(exports.store.columns[db], table, obj); | |
} | |
return [2 /*return*/]; | |
} | |
}); | |
}); })]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); | |
}); | |
} | |
exports.loadTable = loadTable; | |
function sharpData(db, table, args) { | |
return __awaiter(this, void 0, void 0, function () { | |
var url; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
url = "/db/" + db + "/" + table + "?format=json"; | |
if (args) { | |
url = client_1.appendQueryString(url, args); | |
} | |
return [4 /*yield*/, fetch(url)]; | |
case 1: return [4 /*yield*/, (_a.sent()).json()]; | |
case 2: return [2 /*return*/, _a.sent()]; | |
} | |
}); | |
}); | |
} | |
exports.sharpData = sharpData; | |
vue_1.default.filter('upper', function (value) { | |
return value ? .toUpperCase() : ; | |
}); | |
vue_1.default.filter('json', function (value) { | |
return value && JSON.stringify(value); | |
}); | |
(function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: return [4 /*yield*/, loadSettings()]; | |
case 1: | |
_a.sent(); | |
return [2 /*return*/]; | |
} | |
}); }); })(); | |
(function () { return __awaiter(_this, void 0, void 0, function () { | |
var _loop_1, _a, _b, _i, db; | |
return __generator(this, function (_c) { | |
switch (_c.label) { | |
case 0: | |
_loop_1 = function (db) { | |
var r, json, kvps, columnTotals_1, e_4; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
_a.trys.push([0, 3, , 4]); | |
return [4 /*yield*/, fetch("/db/" + db + "/totals?format=json")]; | |
case 1: | |
r = _a.sent(); | |
return [4 /*yield*/, r.text()]; | |
case 2: | |
json = _a.sent(); | |
if (json) { | |
kvps = JSON.parse(json); | |
columnTotals_1 = {}; | |
kvps.forEach(function (x) { | |
columnTotals_1[x.key] = x.value; | |
}); | |
vue_1.default.set(exports.store.totals, db, columnTotals_1); | |
} | |
return [3 /*break*/, 4]; | |
case 3: | |
e_4 = _a.sent(); | |
log("Can't retrieve totals for '" + db + "':", e_4); | |
return [3 /*break*/, 4]; | |
case 4: return [2 /*return*/]; | |
} | |
}); | |
}; | |
_a = []; | |
for (_b in exports.store.tables) | |
_a.push(_b); | |
_i = 0; | |
_c.label = 1; | |
case 1: | |
if (!(_i < _a.length)) return [3 /*break*/, 4]; | |
db = _a[_i]; | |
return [5 /*yield**/, _loop_1(db)]; | |
case 2: | |
_c.sent(); | |
_c.label = 3; | |
case 3: | |
_i++; | |
return [3 /*break*/, 1]; | |
case 4: return [2 /*return*/]; | |
} | |
}); | |
}); })(); | |
(function () { return __awaiter(_this, void 0, void 0, function () { | |
var _a, e_5; | |
return __generator(this, function (_b) { | |
switch (_b.label) { | |
case 0: | |
_b.trys.push([0, 2, , 3]); | |
_a = exports.store; | |
return [4 /*yield*/, desktop_1.desktopInfo()]; | |
case 1: | |
_a.desktop = _b.sent(); | |
log('In Desktop app:', exports.store.desktop); | |
return [3 /*break*/, 3]; | |
case 2: | |
e_5 = _b.sent(); | |
log("Not in Desktop app:", e_5); | |
return [3 /*break*/, 3]; | |
case 3: return [2 /*return*/]; | |
} | |
}); | |
}); })(); | |
; | |
})(); | |
(function(){ | |
"use strict";var routes;Object.defineProperty(exports,"__esModule",{value:!0});var vue_1=require("vue"),vue_router_1=require("vue-router"),vue_2=require("@servicestack/vue"),Viewer_1=require("../components/Viewer"),Routes;(function(n){n.Home="/";n.ViewTable="/:db/:table";n.Forbidden="/forbidden"})(Routes=exports.Routes||(exports.Routes={}));vue_1.default.use(vue_router_1.default);routes=[{path:Routes.Home,component:Viewer_1.Viewer},{path:Routes.ViewTable,component:Viewer_1.Viewer},{path:Routes.Forbidden,component:vue_2.Forbidden},{path:"*",redirect:"/"},];exports.router=new vue_router_1.default({mode:"history",linkActiveClass:"active",routes:routes});exports.default=exports.router;exports.redirect=function(n){var t=n.indexOf("://")>=0;t?location.href=n:exports.router.push({path:n})}; | |
})(); | |
(function(){ | |
"use strict";var __extends=this&&this.__extends||function(){var n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,t){n.__proto__=t}||function(n,t){for(var i in t)t.hasOwnProperty(i)&&(n[i]=t[i])};return function(t,i){function r(){this.constructor=t}n(t,i);t.prototype=i===null?Object.create(i):(r.prototype=i.prototype,new r)}}(),__decorate=this&&this.__decorate||function(n,t,i,r){var f=arguments.length,u=f<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,i):r,e,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")u=Reflect.decorate(n,t,i,r);else for(o=n.length-1;o>=0;o--)(e=n[o])&&(u=(f<3?e(u):f>3?e(t,i,u):e(t,i))||u);return f>3&&u&&Object.defineProperty(t,i,u),u};Object.defineProperty(exports,"__esModule",{value:!0});var vue_1=require("vue"),vue_property_decorator_1=require("vue-property-decorator"),shared_1=require("./shared"),App=function(n){function t(){return n!==null&&n.apply(this,arguments)||this}return __extends(t,n),Object.defineProperty(t.prototype,"store",{get:function(){return shared_1.store},enumerable:!0,configurable:!0}),__decorate([vue_property_decorator_1.Component({template:"<div>\n <router-view><\/router-view>\n <\/div>"})],t)}(vue_1.default);exports.App=App;exports.default=App; | |
})(); | |
(function(){ | |
"use strict";var __extends=this&&this.__extends||function(){var n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,t){n.__proto__=t}||function(n,t){for(var i in t)t.hasOwnProperty(i)&&(n[i]=t[i])};return function(t,i){function r(){this.constructor=t}n(t,i);t.prototype=i===null?Object.create(i):(r.prototype=i.prototype,new r)}}(),__decorate=this&&this.__decorate||function(n,t,i,r){var f=arguments.length,u=f<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,i):r,e,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")u=Reflect.decorate(n,t,i,r);else for(o=n.length-1;o>=0;o--)(e=n[o])&&(u=(f<3?e(u):f>3?e(t,i,u):e(t,i))||u);return f>3&&u&&Object.defineProperty(t,i,u),u},vue_property_decorator_1,ErrorView;Object.defineProperty(exports,"__esModule",{value:!0});vue_property_decorator_1=require("vue-property-decorator");ErrorView=function(n){function t(){var t=n!==null&&n.apply(this,arguments)||this;return t.showStackTrace=!1,t}return __extends(t,n),__decorate([vue_property_decorator_1.Prop({"default":null})],t.prototype,"responseStatus",void 0),__decorate([vue_property_decorator_1.Component({template:'<div v-if="responseStatus" class="noplugin-error alert alert-danger mt-3 mr-3">\n <div>{{responseStatus.errorCode}}: {{responseStatus.message}}<\/div>\n <div v-if="responseStatus.stackTrace">\n <button v-if="!showStackTrace" class="btn btn-link" style="margin-left: -1em" @click="showStackTrace=true">\n <i class="svg-chevron-right svg-lg mb-1" title="expand" />StackTrace<\/button>\n <div v-if="showStackTrace" class="stacktrace">{{responseStatus.stackTrace}}<\/div>\n <\/div>\n<\/div>'})],t)}(vue_property_decorator_1.Vue);exports.ErrorView=ErrorView;exports.default=ErrorView;vue_property_decorator_1.Vue.component("error-view",ErrorView); | |
})(); | |
(function(){ | |
"use strict";var __extends=this&&this.__extends||function(){var n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,t){n.__proto__=t}||function(n,t){for(var i in t)t.hasOwnProperty(i)&&(n[i]=t[i])};return function(t,i){function r(){this.constructor=t}n(t,i);t.prototype=i===null?Object.create(i):(r.prototype=i.prototype,new r)}}(),__decorate=this&&this.__decorate||function(n,t,i,r){var f=arguments.length,u=f<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,i):r,e,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")u=Reflect.decorate(n,t,i,r);else for(o=n.length-1;o>=0;o--)(e=n[o])&&(u=(f<3?e(u):f>3?e(t,i,u):e(t,i))||u);return f>3&&u&&Object.defineProperty(t,i,u),u};Object.defineProperty(exports,"__esModule",{value:!0});var vue_property_decorator_1=require("vue-property-decorator"),client_1=require("@servicestack/client"),show=function(n){return typeof n!="string"||n.substr(0,2)!=="__"},keyFmt=function(n){return client_1.humanize(client_1.toPascalCase(n))},uniqueKeys=function(n){for(var r,t,u={},i=0,f=n.length;i<f;i++){r=n[i];for(t in r)r.hasOwnProperty(t)&&show(t)&&(u[t]=t)}return u},valueFmt=function(n,t,i){return i},num=function(n){return n},date=function(n){return client_1.toDate(n)},pad=function(n){return n<10?"0"+n:n},dmft=function(n){return n.getFullYear()+"/"+pad(n.getMonth()+1)+"/"+pad(n.getDate())},str=function(n){return n.substr(0,6)==="/Date("?dmft(date(n)):n},obj=function(n){return"<dl>\n "+Object.keys(n).filter(show).map(function(t){return'<dt class="ib">'+keyFmt(t)+"<\/dt><dd>"+valueFmt(t,n[t],val(n[t]))+"<\/dd>"}).join("")+"\n <\/dl>"},arr=function(n){if(typeof n[0]=="string"||typeof n[0]=="number")return"<span>"+n.join(", ")+"<\/span>";var t=uniqueKeys(n);return"\n <table>\n <thead>\n <tr>\n "+Object.keys(t).map(function(n){return"<th><b><\/b>"+keyFmt(n)+"<\/th>"}).join("")+"\n <\/tr>\n <\/thead>\n <tbody>\n "+n.map(function(n){return"<tr>\n "+Object.keys(t).filter(show).map(function(t){return"<td>"+valueFmt(t,n[t],val(n[t]))+"<\/td>"}).join("")+"\n <\/tr>"}).join("")+"\n <\/tbody>\n <\/table>"},val=function(n,t){return(t&&(valueFmt=t),n==null)?"":typeof n=="number"?""+num(n):typeof n=="string"?str(n):typeof n=="boolean"?n?"true":"false":n.length?arr(n):obj(n)},JsonViewer=function(n){function t(){return n!==null&&n.apply(this,arguments)||this}return __extends(t,n),Object.defineProperty(t.prototype,"html",{get:function(){return this.json?val(JSON.parse(this.json)):val(this.value)},enumerable:!0,configurable:!0}),__decorate([vue_property_decorator_1.Prop({"default":null})],t.prototype,"value",void 0),__decorate([vue_property_decorator_1.Prop({"default":null})],t.prototype,"json",void 0),__decorate([vue_property_decorator_1.Component({template:'<div class="jsonviewer">\n <div v-html="html"><\/div>\n <span class="clearfix"><\/span>\n <\/div>'})],t)}(vue_property_decorator_1.Vue);exports.JsonViewer=JsonViewer;exports.default=JsonViewer;vue_property_decorator_1.Vue.component("jsonviewer",JsonViewer); | |
})(); | |
(function(){ | |
"use strict";var vue_1,vue_2;Object.defineProperty(exports,"__esModule",{value:!0});require("./app.scss");require("es6-shim");vue_1=require("vue");vue_2=require("@servicestack/vue");vue_1.default.use(vue_2.default);var App_1=require("./App"),router_1=require("./shared/router"),app=new vue_1.default({el:"#app",render:function(n){return n(App_1.App)},router:router_1.router}); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{ {namedConnection:db} |> if (db && db != 'main') |> useDb }} | |
```code|quiet | |
var ignore = ['db','fields','format','skip','take','orderBy'] | |
var fields = qs.fields ? qs.fields.split(',').map(x => sqlQuote(x)).join(',') : '*' | |
var sql = `SELECT ${fields} FROM ${sqlQuote(table)}` | |
var filters = [] | |
var queryMap = qs.toObjectDictionary().withoutKeys(ignore) | |
#each queryMap.Keys.toList() | |
var search = queryMap[it.sqlVerifyFragment()].sqlVerifyFragment(); | |
#if search == '=null' || search == '!=null' | |
`${sqlQuote(it)} ${search=='=null' ? 'IS' : 'IS NOT'} NULL` |> addTo => filters | |
queryMap[it] = null | |
else if search.startsWith('=') | |
`${sqlQuote(it)} = @${it}` |> addTo => filters | |
queryMap[it] = search.substring(1).coerce() | |
else if search.startsWith('<=') || search.startsWith('>=') || search.startsWith('<>') || search.startsWith('!=') | |
`${sqlQuote(it)} ${search.substring(0,2)} @${it}` |> addTo => filters | |
queryMap[it] = search.substring(2).coerce() | |
else if search.startsWith('<') || search.startsWith('>') | |
`${sqlQuote(it)} ${search.substring(0,1)} @${it}` |> addTo => filters | |
queryMap[it] = search.substring(1).coerce() | |
else if search.endsWith(',') | |
`${sqlQuote(it)} IN (${search.trimEnd(',').split(',').map(i => i.toLong()).join(',')})` |> addTo => filters | |
queryMap[it] = null | |
else if search.startsWith('%') || search.endsWith('%') | |
`${sqlQuote(it).sqlCast('varchar')} LIKE @${it}` |> addTo => filters | |
else | |
`${sqlQuote(it).sqlCast('varchar')} = @${it}` |> addTo => filters | |
/if | |
/each | |
#if !filters.isEmpty() | |
sql = `${sql} WHERE ${filters.join(' AND ')}` | |
/if | |
#if qs.orderBy | |
sql = `${sql} ORDER BY ${sqlOrderByFields(qs.orderBy)}` | |
/if | |
#if qs.skip || qs.take | |
sql = `${sql} ${sqlLimit(qs.skip,qs.take)}` | |
/if | |
sql |> dbSelect(queryMap) |> return | |
``` | |
{{ ifError |> show(sql) }} | |
{{htmlError}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{ {namedConnection:db} |> if (db && db != 'main') |> useDb }} | |
{{ table |> dbColumns |> return }} | |
{{htmlError}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{ {namedConnection:db} |> if (db && db != 'main') |> useDb }} | |
```code|quiet | |
var ignore = ['db','fields','format','orderby','skip','take'] | |
var sql = `SELECT COUNT(*) FROM ${sqlQuote(table)}` | |
var filters = [] | |
var queryMap = qs.toObjectDictionary().withoutKeys(ignore) | |
#each queryMap.Keys.toList() | |
var search = queryMap[it.sqlVerifyFragment()].sqlVerifyFragment(); | |
#if search == '=null' || search == '!=null' | |
`${sqlQuote(it)} ${search=='=null' ? 'IS' : 'IS NOT'} NULL` |> addTo => filters | |
queryMap[it] = null | |
else if search.startsWith('=') | |
`${sqlQuote(it)} = @${it}` |> addTo => filters | |
queryMap[it] = search.substring(1).coerce() | |
else if search.startsWith('<=') || search.startsWith('>=') || search.startsWith('<>') || search.startsWith('!=') | |
`${sqlQuote(it)} ${search.substring(0,2)} @${it}` |> addTo => filters | |
queryMap[it] = search.substring(2).coerce() | |
else if search.startsWith('<') || search.startsWith('>') | |
`${sqlQuote(it)} ${search.substring(0,1)} @${it}` |> addTo => filters | |
queryMap[it] = search.substring(1).coerce() | |
else if search.endsWith(',') | |
`${sqlQuote(it)} IN (${search.trimEnd(',').split(',').map(i => i.toLong()).join(',')})` |> addTo => filters | |
queryMap[it] = null | |
else if search.startsWith('%') || search.endsWith('%') | |
`${sqlQuote(it).sqlCast('varchar')} LIKE @${it}` |> addTo => filters | |
else | |
`${sqlQuote(it).sqlCast('varchar')} = @${it}` |> addTo => filters | |
/if | |
/each | |
#if !filters.isEmpty() | |
sql = `${sql} WHERE ${filters.join(' AND ')}` | |
/if | |
sql |> dbScalar(queryMap) |> return | |
``` | |
{{ ifError |> show(sql) }} | |
{{htmlError}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{ {namedConnection:db} |> if (db && db != 'main') |> useDb }} | |
{{ {live:true} |> dbTableNamesWithRowCounts |> return }} | |
{{htmlError}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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TUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MTwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzI8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NDI8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjMyPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxMy0xMS0xNlQwODoxMToyMzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAyLjIuMTwveG1wOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4Kpcq+GAAAAsFJREFUWAnVl19oj1EYx2f+lxmFpESZ0hrFhfwp2YU/F6zWSq3kwg3SolyQcqGE4krkguTSlUVJwi1Js7mQi9ViYvOn2VjNzPD52u+t0+l3znvO3td+vz312fu+53me83z3/jnn+VVUTBKbGqGzkthdMA964A9MmMUIlbBZcB+aoBo+wlcoSzuJKokWEnkTNkPZmR79G0jE6vgL7sJWKCs7jRpTaHIuwbdgdbmorUXIECQC7eMAPv0zVVBS0wrwBGyB9nUbMVtKqpTi5wKESrjuvD7AaVASa6SqfQd9163ELyqF0jqKjkaKfUn8hH9o8ynaHilUd/w95P7eTmFSCXKZ1tQW6ALfY7d9fcTvgNxMQpvhAZyADaBt1LaFDJyBAbBFua77id0OuZmWIi3iKvgbXsFF2AR2r7CGMfUCLnH2+BdiN0JutoSZesEsJNFP4RAsgMQk/gh8AzPedf6WuBrIzc4yk6/YKfyLjWrrOddX7soxx58RV23kZjpdS/ZPMAvY5+/wH4M5INO7exvsuGLXN4jTN5HZ9BF1QrEi9tgL4nYWKmpHuhyYt7+Qk/nwMLCghKuTugRJY3I+IPczMSshs4U+RvMOP6eqVgPZBTB9xc7vEKOVJpPdI7vY5Gljn8jbXah8PWCOPYXYcR207HQEFHGJ/kHuPtA8j1PmeY0/eWU4jbPlhH8Hl5CQ8RHy94K6KK0Qvpyj+MdlB8jyTRzqG2aebaDt09d9deFXLxFlM4nWkhMqJi1OW6d2o6spcx7EH2XaEtOKx/r1U2YFfPDM3YZvBgSZfrPHdEUxgtWRtYArR/1EPaSaRKrRdU2UdVytnrqwTk+Na/icNh3PYdBEWcWk5V+hxnFPnW58c+GfaSeYDXrB1bZ1QFqBvPxqdBpg0FOzIelWpHgZrAL1nrKkUxq7+n9/tQE8gnWw1FGm/S9DpCdmD6gwqwAAAABJRU5ErkJggg== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{#raw}} | |
<div id="app"> | |
<div class="container"> | |
<div class="row p-4"> | |
<div id="content"> | |
<router-view></router-view> | |
</div> | |
</div> | |
</div> | |
</div> | |
{{/raw}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment