diff --git a/.gitignore b/.gitignore index e4841fd..c29b5e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *egg-info *pyc +/dist/ /.coverage /.mxmake /.vscode diff --git a/js/src/tokens.js b/js/src/tokens.js index dad48a0..fad900c 100644 --- a/js/src/tokens.js +++ b/js/src/tokens.js @@ -13,11 +13,12 @@ export class TokensOverview { this.container = container; this.tokens_elem = $('#tokens-overview', container); this.tokens = $('object.token_qr', this.tokens_elem); - this.tokens_title = $('#tokens-overview-title', container); + this.filter_options = $('#tokens-filter-options', container); + this.create_options = $('#tokens-create-options', container); this.token_settings = this.container.data('token-settings'); // add tokens - this.add_tokens_container = $('.add-tokens', this.tokens_title); + this.add_tokens_container = $('.add-tokens', this.create_options); this.add_tokens_input = $( 'input[name="amount"]', this.add_tokens_container @@ -30,18 +31,18 @@ export class TokensOverview { this.add_tokens_btn.on('click', this.add_tokens); // date filter - this.start = $('input[name="start"]', this.tokens_title) + this.start = $('input[name="start"]', this.filter_options) .addClass('datepicker') .data('date-locale', 'de'); - this.end = $('input[name="end"]', this.tokens_title) + this.end = $('input[name="end"]', this.filter_options) .addClass('datepicker') .data('date-locale', 'de'); - this.filter = $('button[name="filter"]', this.tokens_title); + this.filter = $('button[name="filter"]', this.filter_options); this.filter_tokens = this.filter_tokens.bind(this); this.filter.on('click', this.filter_tokens); // delete tokens - this.delete_tokens_container = $('.delete-tokens', this.tokens_title); + this.delete_tokens_container = $('.delete-tokens', this.create_options); this.delete_tokens_btn = $( 'button[name="delete-tokens"]', this.delete_tokens_container @@ -50,7 +51,7 @@ export class TokensOverview { this.delete_tokens_btn.on('click', this.delete_tokens); this.set_token_size = this.set_token_size.bind(this); - this.size_input = $('input[name="token-size"]', this.tokens_title); + this.size_input = $('input[name="token-size"]', this.filter_options); this.size_input.on('change', this.set_token_size); if (this.tokens.length) { this.original_size = parseInt($(this.tokens[0]).attr('width')); @@ -222,13 +223,13 @@ export class TokenScanner { let input = this._input = $(''); wrapper.append(input); this.elem.append(wrapper); - button.removeClass('inactive').addClass('active'); + button.removeClass('inactive btn-danger').addClass('active btn-success'); input[0].focus(); } else { this._input_wrapper.remove(); this._input_wrapper = null; this._input = null; - button.removeClass('active').addClass('inactive'); + button.removeClass('active btn-success').addClass('inactive btn-danger'); } } diff --git a/js/tests/test_tokens.js b/js/tests/test_tokens.js index 65615ac..f2d2963 100644 --- a/js/tests/test_tokens.js +++ b/js/tests/test_tokens.js @@ -17,35 +17,41 @@ import ts from 'treibstoff'; QUnit.module('TokensOverview', hooks => { let elem, - tokens_title, + tokens_filter, tokens_elem, add_tokens_input, + token_size_input, start_input, end_input; hooks.beforeEach(() => { elem = $('
') .addClass('tokens-overview-container') .appendTo('body'); - tokens_title = $('
') - .appendTo(elem); tokens_elem = $('
') .appendTo(elem); - let token_size_input = $('') - .appendTo(tokens_title); + // filter + tokens_filter = $('
') + .appendTo(elem); + token_size_input = $('') + .appendTo(tokens_filter); + start_input = $('') + .appendTo(tokens_filter); + end_input = $('') + .appendTo(tokens_filter); + // add tokens + let add_tokens = $('
') + .appendTo(elem); let add_tokens_container = $('
') - .appendTo(tokens_title); + .appendTo(add_tokens); add_tokens_input = $('') .appendTo(add_tokens_container); - start_input = $('') - .appendTo(tokens_title); - end_input = $('') - .appendTo(tokens_title); + }); hooks.afterEach(() => { elem.empty().remove(); elem = null; tokens_elem = null; - tokens_title = null; + tokens_filter = null; }); QUnit.test('constructor no tokens', assert => { @@ -120,6 +126,7 @@ QUnit.module('TokensOverview', hooks => { // reset ts ajax ts.ajax.action = original_ts_action; + assert.ok(true) }); QUnit.test('add_tokens', assert => { @@ -331,8 +338,8 @@ QUnit.module('TokenScanner', hooks => { assert.verifySteps(['query_token token-1']); }); - let force_success = false; QUnit.test('query_token', assert => { + let force_success = false; let force_data_success = false; let data_token = false; diff --git a/mx.ini b/mx.ini index bab8b99..6d8c692 100644 --- a/mx.ini +++ b/mx.ini @@ -8,9 +8,6 @@ cs_push = git@github.com:conestack # checkout source packages checkout_packages = true -# feature branch to checkout -feature_branch = master - # main package main-package = -e .[test] @@ -41,7 +38,7 @@ environment = env use = ${settings:checkout_packages} url = ${settings:cs}/odict.git pushurl = ${settings:cs_push}/odict.git -branch = ${settings:feature_branch} +branch = master mxmake-test-path = tests mxmake-source-path = src/odict @@ -49,7 +46,7 @@ mxmake-source-path = src/odict use = ${settings:checkout_packages} url = ${settings:cs}/plumber.git pushurl = ${settings:cs_push}/plumber.git -branch = ${settings:feature_branch} +branch = master extras = test mxmake-test-path = tests mxmake-source-path = src/plumber @@ -62,7 +59,7 @@ mxmake-source-path = src/plumber use = ${settings:checkout_packages} url = ${settings:cs}/node.git pushurl = ${settings:cs_push}/node.git -branch = ${settings:feature_branch} +branch = master mxmake-test-path = src mxmake-source-path = src/node @@ -70,7 +67,7 @@ mxmake-source-path = src/node use = ${settings:checkout_packages} url = ${settings:cs}/node.ext.ugm.git pushurl = ${settings:cs_push}/node.ext.ugm.git -branch = ${settings:feature_branch} +branch = master extras = test mxmake-test-path = src mxmake-source-path = src/node/ext/ugm @@ -83,7 +80,7 @@ mxmake-source-path = src/node/ext/ugm use = ${settings:checkout_packages} url = ${settings:cs}/yafowil.git pushurl = ${settings:cs_push}/yafowil.git -branch = ${settings:feature_branch} +branch = master extras = test mxmake-test-path = src mxmake-source-path = src/yafowil @@ -92,7 +89,7 @@ mxmake-source-path = src/yafowil use = ${settings:checkout_packages} url = ${settings:cs}/yafowil.yaml.git pushurl = ${settings:cs_push}/yafowil.yaml.git -branch = ${settings:feature_branch} +branch = master mxmake-test-path = src mxmake-source-path = src/yafowil/yaml @@ -100,7 +97,7 @@ mxmake-source-path = src/yafowil/yaml use = ${settings:checkout_packages} url = ${settings:cs}/yafowil.webob.git pushurl = ${settings:cs_push}/yafowil.webob.git -branch = ${settings:feature_branch} +branch = master mxmake-test-path = src mxmake-source-path = src/yafowil/webob @@ -108,7 +105,7 @@ mxmake-source-path = src/yafowil/webob use = ${settings:checkout_packages} url = ${settings:cs}/yafowil.bootstrap.git pushurl = ${settings:cs_push}/yafowil.bootstrap.git -branch = ${settings:feature_branch} +branch = master mxmake-test-path = src mxmake-source-path = src/yafowil/bootstrap @@ -116,7 +113,7 @@ mxmake-source-path = src/yafowil/bootstrap use = ${settings:checkout_packages} url = ${settings:cs}/yafowil.widget.array.git pushurl = ${settings:cs_push}/yafowil.widget.array.git -branch = ${settings:feature_branch} +branch = master extras = test mxmake-test-path = src mxmake-source-path = src/yafowil/widget/array @@ -126,7 +123,7 @@ mxmake-omit-path = src/yafowil/widget/array/example.py use = ${settings:checkout_packages} url = ${settings:cs}/yafowil.widget.autocomplete.git pushurl = ${settings:cs_push}/yafowil.widget.autocomplete.git -branch = ${settings:feature_branch} +branch = master extras = test mxmake-test-path = src mxmake-source-path = src/yafowil/widget/autocomplete @@ -136,7 +133,7 @@ mxmake-omit-path = src/yafowil/widget/autocomplete/example.py use = ${settings:checkout_packages} url = ${settings:cs}/yafowil.widget.datetime.git pushurl = ${settings:cs_push}/yafowil.widget.datetime.git -branch = ${settings:feature_branch} +branch = master extras = test mxmake-test-path = src mxmake-source-path = src/yafowil/widget/datetime @@ -146,7 +143,7 @@ mxmake-omit-path = src/yafowil/widget/datetime/example.py use = ${settings:checkout_packages} url = ${settings:cs}/yafowil.widget.dict.git pushurl = ${settings:cs_push}/yafowil.widget.dict.git -branch = ${settings:feature_branch} +branch = master extras = test mxmake-test-path = src mxmake-source-path = src/yafowil/widget/dict @@ -156,7 +153,7 @@ mxmake-omit-path = src/yafowil/widget/dict/example.py use = ${settings:checkout_packages} url = ${settings:cs}/yafowil.widget.image.git pushurl = ${settings:cs_push}/yafowil.widget.image.git -branch = ${settings:feature_branch} +branch = master extras = test mxmake-test-path = src mxmake-source-path = src/yafowil/widget/image @@ -170,7 +167,7 @@ mxmake-omit-path = src/yafowil/widget/image/example.py use = ${settings:checkout_packages} url = ${settings:cs}/treibstoff.git pushurl = ${settings:cs_push}/treibstoff.git -branch = ${settings:feature_branch} +branch = 2.0 [webresource] use = ${settings:checkout_packages} @@ -185,7 +182,7 @@ mxmake-source-path = webresource use = ${settings:checkout_packages} url = ${settings:cs}/cone.tile.git pushurl = ${settings:cs_push}/cone.tile.git -branch = ${settings:feature_branch} +branch = master extras = test mxmake-test-path = src mxmake-source-path = src/cone/tile @@ -194,7 +191,7 @@ mxmake-source-path = src/cone/tile use = ${settings:checkout_packages} url = ${settings:cs}/cone.app.git pushurl = ${settings:cs_push}/cone.app.git -branch = ${settings:feature_branch} +branch = 2.0 extras = test mxmake-test-path = src mxmake-source-path = src/cone/app @@ -203,7 +200,7 @@ mxmake-source-path = src/cone/app use = ${settings:checkout_packages} url = ${settings:cs}/cone.sql.git pushurl = ${settings:cs_push}/cone.sql.git -branch = ${settings:feature_branch} +branch = master extras = test mxmake-test-path = src mxmake-source-path = src/cone/sql @@ -212,7 +209,7 @@ mxmake-source-path = src/cone/sql use = ${settings:checkout_packages} url = ${settings:cs}/cone.ugm.git pushurl = ${settings:cs_push}/cone.ugm.git -branch = ${settings:feature_branch} +branch = 2.0 extras = test mxmake-test-path = src mxmake-source-path = src/cone/ugm diff --git a/package.json b/package.json index 2633de5..6a5d4e4 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "qunit": "^2.20.1", "rollup": "^2.79.2", "rollup-plugin-cleanup": "^3.2.1", - "sass": "^1.94.2", + "sass": "^1.96.0", "web-test-runner-qunit": "^2.0.0" }, "packageManager": "pnpm@9.3.0+sha512.ee7b93e0c2bd11409c6424f92b866f31d3ea1bef5fbe47d3c7500cdc3c9668833d2e55681ad66df5b640c61fa9dc25d546efa54d76d7f8bf54b13614ac293631" diff --git a/pyproject.toml b/pyproject.toml index 202de11..c84d9c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "cone.tokens" -version = "1.1.0.dev0" +version = "2.0.0.dev0" description = "cone token api" dynamic = ["readme"] requires-python = ">=3.10" @@ -22,7 +22,7 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP :: Dynamic Content", ] dependencies = [ - "cone.app>1.0.99,<2.0.0", + "cone.app>1.99", "cone.sql>1.0.99", "python-dateutil", "qrcode[pil]", diff --git a/scss/styles.scss b/scss/styles.scss index 9b3d854..3d75f88 100644 --- a/scss/styles.scss +++ b/scss/styles.scss @@ -1,69 +1,22 @@ @media screen { - div.token-overview { - display: flex; - flex-wrap: wrap; - - div.panel.token { - flex: 1; - min-width: fit-content; - border-right: 0; - box-shadow: 1px 0px 0px #e5e5e5; - - li.flex-group { - display: flex; - justify-content: space-between; - flex-wrap: wrap; - } - .token-active { - pointer-events: none; - } - } - - div.QR { - display: flex; - flex-direction: column; - align-items: center; - padding: 2px; - - .stream_image { - margin:auto; - } - } - } - .token-title { - border-radius: 4px 4px 0 0; - } - - // Tokens Overview + // // Tokens Overview .tokens-overview-container { - #tokens-overview { - display: grid; + .form-inline { + flex: 1 1 20%; + flex-wrap: nowrap; + white-space: nowrap; } - #tokens-overview-title { - display: flex; - align-items: baseline; - justify-content: space-between; - flex-wrap: wrap; - gap: 10px; - .token-size .token-button { - color: #000; - margin: 0 10px; - } + .btn { + white-space: nowrap; - button.datepicker-trigger { - transform: translateX(-100%); + &.filter { + min-width: 100px; } + } - input.add-tokens-amount { - width: 70px; - } - input.token-button { - width: 70px; - } - > div > * { - display: inline-block; - } + input { + min-width: 100px!important; } } @@ -74,12 +27,6 @@ height: 200px; font-size: 500%; } - .scan-token.inactive { - background-color: #dd0000; - } - .scan-token.active { - background-color: #00dd00; - } } } diff --git a/src/cone/tokens/browser/__init__.py b/src/cone/tokens/browser/__init__.py index 31b1387..b73a375 100644 --- a/src/cone/tokens/browser/__init__.py +++ b/src/cone/tokens/browser/__init__.py @@ -10,7 +10,7 @@ ) cone_tokens_resources.add(wr.ScriptResource( name='cone-tokens-js', - depends='cone-app-protected-js', + depends='cone-app-js', resource='cone.tokens.js', compressed='cone.tokens.min.js' )) diff --git a/src/cone/tokens/browser/settings.py b/src/cone/tokens/browser/settings.py index d1ecd4e..f42e14b 100644 --- a/src/cone/tokens/browser/settings.py +++ b/src/cone/tokens/browser/settings.py @@ -14,7 +14,7 @@ import json -_ = TranslationStringFactory('cone.ugm') +_ = TranslationStringFactory('cone.tokens') @settings_form(TokenSettings) @@ -60,7 +60,9 @@ def prepare(self): form['morning'] = factory( '#field:error:*morning:compound', props={ - 'label': _('morning', default='Morning') + 'label': _('morning', default='Morning'), + 'label.class_add': 'col-12 fw-bold', + 'class_add': 'd-flex flex-wrap' }, custom = { 'morning': { @@ -77,7 +79,8 @@ def prepare(self): 'label': _('start', default='Start'), 'timepicker': True, 'time': True, - 'persist': True + 'persist': True, + 'class_add': 'col-6 pe-3' }) form['morning']['end'] = factory( '#field:time', @@ -87,12 +90,15 @@ def prepare(self): 'label': _('end', default='End'), 'timepicker': True, 'time': True, - 'persist': True + 'persist': True, + 'class_add': 'col-6' }) form['afternoon'] = factory( '#field:error:*afternoon:compound', props={ - 'label': _('afternoon', default='Afternoon') + 'label': _('afternoon', default='Afternoon'), + 'label.class_add': 'col-12 fw-bold', + 'class_add': 'd-flex flex-wrap' }, custom = { 'afternoon': { @@ -107,7 +113,8 @@ def prepare(self): 'label': _('start', default='Start'), 'timepicker': True, 'time': True, - 'persist': True + 'persist': True, + 'class_add': 'col-6 pe-3' }) form['afternoon']['end'] = factory( '#field:time', @@ -117,12 +124,15 @@ def prepare(self): 'label': _('end', default='End'), 'timepicker': True, 'time': True, - 'persist': True + 'persist': True, + 'class_add': 'col-6' }) form['today'] = factory( '#field:error:*today:compound', props={ - 'label': _('today', default='Today') + 'label': _('today', default='Today'), + 'label.class_add': 'col-12 fw-bold', + 'class_add': 'd-flex flex-wrap' }, custom = { 'today': { @@ -137,7 +147,8 @@ def prepare(self): 'label': _('start', default='Start'), 'timepicker': True, 'time': True, - 'persist': True + 'persist': True, + 'class_add': 'col-6 pe-3' }) form['today']['end'] = factory( '#field:time', @@ -147,7 +158,8 @@ def prepare(self): 'label': _('end', default='End'), 'timepicker': True, 'time': True, - 'persist': True + 'persist': True, + 'class_add': 'col-6' }) form['default_locktime'] = factory( '#field:number', @@ -159,7 +171,8 @@ def prepare(self): 'default_locktime_required', default='Default Locktime is required.' ), - 'label': _('default_locktime', default='Default Locktime') + 'label': _('default_locktime', default='Default Locktime'), + 'label.class_add': 'fw-bold' }) form['default_usage_count'] = factory( '#field:number', @@ -171,7 +184,8 @@ def prepare(self): 'default_usage_count_required', default='Default number of uses required.' ), - 'label': _('default_usage_count', default='Default Uses') + 'label': _('default_usage_count', default='Default Uses'), + 'label.class_add': 'fw-bold' }) form['save'] = factory( 'submit', @@ -180,7 +194,8 @@ def prepare(self): 'expression': True, 'handler': self.save, 'next': self.next, - 'label': 'Save' + 'label': _('save', default='Save'), + 'submit.class_add': 'my-3' }) def save(self, widget, data): diff --git a/src/cone/tokens/browser/static/cone.tokens.css b/src/cone/tokens/browser/static/cone.tokens.css index 7107ab9..588bffa 100644 --- a/src/cone/tokens/browser/static/cone.tokens.css +++ b/src/cone/tokens/browser/static/cone.tokens.css @@ -1,71 +1,23 @@ @media screen { - div.token-overview { - display: flex; - flex-wrap: wrap; + .tokens-overview-container .form-inline { + flex: 1 1 20%; + flex-wrap: nowrap; + white-space: nowrap; } - div.token-overview div.panel.token { - flex: 1; - min-width: fit-content; - border-right: 0; - box-shadow: 1px 0px 0px #e5e5e5; + .tokens-overview-container .btn { + white-space: nowrap; } - div.token-overview div.panel.token li.flex-group { - display: flex; - justify-content: space-between; - flex-wrap: wrap; + .tokens-overview-container .btn.filter { + min-width: 100px; } - div.token-overview div.panel.token .token-active { - pointer-events: none; - } - div.token-overview div.QR { - display: flex; - flex-direction: column; - align-items: center; - padding: 2px; - } - div.token-overview div.QR .stream_image { - margin: auto; - } - .token-title { - border-radius: 4px 4px 0 0; - } - .tokens-overview-container #tokens-overview { - display: grid; - } - .tokens-overview-container #tokens-overview-title { - display: flex; - align-items: baseline; - justify-content: space-between; - flex-wrap: wrap; - gap: 10px; - } - .tokens-overview-container #tokens-overview-title .token-size .token-button { - color: #000; - margin: 0 10px; - } - .tokens-overview-container #tokens-overview-title button.datepicker-trigger { - transform: translateX(-100%); - } - .tokens-overview-container #tokens-overview-title input.add-tokens-amount { - width: 70px; - } - .tokens-overview-container #tokens-overview-title input.token-button { - width: 70px; - } - .tokens-overview-container #tokens-overview-title > div > * { - display: inline-block; + .tokens-overview-container input { + min-width: 100px !important; } .tokens-container .scan-token { width: 100%; height: 200px; font-size: 500%; } - .tokens-container .scan-token.inactive { - background-color: #dd0000; - } - .tokens-container .scan-token.active { - background-color: #00dd00; - } } @media print { #tokens-overview-title { diff --git a/src/cone/tokens/browser/static/cone.tokens.js b/src/cone/tokens/browser/static/cone.tokens.js index 206363a..9beeec0 100644 --- a/src/cone/tokens/browser/static/cone.tokens.js +++ b/src/cone/tokens/browser/static/cone.tokens.js @@ -90,9 +90,10 @@ var cone_tokens = (function (exports, $, ts) { this.container = container; this.tokens_elem = $('#tokens-overview', container); this.tokens = $('object.token_qr', this.tokens_elem); - this.tokens_title = $('#tokens-overview-title', container); + this.filter_options = $('#tokens-filter-options', container); + this.create_options = $('#tokens-create-options', container); this.token_settings = this.container.data('token-settings'); - this.add_tokens_container = $('.add-tokens', this.tokens_title); + this.add_tokens_container = $('.add-tokens', this.create_options); this.add_tokens_input = $( 'input[name="amount"]', this.add_tokens_container @@ -103,16 +104,16 @@ var cone_tokens = (function (exports, $, ts) { ); this.add_tokens = this.add_tokens.bind(this); this.add_tokens_btn.on('click', this.add_tokens); - this.start = $('input[name="start"]', this.tokens_title) + this.start = $('input[name="start"]', this.filter_options) .addClass('datepicker') .data('date-locale', 'de'); - this.end = $('input[name="end"]', this.tokens_title) + this.end = $('input[name="end"]', this.filter_options) .addClass('datepicker') .data('date-locale', 'de'); - this.filter = $('button[name="filter"]', this.tokens_title); + this.filter = $('button[name="filter"]', this.filter_options); this.filter_tokens = this.filter_tokens.bind(this); this.filter.on('click', this.filter_tokens); - this.delete_tokens_container = $('.delete-tokens', this.tokens_title); + this.delete_tokens_container = $('.delete-tokens', this.create_options); this.delete_tokens_btn = $( 'button[name="delete-tokens"]', this.delete_tokens_container @@ -120,7 +121,7 @@ var cone_tokens = (function (exports, $, ts) { this.delete_tokens = this.delete_tokens.bind(this); this.delete_tokens_btn.on('click', this.delete_tokens); this.set_token_size = this.set_token_size.bind(this); - this.size_input = $('input[name="token-size"]', this.tokens_title); + this.size_input = $('input[name="token-size"]', this.filter_options); this.size_input.on('change', this.set_token_size); if (this.tokens.length) { this.original_size = parseInt($(this.tokens[0]).attr('width')); @@ -279,13 +280,13 @@ var cone_tokens = (function (exports, $, ts) { let input = this._input = $(''); wrapper.append(input); this.elem.append(wrapper); - button.removeClass('inactive').addClass('active'); + button.removeClass('inactive btn-danger').addClass('active btn-success'); input[0].focus(); } else { this._input_wrapper.remove(); this._input_wrapper = null; this._input = null; - button.removeClass('active').addClass('inactive'); + button.removeClass('active btn-success').addClass('inactive btn-danger'); } } scan_token() { diff --git a/src/cone/tokens/browser/static/cone.tokens.min.css b/src/cone/tokens/browser/static/cone.tokens.min.css index 1341ab1..07ae73d 100644 --- a/src/cone/tokens/browser/static/cone.tokens.min.css +++ b/src/cone/tokens/browser/static/cone.tokens.min.css @@ -1 +1 @@ -@media screen{div.token-overview{display:flex;flex-wrap:wrap}div.token-overview div.panel.token{flex:1;min-width:fit-content;border-right:0;box-shadow:1px 0px 0px #e5e5e5}div.token-overview div.panel.token li.flex-group{display:flex;justify-content:space-between;flex-wrap:wrap}div.token-overview div.panel.token .token-active{pointer-events:none}div.token-overview div.QR{display:flex;flex-direction:column;align-items:center;padding:2px}div.token-overview div.QR .stream_image{margin:auto}.token-title{border-radius:4px 4px 0 0}.tokens-overview-container #tokens-overview{display:grid}.tokens-overview-container #tokens-overview-title{display:flex;align-items:baseline;justify-content:space-between;flex-wrap:wrap;gap:10px}.tokens-overview-container #tokens-overview-title .token-size .token-button{color:#000;margin:0 10px}.tokens-overview-container #tokens-overview-title button.datepicker-trigger{transform:translateX(-100%)}.tokens-overview-container #tokens-overview-title input.add-tokens-amount{width:70px}.tokens-overview-container #tokens-overview-title input.token-button{width:70px}.tokens-overview-container #tokens-overview-title>div>*{display:inline-block}.tokens-container .scan-token{width:100%;height:200px;font-size:500%}.tokens-container .scan-token.inactive{background-color:#d00}.tokens-container .scan-token.active{background-color:#0d0}}@media print{#tokens-overview-title{display:none}} +@media screen{.tokens-overview-container .form-inline{flex:1 1 20%;flex-wrap:nowrap;white-space:nowrap}.tokens-overview-container .btn{white-space:nowrap}.tokens-overview-container .btn.filter{min-width:100px}.tokens-overview-container input{min-width:100px !important}.tokens-container .scan-token{width:100%;height:200px;font-size:500%}}@media print{#tokens-overview-title{display:none}} diff --git a/src/cone/tokens/browser/static/cone.tokens.min.js b/src/cone/tokens/browser/static/cone.tokens.min.js index 1369552..91d60a4 100644 --- a/src/cone/tokens/browser/static/cone.tokens.min.js +++ b/src/cone/tokens/browser/static/cone.tokens.min.js @@ -1 +1 @@ -var cone_tokens=function(t,e,s){"use strict";class n{static initialize(t){e(".token",t).each(function(){new n(e(this))})}constructor(t){this.elem=t,this.settings=t.data("token-settings");const s=this;e(".btn-group.timeranges button",t).each(function(){const t=e(this);t.on("click",function(e){s.set_timerange(t.data("timerange-scope"))})}),e(".btn-group.usage-count button",t).each(function(){const t=e(this);t.on("click",function(e){s.set_usage_count(t.data("usage-count"))})})}request_api(t){const e=this.settings;s.http_request({url:`${e.base_url}/update_token`,params:t,type:"json",method:"POST",success:(t,n,i)=>{t.success?s.ajax.action({name:"content",selector:"#content",mode:"inner",url:`${e.base_url}`,params:{}}):s.show_error(t.message)},error:(t,e,n)=>{s.show_error(`Failed to request JSON API: ${n}`)}})}set_timerange(t){const e=this.settings.timeranges;let s,n,i;if(Object.keys(e).includes(t)){s=e[t];let o=s.start.split(":");n=new Date,n.setHours(o[0],o[1],0);let a=s.end.split(":");i=new Date,i.setHours(a[0],a[1],0)}function o(t){return t&&(t=new Date(t.getTime()-6e4*t.getTimezoneOffset())),t?t.toISOString():""}this.request_api({valid_from:o(n),valid_to:o(i)})}set_usage_count(t){this.request_api({usage_count:t})}}class i{static initialize(t){e(".tokens-overview-container",t).each(function(){new i(e(this))})}constructor(t){this.container=t,this.tokens_elem=e("#tokens-overview",t),this.tokens=e("object.token_qr",this.tokens_elem),this.tokens_title=e("#tokens-overview-title",t),this.token_settings=this.container.data("token-settings"),this.add_tokens_container=e(".add-tokens",this.tokens_title),this.add_tokens_input=e('input[name="amount"]',this.add_tokens_container),this.add_tokens_btn=e('button[name="add-tokens"]',this.add_tokens_container),this.add_tokens=this.add_tokens.bind(this),this.add_tokens_btn.on("click",this.add_tokens),this.start=e('input[name="start"]',this.tokens_title).addClass("datepicker").data("date-locale","de"),this.end=e('input[name="end"]',this.tokens_title).addClass("datepicker").data("date-locale","de"),this.filter=e('button[name="filter"]',this.tokens_title),this.filter_tokens=this.filter_tokens.bind(this),this.filter.on("click",this.filter_tokens),this.delete_tokens_container=e(".delete-tokens",this.tokens_title),this.delete_tokens_btn=e('button[name="delete-tokens"]',this.delete_tokens_container),this.delete_tokens=this.delete_tokens.bind(this),this.delete_tokens_btn.on("click",this.delete_tokens),this.set_token_size=this.set_token_size.bind(this),this.size_input=e('input[name="token-size"]',this.tokens_title),this.size_input.on("change",this.set_token_size),this.tokens.length?this.original_size=parseInt(e(this.tokens[0]).attr("width")):this.original_size=256,this.token_size=100}get token_size(){return this._token_size}set token_size(t){t||(t=100);let s=this.original_size*(t/100);this.tokens_elem.css("grid-template-columns",`repeat( auto-fit, minmax(${s}px, 1fr) )`),this.tokens.each(function(){let t=e(this);t.attr("width",`${s}px`),t.attr("height",`${s}px`)}),this.size_input.val()||this.size_input.val(t),this._token_size=t}filter_tokens(t){t.preventDefault();let e={start:this.start.val(),end:this.end.val()};s.ajax.action({name:"tokens_overview",mode:"inner",selector:"#content",url:this.token_settings.base_url,params:e})}add_tokens(t){const e=this.token_settings.base_url;let n=this.add_tokens_input.val();n&&(n=parseInt(n),function t(n,i){s.http_request({url:`${e}/add_token`,params:{},type:"json",method:"POST",success:(o,a,r)=>{o.success?n===(i+=1)?s.ajax.action({name:"tokens_overview",selector:"#content",mode:"inner",url:e,params:{}}):t(n,i):s.show_error(o.message)},error:(t,e,n)=>{s.show_error(`Failed to request JSON API: ${n}`)}})}(n,0))}delete_tokens(t){const n=this.token_settings.base_url;s.show_dialog({title:"Delete tokens?",message:"Do you really want to delete selected tokens?",on_confirm:()=>{let t=[];for(let s of this.tokens){let n=e(s).data("token-uid");t.push(n)}s.http_request({url:`${n}/delete_tokens`,params:{token_uids:JSON.stringify(t)},type:"json",method:"POST",success:(t,e,i)=>{t.success?(s.ajax.action({name:"tokens_overview",selector:"#content",mode:"inner",url:n,params:{}}),s.show_message({message:t.message,flavor:""})):s.show_error(t.message)},error:(t,e,n)=>{s.show_error(`Failed to request JSON API: ${n}`)}})}})}set_token_size(t){t.preventDefault();let e=this.size_input.val();this.token_size=e}}class o{static initialize(t){e(".tokens-container",t).each(function(){new o(e(this))})}constructor(t){this.elem=t,this.base_url=t.data("base-url"),this.button=e(".scan-token",t),this._input_wrapper=null,this._input=null,this.scan_token=this.scan_token.bind(this),this.button.on("click",t=>{this.scan_token()})}get active(){return null!==this._input}set active(t){if(t==this.value)return;let s=this.button;if(t){let t=this._input_wrapper=e("
").css("width",0).css("overflow","hidden"),n=this._input=e('');t.append(n),this.elem.append(t),s.removeClass("inactive").addClass("active"),n[0].focus()}else this._input_wrapper.remove(),this._input_wrapper=null,this._input=null,s.removeClass("active").addClass("inactive")}scan_token(){this.active=!0;let t=this._input;t.one("change",()=>{this.query_token(t.val())})}load_token(t){console.log("load token: "+t),s.ajax.action({name:"layout",selector:"#layout",mode:"replace",url:`${this.base_url}/${t}`,params:{}})}query_token(t){s.http_request({url:`${this.base_url}/query_token`,params:{value:t},type:"json",success:(e,n,i)=>{e.success?e.token?this.load_token(e.token.uid):(this.active=!1,s.show_dialog({title:"Token not exists?",message:"Do you want to create it?",on_confirm:()=>{s.http_request({url:`${this.base_url}/add_token`,params:{value:t},type:"json",method:"POST",success:(t,e,n)=>{t.success?this.load_token(t.token_uid):s.show_error(t.message)},error:(t,e,n)=>{s.show_error(`Failed to request JSON API: ${n}`)}})}})):s.show_error(e.message)},error:(t,e,n)=>{s.show_error(`Failed to request JSON API: ${n}`)}})}}return e(function(){s.ajax.register(n.initialize,!0),s.ajax.register(o.initialize,!0),s.ajax.register(i.initialize,!0)}),t.TokenScanner=o,t.TokensOverview=i,Object.defineProperty(t,"__esModule",{value:!0}),t}({},jQuery,ts); +var cone_tokens=function(t,e,s){"use strict";class n{static initialize(t){e(".token",t).each(function(){new n(e(this))})}constructor(t){this.elem=t,this.settings=t.data("token-settings");const s=this;e(".btn-group.timeranges button",t).each(function(){const t=e(this);t.on("click",function(e){s.set_timerange(t.data("timerange-scope"))})}),e(".btn-group.usage-count button",t).each(function(){const t=e(this);t.on("click",function(e){s.set_usage_count(t.data("usage-count"))})})}request_api(t){const e=this.settings;s.http_request({url:`${e.base_url}/update_token`,params:t,type:"json",method:"POST",success:(t,n,i)=>{t.success?s.ajax.action({name:"content",selector:"#content",mode:"inner",url:`${e.base_url}`,params:{}}):s.show_error(t.message)},error:(t,e,n)=>{s.show_error(`Failed to request JSON API: ${n}`)}})}set_timerange(t){const e=this.settings.timeranges;let s,n,i;if(Object.keys(e).includes(t)){s=e[t];let o=s.start.split(":");n=new Date,n.setHours(o[0],o[1],0);let a=s.end.split(":");i=new Date,i.setHours(a[0],a[1],0)}function o(t){return t&&(t=new Date(t.getTime()-6e4*t.getTimezoneOffset())),t?t.toISOString():""}this.request_api({valid_from:o(n),valid_to:o(i)})}set_usage_count(t){this.request_api({usage_count:t})}}class i{static initialize(t){e(".tokens-overview-container",t).each(function(){new i(e(this))})}constructor(t){this.container=t,this.tokens_elem=e("#tokens-overview",t),this.tokens=e("object.token_qr",this.tokens_elem),this.filter_options=e("#tokens-filter-options",t),this.create_options=e("#tokens-create-options",t),this.token_settings=this.container.data("token-settings"),this.add_tokens_container=e(".add-tokens",this.create_options),this.add_tokens_input=e('input[name="amount"]',this.add_tokens_container),this.add_tokens_btn=e('button[name="add-tokens"]',this.add_tokens_container),this.add_tokens=this.add_tokens.bind(this),this.add_tokens_btn.on("click",this.add_tokens),this.start=e('input[name="start"]',this.filter_options).addClass("datepicker").data("date-locale","de"),this.end=e('input[name="end"]',this.filter_options).addClass("datepicker").data("date-locale","de"),this.filter=e('button[name="filter"]',this.filter_options),this.filter_tokens=this.filter_tokens.bind(this),this.filter.on("click",this.filter_tokens),this.delete_tokens_container=e(".delete-tokens",this.create_options),this.delete_tokens_btn=e('button[name="delete-tokens"]',this.delete_tokens_container),this.delete_tokens=this.delete_tokens.bind(this),this.delete_tokens_btn.on("click",this.delete_tokens),this.set_token_size=this.set_token_size.bind(this),this.size_input=e('input[name="token-size"]',this.filter_options),this.size_input.on("change",this.set_token_size),this.tokens.length?this.original_size=parseInt(e(this.tokens[0]).attr("width")):this.original_size=256,this.token_size=100}get token_size(){return this._token_size}set token_size(t){t||(t=100);let s=this.original_size*(t/100);this.tokens_elem.css("grid-template-columns",`repeat( auto-fit, minmax(${s}px, 1fr) )`),this.tokens.each(function(){let t=e(this);t.attr("width",`${s}px`),t.attr("height",`${s}px`)}),this.size_input.val()||this.size_input.val(t),this._token_size=t}filter_tokens(t){t.preventDefault();let e={start:this.start.val(),end:this.end.val()};s.ajax.action({name:"tokens_overview",mode:"inner",selector:"#content",url:this.token_settings.base_url,params:e})}add_tokens(t){const e=this.token_settings.base_url;let n=this.add_tokens_input.val();n&&(n=parseInt(n),function t(n,i){s.http_request({url:`${e}/add_token`,params:{},type:"json",method:"POST",success:(o,a,r)=>{o.success?n===(i+=1)?s.ajax.action({name:"tokens_overview",selector:"#content",mode:"inner",url:e,params:{}}):t(n,i):s.show_error(o.message)},error:(t,e,n)=>{s.show_error(`Failed to request JSON API: ${n}`)}})}(n,0))}delete_tokens(t){const n=this.token_settings.base_url;s.show_dialog({title:"Delete tokens?",message:"Do you really want to delete selected tokens?",on_confirm:()=>{let t=[];for(let s of this.tokens){let n=e(s).data("token-uid");t.push(n)}s.http_request({url:`${n}/delete_tokens`,params:{token_uids:JSON.stringify(t)},type:"json",method:"POST",success:(t,e,i)=>{t.success?(s.ajax.action({name:"tokens_overview",selector:"#content",mode:"inner",url:n,params:{}}),s.show_message({message:t.message,flavor:""})):s.show_error(t.message)},error:(t,e,n)=>{s.show_error(`Failed to request JSON API: ${n}`)}})}})}set_token_size(t){t.preventDefault();let e=this.size_input.val();this.token_size=e}}class o{static initialize(t){e(".tokens-container",t).each(function(){new o(e(this))})}constructor(t){this.elem=t,this.base_url=t.data("base-url"),this.button=e(".scan-token",t),this._input_wrapper=null,this._input=null,this.scan_token=this.scan_token.bind(this),this.button.on("click",t=>{this.scan_token()})}get active(){return null!==this._input}set active(t){if(t==this.value)return;let s=this.button;if(t){let t=this._input_wrapper=e("
").css("width",0).css("overflow","hidden"),n=this._input=e('');t.append(n),this.elem.append(t),s.removeClass("inactive btn-danger").addClass("active btn-success"),n[0].focus()}else this._input_wrapper.remove(),this._input_wrapper=null,this._input=null,s.removeClass("active btn-success").addClass("inactive btn-danger")}scan_token(){this.active=!0;let t=this._input;t.one("change",()=>{this.query_token(t.val())})}load_token(t){console.log("load token: "+t),s.ajax.action({name:"layout",selector:"#layout",mode:"replace",url:`${this.base_url}/${t}`,params:{}})}query_token(t){s.http_request({url:`${this.base_url}/query_token`,params:{value:t},type:"json",success:(e,n,i)=>{e.success?e.token?this.load_token(e.token.uid):(this.active=!1,s.show_dialog({title:"Token not exists?",message:"Do you want to create it?",on_confirm:()=>{s.http_request({url:`${this.base_url}/add_token`,params:{value:t},type:"json",method:"POST",success:(t,e,n)=>{t.success?this.load_token(t.token_uid):s.show_error(t.message)},error:(t,e,n)=>{s.show_error(`Failed to request JSON API: ${n}`)}})}})):s.show_error(e.message)},error:(t,e,n)=>{s.show_error(`Failed to request JSON API: ${n}`)}})}}return e(function(){s.ajax.register(n.initialize,!0),s.ajax.register(o.initialize,!0),s.ajax.register(i.initialize,!0)}),t.TokenScanner=o,t.TokensOverview=i,Object.defineProperty(t,"__esModule",{value:!0}),t}({},jQuery,ts); diff --git a/src/cone/tokens/browser/templates/token.pt b/src/cone/tokens/browser/templates/token.pt index 74b6f9b..3490947 100644 --- a/src/cone/tokens/browser/templates/token.pt +++ b/src/cone/tokens/browser/templates/token.pt @@ -7,107 +7,101 @@ -
- Token -
- -
-
- -
    +
    -
  • - -
  • -
  • - Value: - Value -
  • +
    +
    Token
    +
    +
      +
      + + Active +
      +
    • + Value: + Value +
    • -
    • -
      +
    • +
      Valid: - - - - - - - - Unlimited - -
      -
      - - - - -
      -
    • + + + - + + + + Unlimited + +
    +
    + + + + +
    + -
  • -
    - Usage Count: - - Usage Count - - - Unlimited - -
    -
    - - - - - - - -
    -
  • +
  • +
    + Usage Count: + + Usage Count + + + Unlimited + +
    +
    + + + + + + + +
    +
  • -
  • - Lock Time: - -
  • +
  • + Lock Time: + +
  • -
  • - Creator: - -
  • +
  • + Creator: + +
  • -
  • - Created: - -
  • +
  • + Created: + +
  • -
  • - Modified: - -
  • -
-
+
  • + Modified: + +
  • + -
    +