diff --git a/.eslintrc.js b/.eslintrc.js index 04081bc90..e02011018 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -53,6 +53,21 @@ module.exports = { asyncArrow: 'always' }], 'spaced-comment': 'off', + 'vue/attributes-order': ['error', { + order: [ + 'DEFINITION', + 'LIST_RENDERING', + 'CONDITIONALS', + 'RENDER_MODIFIERS', + 'GLOBAL', + ['UNIQUE', 'SLOT'], + 'TWO_WAY_BINDING', + ['OTHER_DIRECTIVES', 'OTHER_ATTR'], + 'EVENTS', + 'CONTENT' + ], + alphabetical: false + }], 'vue/first-attribute-linebreak': 'off', 'vue/html-closing-bracket-newline': ['error', { singleline: 'never', diff --git a/package-lock.json b/package-lock.json index 12ccaca3e..be11944ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "odk-central-frontend", "version": "0.1.0", "dependencies": { + "@floating-ui/dom": "^1.1.0", "axios": "^0.22.0", "bootstrap": "~3", "dompurify": "~2", @@ -507,6 +508,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@floating-ui/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.1.0.tgz", + "integrity": "sha512-zbsLwtnHo84w1Kc8rScAo5GMk1GdecSlrflIbfnEBJwvTSj1SL6kkOYV+nHraMCPEy+RNZZUaZyL8JosDGCtGQ==" + }, + "node_modules/@floating-ui/dom": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.1.0.tgz", + "integrity": "sha512-TSogMPVxbRe77QCj1dt8NmRiJasPvuc+eT5jnJ6YpLqgOD2zXc5UA3S1qwybN+GVCDNdKfpKy1oj8RpzLJvh6A==", + "dependencies": { + "@floating-ui/core": "^1.0.5" + } + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -13029,6 +13043,19 @@ } } }, + "@floating-ui/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.1.0.tgz", + "integrity": "sha512-zbsLwtnHo84w1Kc8rScAo5GMk1GdecSlrflIbfnEBJwvTSj1SL6kkOYV+nHraMCPEy+RNZZUaZyL8JosDGCtGQ==" + }, + "@floating-ui/dom": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.1.0.tgz", + "integrity": "sha512-TSogMPVxbRe77QCj1dt8NmRiJasPvuc+eT5jnJ6YpLqgOD2zXc5UA3S1qwybN+GVCDNdKfpKy1oj8RpzLJvh6A==", + "requires": { + "@floating-ui/core": "^1.0.5" + } + }, "@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", diff --git a/package.json b/package.json index 32312205b..0c7ce8cbc 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "pre-commit": "node bin/transifex/restructure.js && git diff --exit-code -- transifex/strings_en.json" }, "dependencies": { + "@floating-ui/dom": "^1.1.0", "axios": "^0.22.0", "bootstrap": "~3", "dompurify": "~2", diff --git a/src/assets/scss/app.scss b/src/assets/scss/app.scss index d1cfae79f..8c1ec7e72 100644 --- a/src/assets/scss/app.scss +++ b/src/assets/scss/app.scss @@ -74,6 +74,23 @@ em:lang(ja) { font-weight: bold; } +.tooltip { + /* v-tooltip.aria-describedby tooltips are rendered before they are shown + on-screen. `display` is not set to `none` for those tooltips. Instead, they + are transparent. However, we do need to position them: otherwise, they would + result in extra space at the bottom of the page. I tried using the sr-only + class, but that resulted in Floating UI miscalculating the position of the + tooltip. Instead, tooltips will be positioned at the top of the page. */ + top: 0; + // Move the tooltip to the left so that it doesn't obstruct the navbar. + left: -1000px; +} +.tooltip-inner { + overflow-wrap: break-word; + // Allow the text to have line breaks. + white-space: pre-line; +} + //////////////////////////////////////////////////////////////////////////////// @@ -198,8 +215,8 @@ a, .btn-link { a { &.disabled, fieldset[disabled] & { - // Not specifying pointer-events so that the cursor and any title attribute - // is shown. + // Not specifying pointer-events so that the cursor and any tooltip is + // shown. &.btn { color: #fff; } } diff --git a/src/components/actor-link.vue b/src/components/actor-link.vue index 3bc09fc79..a7cbea94a 100644 --- a/src/components/actor-link.vue +++ b/src/components/actor-link.vue @@ -10,8 +10,8 @@ including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file. --> diff --git a/src/components/form/head.vue b/src/components/form/head.vue index 5ec90079c..425da9b9c 100644 --- a/src/components/form/head.vue +++ b/src/components/form/head.vue @@ -21,7 +21,7 @@ except according to the terms contained in the LICENSE file.
-
+
{{ form.nameOrId }}
@@ -33,34 +33,37 @@ except according to the terms contained in the LICENSE file. to render the tabs even if the form does not have a published version (in which case canRoute() will return `false`). -->
  • - + role="presentation"> + {{ $t('common.tab.overview') }}
  • -
  • - +
  • + {{ $t('formHead.tab.versions') }}
  • -
  • - +
  • + {{ $t('resource.submissions') }}
  • - + role="presentation"> + {{ $t('formHead.tab.publicAccess') }}
  • - + role="presentation"> + {{ $t('common.tab.settings') }}
  • @@ -132,7 +135,7 @@ export default { rendersFormTabs() { return this.project.dataExists && this.project.permits(['form.update']); }, - formTabTitle() { + formTabDescription() { return this.form.dataExists && this.form.publishedAt == null ? this.$t('formNav.tabTitle') : null; diff --git a/src/components/form/row.vue b/src/components/form/row.vue index a5c4d541d..57838704a 100644 --- a/src/components/form/row.vue +++ b/src/components/form/row.vue @@ -21,7 +21,7 @@ except according to the terms contained in the LICENSE file.