fix bottom bar, migrate placeholder

This commit is contained in:
_Bastler 2022-12-11 10:29:49 +01:00
parent 159d19e939
commit 3d7dc4d03c
16 changed files with 167 additions and 170 deletions

View File

@ -2,7 +2,7 @@
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
"index": "/index.html",
"appData": {
"version": "1.5.4"
"version": "1.5.5"
},
"assetGroups": [
{

181
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "bstlboard",
"version": "1.5.4",
"version": "1.5.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "bstlboard",
"version": "1.5.4",
"version": "1.5.5",
"license": "AGPL3",
"dependencies": {
"@angular-material-components/datetime-picker": "^9.0.0",
@ -3726,14 +3726,11 @@
"yarn": ">= 1.13.0"
}
},
"node_modules/@socket.io/base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==",
"dev": true,
"engines": {
"node": ">= 0.6.0"
}
"node_modules/@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==",
"dev": true
},
"node_modules/@tootallnate/once": {
"version": "2.0.0",
@ -3763,12 +3760,6 @@
"@types/node": "*"
}
},
"node_modules/@types/component-emitter": {
"version": "1.2.11",
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz",
"integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==",
"dev": true
},
"node_modules/@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
@ -3795,10 +3786,13 @@
"dev": true
},
"node_modules/@types/cors": {
"version": "2.8.12",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==",
"dev": true
"version": "2.8.13",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
"integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/eslint": {
"version": "8.4.1",
@ -4183,9 +4177,9 @@
}
},
"node_modules/adjust-sourcemap-loader/node_modules/loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
@ -5224,12 +5218,6 @@
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
"dev": true
},
"node_modules/component-emitter": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
"dev": true
},
"node_modules/compressible": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@ -6061,9 +6049,9 @@
}
},
"node_modules/engine.io": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.3.tgz",
"integrity": "sha512-rqs60YwkvWTLLnfazqgZqLa/aKo+9cueVfEi/dZ8PyGyaf8TLOxj++4QMIgeG3Gn0AhrWiFXvghsoY9L9h25GA==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz",
"integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==",
"dev": true,
"dependencies": {
"@types/cookie": "^0.4.1",
@ -6082,13 +6070,10 @@
}
},
"node_modules/engine.io-parser": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz",
"integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==",
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz",
"integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==",
"dev": true,
"dependencies": {
"@socket.io/base64-arraybuffer": "~1.0.2"
},
"engines": {
"node": ">=10.0.0"
}
@ -11607,9 +11592,9 @@
}
},
"node_modules/resolve-url-loader/node_modules/loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
@ -12210,36 +12195,35 @@
}
},
"node_modules/socket.io": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz",
"integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==",
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz",
"integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==",
"dev": true,
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"debug": "~4.3.2",
"engine.io": "~6.1.0",
"socket.io-adapter": "~2.3.3",
"socket.io-parser": "~4.0.4"
"engine.io": "~6.2.1",
"socket.io-adapter": "~2.4.0",
"socket.io-parser": "~4.2.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-adapter": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz",
"integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==",
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz",
"integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==",
"dev": true
},
"node_modules/socket.io-parser": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
"integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
"integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
"dev": true,
"dependencies": {
"@types/component-emitter": "^1.2.10",
"component-emitter": "~1.3.0",
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
@ -16573,10 +16557,10 @@
"jsonc-parser": "3.2.0"
}
},
"@socket.io/base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==",
"@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==",
"dev": true
},
"@tootallnate/once": {
@ -16604,12 +16588,6 @@
"@types/node": "*"
}
},
"@types/component-emitter": {
"version": "1.2.11",
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz",
"integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==",
"dev": true
},
"@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
@ -16636,10 +16614,13 @@
"dev": true
},
"@types/cors": {
"version": "2.8.12",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==",
"dev": true
"version": "2.8.13",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
"integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/eslint": {
"version": "8.4.1",
@ -17010,9 +16991,9 @@
},
"dependencies": {
"loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
@ -17796,12 +17777,6 @@
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
"dev": true
},
"component-emitter": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
"dev": true
},
"compressible": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@ -18449,9 +18424,9 @@
}
},
"engine.io": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.3.tgz",
"integrity": "sha512-rqs60YwkvWTLLnfazqgZqLa/aKo+9cueVfEi/dZ8PyGyaf8TLOxj++4QMIgeG3Gn0AhrWiFXvghsoY9L9h25GA==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz",
"integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==",
"dev": true,
"requires": {
"@types/cookie": "^0.4.1",
@ -18467,13 +18442,10 @@
}
},
"engine.io-parser": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz",
"integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==",
"dev": true,
"requires": {
"@socket.io/base64-arraybuffer": "~1.0.2"
}
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz",
"integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==",
"dev": true
},
"enhanced-resolve": {
"version": "5.12.0",
@ -22615,9 +22587,9 @@
},
"dependencies": {
"loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
@ -23074,33 +23046,32 @@
"dev": true
},
"socket.io": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz",
"integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==",
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz",
"integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==",
"dev": true,
"requires": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"debug": "~4.3.2",
"engine.io": "~6.1.0",
"socket.io-adapter": "~2.3.3",
"socket.io-parser": "~4.0.4"
"engine.io": "~6.2.1",
"socket.io-adapter": "~2.4.0",
"socket.io-parser": "~4.2.1"
}
},
"socket.io-adapter": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz",
"integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==",
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz",
"integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==",
"dev": true
},
"socket.io-parser": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
"integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
"integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
"dev": true,
"requires": {
"@types/component-emitter": "^1.2.10",
"component-emitter": "~1.3.0",
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
}
},

