diff --git a/app/jest.config.js b/app/jest.config.js new file mode 100644 index 0000000000..d59a9936d4 --- /dev/null +++ b/app/jest.config.js @@ -0,0 +1,5 @@ +/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', +}; diff --git a/app/package.json b/app/package.json index b9e9f326dd..10fada407c 100644 --- a/app/package.json +++ b/app/package.json @@ -24,7 +24,9 @@ "scripts": { "dev": "vite", "build": "vite build", - "serve": "vite preview" + "serve": "vite preview", + "test": "jest --coverage", + "test:watch": "jest --coverage --watchAll" }, "gitHead": "24621f3934dc77eb23441331040ed13c676ceffd", "devDependencies": { @@ -55,6 +57,7 @@ "@types/diff": "5.0.1", "@types/dompurify": "2.3.1", "@types/geojson": "7946.0.8", + "@types/jest": "27.4.0", "@types/lodash": "4.14.177", "@types/mapbox__mapbox-gl-draw": "1.2.3", "@types/mapbox__mapbox-gl-geocoder": "4.7.1", @@ -80,6 +83,7 @@ "flatpickr": "4.6.9", "front-matter": "4.0.2", "html-entities": "2.3.2", + "jest": "27.4.7", "jsonlint-mod": "1.7.6", "maplibre-gl": "1.15.2", "marked": "4.0.10", @@ -95,6 +99,7 @@ "rimraf": "3.0.2", "sass": "1.43.4", "tinymce": "5.10.2", + "ts-jest": "27.1.3", "typescript": "4.5.2", "vite": "2.6.14", "vite-plugin-md": "0.11.4", diff --git a/app/src/interfaces/input-multiline/index.ts b/app/src/interfaces/input-multiline/index.ts index 7fb7442e5a..2fe06275e5 100644 --- a/app/src/interfaces/input-multiline/index.ts +++ b/app/src/interfaces/input-multiline/index.ts @@ -23,6 +23,19 @@ export default defineInterface({ }, }, }, + { + field: 'softLength', + name: '$t:soft_length', + type: 'integer', + meta: { + width: 'half', + interface: 'input', + options: { + placeholder: '255', + min: 1, + }, + }, + }, { field: 'trim', name: '$t:interfaces.input.trim', diff --git a/app/src/interfaces/input-multiline/input-multiline.vue b/app/src/interfaces/input-multiline/input-multiline.vue index df0ba7d00c..b3d07d218c 100644 --- a/app/src/interfaces/input-multiline/input-multiline.vue +++ b/app/src/interfaces/input-multiline/input-multiline.vue @@ -6,11 +6,24 @@ :disabled="disabled" :class="font" @update:model-value="$emit('input', $event)" - /> + > + + @@ -57,4 +100,28 @@ export default defineComponent({ --v-textarea-font-family: var(--family-sans-serif); } } + +.remaining { + position: absolute; + right: 10px; + bottom: 5px; + width: 24px; + color: var(--foreground-subdued); + font-weight: 600; + text-align: right; + vertical-align: middle; + font-feature-settings: 'tnum'; +} + +.v-input:focus-within .remaining { + display: block; +} + +.v-input:focus-within .hide { + display: none; +} + +.warning { + color: var(--warning); +} diff --git a/app/src/interfaces/input-rich-text-html/index.ts b/app/src/interfaces/input-rich-text-html/index.ts index 75cd30c4a3..91af08c538 100644 --- a/app/src/interfaces/input-rich-text-html/index.ts +++ b/app/src/interfaces/input-rich-text-html/index.ts @@ -268,6 +268,19 @@ export default defineInterface({ }, ], advanced: [ + { + field: 'softLength', + name: '$t:soft_length', + type: 'integer', + meta: { + width: 'half', + interface: 'input', + options: { + placeholder: '255', + min: 1, + }, + }, + }, { field: 'customFormats', name: '$t:interfaces.input-rich-text-html.custom_formats', diff --git a/app/src/interfaces/input-rich-text-html/input-rich-text-html.vue b/app/src/interfaces/input-rich-text-html/input-rich-text-html.vue index 98f3b33704..e7cf2f3a27 100644 --- a/app/src/interfaces/input-rich-text-html/input-rich-text-html.vue +++ b/app/src/interfaces/input-rich-text-html/input-rich-text-html.vue @@ -1,5 +1,5 @@