View File

@ -1,6 +1,6 @@
{
"name": "bstlboard",
"version": "1.5.4",
"version": "1.5.5",
"license": "AGPL3",
"scripts": {
"ng": "ng",

View File

@ -1,11 +1,13 @@
<div class="container">
<mat-progress-bar *ngIf="!entry" mode="indeterminate"></mat-progress-bar>
<form [formGroup]="form" (ngSubmit)="entry.id ? update() : create()" #formDirective="ngForm" *ngIf="entry && settings">
<form [formGroup]="form" (ngSubmit)="entry.id ? update() : create()" #formDirective="ngForm"
*ngIf="entry && settings">
<mat-card>
<mat-card-content>
<p>{{ (entry.id ? 'submission.edit' : 'submission.info') | i18n}}</p>
<mat-form-field>
<mat-select placeholder="{{'submission.entryType' | i18n}}" formControlName="entryType">
<mat-label>{{'submission.entryType' | i18n}}</mat-label>
<mat-select formControlName="entryType">
<mat-select-trigger>
<mat-icon>{{'entryType.' + entryType + '.icon' | i18n}}</mat-icon> {{'entryType.' + entryType | i18n}}
</mat-select-trigger>
@ -16,23 +18,24 @@
</mat-form-field>
<mat-form-field>
<input matInput placeholder="{{'submission.url' | i18n}}" formControlName="url" type="url"
[required]="entryType == 'LINK'" matAutofocus>
<mat-label>{{'submission.url' | i18n}}</mat-label>
<input matInput formControlName="url" type="url" [required]="entryType == 'LINK'" matAutofocus>
<mat-error *ngIf="hasError('url')">
{{'submission.url.error' | i18n}}
</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="{{'submission.title' | i18n}}" formControlName="title" type="text" required
(focus)="onTitleFocus($event)">
<mat-label>{{'submission.title' | i18n}}</mat-label>
<input matInput formControlName="title" type="text" required (focus)="onTitleFocus($event)">
<mat-error>
{{'submission.title.error' | i18n}}
</mat-error>
</mat-form-field>
<mat-form-field>
<textarea matAutosize matAutosizeMinRows="3" matInput placeholder="{{'submission.text' | i18n}}"
[required]="entryType != 'LINK'" formControlName="text"></textarea>
<mat-label>{{'submission.text' | i18n}}</mat-label>
<textarea matAutosize matAutosizeMinRows="3" matInput [required]="entryType != 'LINK'"
formControlName="text"></textarea>
<mat-error>
{{'submission.text.error' | i18n}}
</mat-error>

View File

@ -24,15 +24,15 @@
{{'login.invalid' | i18n}}
</mat-error>
<mat-form-field>
<input id="username" name="username" matInput placeholder="{{'username' | i18n}}" required
matAutofocus>
<mat-label>{{'username' | i18n}}</mat-label>
<input id="username" name="username" matInput required matAutofocus>
<mat-error>
{{'username.missing' | i18n}}
</mat-error>
</mat-form-field>
<mat-form-field>
<input id="password" name="password" matInput type="password"
placeholder="{{'password' | i18n}}" required>
<mat-label>{{'password' | i18n}}</mat-label>
<input id="password" name="password" matInput type="password" required>
<mat-error>
{{'password.invalid.hint' | i18n}}
</mat-error>

View File

@ -5,8 +5,8 @@
<input matInput [formControl]="searchFormControl">
</mat-form-field>
<mat-form-field>
<mat-select placeholder="{{'search.types' | i18n}}" [value]="searchType"
(selectionChange)="searchType = $event.value; refresh()">
<mat-label>{{'search.types' | i18n}}</mat-label>
<mat-select [value]="searchType" (selectionChange)="searchType = $event.value; refresh()">
<mat-select-trigger>
<span *ngIf="searchType">
<mat-icon>{{'search.types.' + searchType + '.icon' | i18n}}</mat-icon> {{'search.types.' +
@ -24,8 +24,8 @@
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-select placeholder="{{'search.byDate' | i18n}}" [value]="byDate"
(selectionChange)="byDate = $event.value; refresh()">
<mat-label>{{'search.byDate' | i18n}}</mat-label>
<mat-select [value]="byDate" (selectionChange)="byDate = $event.value; refresh()">
<mat-select-trigger>
<mat-icon>{{'search.byDate.' + byDate + '.icon' | i18n}}</mat-icon> {{'search.byDate.' +
byDate | i18n}}
@ -41,7 +41,8 @@
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-select placeholder="{{'search.asc' | i18n}}" [value]="asc" (selectionChange)="asc = $event.value; refresh()">
<mat-label>{{'search.asc' | i18n}}</mat-label>
<mat-select [value]="asc" (selectionChange)="asc = $event.value; refresh()">
<mat-select-trigger>
<mat-icon>{{'search.asc.' + asc + '.icon' | i18n}}</mat-icon> {{'search.asc.' +
asc | i18n}}

View File

@ -4,14 +4,15 @@
<mat-card-content>
<mat-card-title><a routerLink="/u/{{user.username}}">{{user.username}}</a></mat-card-title>
<mat-form-field>
<input matInput placeholder="{{'settings.email' | i18n}}" formControlName="email" type="email">
<mat-label>{{'settings.email' | i18n}}</mat-label>
<input matInput formControlName="email" type="email">
<mat-error *ngIf="hasError('email')">
{{'settings.email.error' | i18n}}
</mat-error>
</mat-form-field>
<mat-form-field>
<textarea matAutosize matAutosizeMinRows="3" matInput placeholder="{{'settings.about' | i18n}}"
formControlName="about"></textarea>
<mat-label>{{'settings.about' | i18n}}</mat-label>
<textarea matAutosize matAutosizeMinRows="3" matInput formControlName="about"></textarea>
<mat-error>
{{'settings.about.error' | i18n}}
</mat-error>
@ -24,8 +25,8 @@
mat-icon-button (click)="resetGravity()">
<mat-icon>cancel</mat-icon>
</button>
<input type="number" min="0" max="2" step="0.1" matInput placeholder="{{'settings.gravity' | i18n}}"
formControlName="gravity">
<mat-label>{{'settings.gravity' | i18n}}</mat-label>
<input type="number" min="0" max="2" step="0.1" matInput formControlName="gravity">
<mat-hint *ngIf="form.get('gravity').value != 0">
{{'settings.gravity.hint' | i18n}}
</mat-hint>
@ -39,8 +40,8 @@
mat-icon-button (click)="resetEntryDelay()">
<mat-icon>cancel</mat-icon>
</button>
<input type="number" min="0" max="15" step="1" matInput placeholder="{{'settings.entryDelay' | i18n}}"
formControlName="entryDelay">
<mat-label>{{'settings.entryDelay' | i18n}}</mat-label>
<input type="number" min="0" max="15" step="1" matInput formControlName="entryDelay">
<mat-hint *ngIf="form.get('entryDelay').value != 0">
{{'settings.entryDelay.hint' | i18n}}
</mat-hint>
@ -54,8 +55,8 @@
matPrefix mat-icon-button (click)="resetCommentDelay()">
<mat-icon>cancel</mat-icon>
</button>
<input type="number" min="0" max="15" step="1" matInput placeholder="{{'settings.commentDelay' | i18n}}"
formControlName="commentDelay">
<mat-label>{{'settings.commentDelay' | i18n}}</mat-label>
<input type="number" min="0" max="15" step="1" matInput formControlName="commentDelay">
<mat-hint *ngIf="form.get('commentDelay').value != 0">
{{'settings.commentDelay.hint' | i18n}}
</mat-hint>
@ -70,8 +71,8 @@
mat-icon-button (click)="resetPageSize()">
<mat-icon>cancel</mat-icon>
</button>
<input type="number" min="1" max="100" step="1" matInput placeholder="{{'settings.pageSize' | i18n}}"
formControlName="pageSize">
<mat-label>{{'settings.pageSize' | i18n}}</mat-label>
<input type="number" min="1" max="100" step="1" matInput formControlName="pageSize">
<mat-hint *ngIf="form.get('pageSize').value != 0">
{{'settings.pageSize.hint' | i18n}}
</mat-hint>

View File

@ -6,7 +6,8 @@
<p>{{ (view.id ? 'views.edit' : 'views.create') | i18n}}</p>
<mat-form-field>
<input matInput placeholder="{{'views.name' | i18n}}" formControlName="name" matAutofocus>
<mat-label>{{'views.name' | i18n}}</mat-label>
<input matInput formControlName="name" matAutofocus>
<mat-error *ngIf="hasError('name')">
<div *ngFor="let error of form.get('name').errors | keyvalue">
{{'views.name.error.' + error.key | i18n}}<br>
@ -15,7 +16,8 @@
</mat-form-field>
<mat-form-field>
<mat-select placeholder="{{'views.sorting' | i18n}}" formControlName="sorting">
<mat-label>{{'views.sorting' | i18n}}</mat-label>
<mat-select formControlName="sorting">
<mat-select-trigger>
<mat-icon>{{'sorting.' + sorting + '.icon' | i18n}}</mat-icon> {{'sorting.' + sorting | i18n}}
</mat-select-trigger>
@ -32,7 +34,8 @@
</ui-tagspicker>
<mat-form-field>
<mat-select placeholder="{{'views.entryType' | i18n}}" formControlName="entryType">
<mat-label>{{'views.entryType' | i18n}}</mat-label>
<mat-select formControlName="entryType">
<mat-select-trigger>
<span *ngIf="entryType">
<mat-icon>{{'entryType.' + entryType + '.icon' | i18n}}</mat-icon> {{'entryType.' +
@ -51,7 +54,8 @@
</mat-form-field>
<mat-form-field>
<input matInput placeholder="{{'views.index' | i18n}}" formControlName="index" type="number" min="0">
<mat-label>{{'views.index' | i18n}}</mat-label>
<input matInput formControlName="index" type="number" min="0">
<mat-error *ngIf="hasError('index')">
<div *ngFor="let error of form.get('index').errors | keyvalue">
{{'views.index.error.' + error.key | i18n}}<br>

View File

@ -68,8 +68,8 @@
<ng-container *ngIf="comment.metadata && comment.metadata.edit">
<form [formGroup]="form" (ngSubmit)="update()" #formDirective="ngForm">
<mat-form-field>
<textarea matAutosize matAutosizeMinRows="3" matInput formControlName="text"
placeholder="{{'comment.text' | i18n}}" required></textarea>
<mat-label>{{'comment.text' | i18n}}</mat-label>
<textarea matAutosize matAutosizeMinRows="3" matInput formControlName="text" required></textarea>
<mat-error *ngIf="hasError('text')">
{{'comment.text.error' | i18n}}
</mat-error>

View File

@ -1,7 +1,8 @@
<form [formGroup]="form" (ngSubmit)="create()" #formDirective="ngForm">
<mat-form-field>
<textarea matAutosize matAutosizeMinRows="3" matInput formControlName="text" placeholder="{{'comment.text' | i18n}}" required></textarea>
<mat-label>{{'comment.text' | i18n}}</mat-label>
<textarea matAutosize matAutosizeMinRows="3" matInput formControlName="text" required></textarea>
<mat-error *ngIf="hasError('text')">
{{'comment.text.error' | i18n}}
</mat-error>

View File

@ -35,27 +35,28 @@
<span class="spacer"></span>
<div class="mat-mdc-paginator flex wrap">
<div class="mat-mdc-paginator flex" [ngClass]="{'wrap' : filterOpen}">
<div *ngIf="filter" class="mat-mdc-paginator flex wrap filter-container">
<a mat-icon-button (click)="filterOpen=!filterOpen" title="{{'entries.filter' | i18n}}"
[color]="filterOpen ? 'accent' : 'primary'">
<mat-icon>filter_alt</mat-icon>
</a>
<div class="flex wrap filter" *ngIf="filterOpen">
<ui-tagspicker [(model)]="tags" placeholder="{{'entries.filter.tags' | i18n}}" [change]="boundTagsPickerChange">
<form class="flex wrap filter" *ngIf="filterOpen">
<ui-tagspicker [(model)]="tags" placeholder="{{'entries.filter.tags' | i18n}}" [change]="boundTagsPickerChange"
appearance="outline">
</ui-tagspicker>
<mat-form-field>
<mat-form-field appearance="outline">
<mat-label>{{'entries.filter.date' | i18n}}</mat-label>
<input matInput [matDatepicker]="picker" [value]="entries && entries.filter && entries.filter.date"
(dateChange)="setFilter('date', $event.value && $event.value.toISOString() || undefined)"
placeholder="{{'entries.filter.date' | i18n}}">
(dateChange)="setFilter('date', $event.value && $event.value.toISOString() || undefined)">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker touchUi></mat-datepicker>
</mat-form-field>
<mat-form-field>
<mat-select placeholder="{{'entries.filter.entryType' | i18n}}"
[value]="entries && entries.filter && entries.filter.type"
<mat-form-field appearance="outline">
<mat-label>{{'entries.filter.entryType' | i18n}}</mat-label>
<mat-select [value]="entries && entries.filter && entries.filter.type"
(selectionChange)="setFilter('type', $event.value || undefined)">
<mat-select-trigger>
<span *ngIf="entries.filter.type">
@ -75,16 +76,16 @@
</mat-form-field>
<ui-tagspicker [(model)]="excludedTags" placeholder="{{'entries.filter.excludedTags' | i18n}}"
[change]="boundExcludedTagsPickerChange">
[change]="boundExcludedTagsPickerChange" appearance="outline">
</ui-tagspicker>
<mat-form-field *ngIf="gravityFilter">
<mat-form-field *ngIf="gravityFilter" appearance="outline">
<mat-label>{{'entries.filter.gravity' | i18n}}</mat-label>
<input matInput type="number" step="0.01" min="0" max="2.0"
[value]="entries && entries.filter && entries.filter.gravity"
(change)="setFilter('gravity', $event.target && $event.target.value || undefined)"
placeholder="{{'entries.filter.gravity' | i18n}}">
(change)="setFilter('gravity', $event.target && $event.target.value || undefined)">
</mat-form-field>
</div>
</form>
</div>
<span class="spacer"></span>
<mat-paginator [pageSizeOptions]="pageSizeOptions" [pageIndex]="entries.number" [length]="entries.totalElements"

View File

@ -19,7 +19,7 @@
justify-content: flex-start;
align-items: center;
&> * {
&>* {
margin-top: 5px;
margin-bottom: 5px;
margin-left: 15px;

View File

@ -45,8 +45,8 @@
</mat-toolbar>
<mat-sidenav-container>
<mat-sidenav #sidenav [mode]="isBiggerScreen() ? 'side' : 'over'" [(opened)]="opened || searchFocus" [autoFocus]="false"
(click)="!isBiggerScreen() && this.close()">
<mat-sidenav #sidenav [mode]="isBiggerScreen() ? 'side' : 'over'" [(opened)]="opened || searchFocus"
[autoFocus]="false" (click)="!isBiggerScreen() && this.close()">
<mat-nav-list *ngIf="authenticated">
<ui-viewmenu></ui-viewmenu>
<mat-divider *ngIf="moderator"></mat-divider>
@ -65,8 +65,9 @@
</a>
</mat-nav-list>
<mat-form-field *ngIf="authenticated" (click)="preventClose($event)">
<mat-label>{{'search' | i18n}}</mat-label>
<input matInput type="text" (change)="search($event.target && $event.target.value || undefined, $event)"
placeholder="{{'search' | i18n}}" (focus)="searchFocus = true" (blur)="searchFocus = false">
(focus)="searchFocus = true" (blur)="searchFocus = false">
</mat-form-field>
<span class="spacer"></span>
<mat-nav-list>
@ -86,7 +87,8 @@
style="font-size: 0.7em;">
{{'page.privacy-policy' | i18n}}
</a>
<span style="font-size: 0.7em; margin-right: 1em; float: right;">v{{version}} <span *ngIf="hasUpdate" (click)="updateSw()">{{'updateSw' | i18n}}</span></span>
<span style="font-size: 0.7em; margin-right: 1em; float: right;">v{{version}} <span *ngIf="hasUpdate"
(click)="updateSw()">{{'updateSw' | i18n}}</span></span>
</mat-nav-list>
</mat-sidenav>

View File

@ -1,4 +1,5 @@
<mat-form-field>
<mat-form-field [appearance]="appearance">
<mat-label>{{placeholder}}</mat-label>
<mat-chip-grid #tagList>
<mat-chip-row *ngFor="let tag of tags" [removable]="true" (removed)="removeTag(tag)">
<mat-icon inline="true">tag</mat-icon>{{tag}}
@ -6,9 +7,9 @@
<mat-icon>cancel</mat-icon>
</button>
</mat-chip-row>
<input *ngIf="max == 0 || !tags || tags.length < max" #tagsInput placeholder="{{placeholder}}"
[formControl]="searchFormControl" [matAutocomplete]="auto" [matChipInputFor]="tagList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" (matChipInputTokenEnd)="addInputTag($event)">
<input *ngIf="max == 0 || !tags || tags.length < max" #tagsInput [formControl]="searchFormControl"
[matAutocomplete]="auto" [matChipInputFor]="tagList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="addInputTag($event)">
<mat-hint *ngIf="max > 1" align="end">{{tags && tags.length || 0}}/{{max}}</mat-hint>
</mat-chip-grid>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="addOptionTag($event)">

View File

@ -10,13 +10,14 @@ import { TagsService } from 'src/app/services/tags.service';
@Component({
selector: 'ui-tagspicker',
templateUrl: './tagspicker.ui.html',
styleUrls: [ './tagspicker.ui.scss' ]
styleUrls: ['./tagspicker.ui.scss']
})
export class UiTagsPicker implements OnInit {
@Input() change: Function;
@Input() model: any;
@Input() placeholder: string;
@Input() appearance: string;
@Input() max: number = 0;
tags: string[] = [];
searchTags: Observable<Object>;
@ -24,7 +25,7 @@ export class UiTagsPicker implements OnInit {
@ViewChild('tagsInput') tagsInput: ElementRef<HTMLInputElement>;
searchFormControl = new FormControl();
readonly separatorKeysCodes = [ ENTER, COMMA, SPACE ] as const;
readonly separatorKeysCodes = [ENTER, COMMA, SPACE] as const;
constructor(private tagsService: TagsService) { }

View File

@ -150,6 +150,7 @@ qrcode canvas {
max-width: 400px !important;
}
.flex {
display: flex !important;
@ -173,6 +174,16 @@ qrcode canvas {
}
}
@media (max-width: 576px) {
mat-paginator {
.mat-mdc-paginator-range-actions {
flex-wrap: wrap;
}
}
}
.scroll-container {
overflow: auto;
}