Skip to content

Commit

Permalink
Merge pull request #1067 from getodk/hover-cards
Browse files Browse the repository at this point in the history
Add hover cards
  • Loading branch information
matthew-white authored Dec 11, 2024
2 parents c9b8bef + 12afaf1 commit dbf6458
Show file tree
Hide file tree
Showing 65 changed files with 1,846 additions and 427 deletions.
3 changes: 1 addition & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ module.exports = {
'spaced-comment': 'off',
'vue/attributes-order': ['error', {
order: [
'DEFINITION',
'LIST_RENDERING',
'CONDITIONALS',
['CONDITIONALS', 'DEFINITION'],
'RENDER_MODIFIERS',
'GLOBAL',
['UNIQUE', 'SLOT'],
Expand Down
3 changes: 3 additions & 0 deletions src/assets/scss/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ $padding-top-btn: 6px;
$font-size-dropdown-menu: $font-size-btn;
$min-width-dropdown-menu: 150px;

$padding-block-dl: 10px;

// Forms
$padding-top-form-control: 6px;

Expand Down Expand Up @@ -94,6 +96,7 @@ $color-subpanel-border-strong: #c3c3c3;
$ease-extreme-out: cubic-bezier(.05, .9, 0, 1);



////////////////////////////////////////////////////////////////////////////////
// COMPONENTS

Expand Down
5 changes: 2 additions & 3 deletions src/assets/scss/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ p { @include text-block; }

dl > * {
border-bottom: 1px solid #ddd;
padding-bottom: 10px;
padding-top: 10px;
padding-block: $padding-block-dl;

&:first-of-type { padding-top: 0; }

Expand Down Expand Up @@ -75,7 +74,7 @@ dl:not(.dl-horizontal) {
// down to the fact that .dl-horizontal uses a CSS grid, while other <dl>
// elements use flexbox.
.dl-horizontal {
$padding-between: 10px;
$padding-between: 12px;
$dt-width: 160px + $padding-panel-body + $padding-between;

display: grid;
Expand Down
9 changes: 8 additions & 1 deletion src/components/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ except according to the terms contained in the LICENSE file.
<template v-else-if="$route.meta.standalone">
<router-view/>
</template>

<div id="tooltips"></div>
<hover-cards/>
</div>
</template>

Expand All @@ -48,7 +50,12 @@ import { loadAsync } from '../util/load-async';

export default {
name: 'App',
components: { Alert, Navbar, FeedbackButton: defineAsyncComponent(loadAsync('FeedbackButton')) },
components: {
Alert,
HoverCards: defineAsyncComponent(loadAsync('HoverCards')),
Navbar,
FeedbackButton: defineAsyncComponent(loadAsync('FeedbackButton'))
},
inject: ['alert', 'config'],
setup() {
const { visiblyLoggedIn } = useSessions();
Expand Down
48 changes: 31 additions & 17 deletions src/components/audit/row.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ except according to the terms contained in the LICENSE file.
</td>
<td class="target">
<template v-if="target != null">
<router-link v-if="target.path != null" :to="target.path"
<component v-if="target.component != null" :is="target.component"
v-bind="target.props" v-tooltip.text/>
<router-link v-else-if="target.path != null" :to="target.path"
v-tooltip.text>
{{ target.title }}
</router-link>
Expand All @@ -47,7 +49,11 @@ except according to the terms contained in the LICENSE file.
</template>

<script>
import { pick } from 'ramda';

import ActorLink from '../actor-link.vue';
import DatasetLink from '../dataset/link.vue';
import FormLink from '../form/link.vue';
import DateTime from '../date-time.vue';
import Selectable from '../selectable.vue';

Expand Down Expand Up @@ -88,10 +94,13 @@ const acteeSpeciesByCategory = {
},
form: {
title: (actee) => (actee.name != null ? actee.name : actee.xmlFormId),
path: (actee, { primaryFormPath }) => primaryFormPath(actee)
component: FormLink,
props: (actee) => ({ form: actee })
},
dataset: {
title: (actee) => actee.name
title: (actee) => actee.name,
component: DatasetLink,
props: pick(['projectId', 'name'])
},
public_link: {
title: getDisplayName
Expand All @@ -107,7 +116,7 @@ acteeSpeciesByCategory.upgrade = acteeSpeciesByCategory.form;

export default {
name: 'AuditRow',
components: { ActorLink, DateTime, Selectable },
components: { ActorLink, DatasetLink, DateTime, FormLink, Selectable },
props: {
audit: {
type: Object,
Expand All @@ -116,8 +125,8 @@ export default {
},
setup() {
const { actionMessage } = useAudit();
const { projectPath, primaryFormPath, userPath } = useRoutes();
return { actionMessage, projectPath, primaryFormPath, userPath };
const { projectPath, userPath } = useRoutes();
return { actionMessage, projectPath, userPath };
},
computed: {
// When an audit log action has multiple parts/segments, we treat it as
Expand All @@ -144,18 +153,23 @@ export default {
if (this.category == null) return null;
const species = acteeSpeciesByCategory[this.category];
if (species == null) return null;
const { actee } = this.audit;

// purged actee (used purgedName as title)
if (actee.purgedAt != null)
return { title: actee.purgedName, purged: true };

const title = species.title(actee);
// soft-deleted actee (use species title but don't make a link)
if (actee.deletedAt != null) return { title, deleted: true };

const result = { title };
if (species.path != null) result.path = species.path(actee, this);
const { actee } = this.audit;
const deleted = actee.deletedAt != null;
const purged = actee.purgedAt != null;
const result = {
title: purged ? actee.purgedName : species.title(actee),
deleted,
purged
};
if (!(deleted || purged)) {
if (species.path != null) {
result.path = species.path(actee, this);
} else if (species.component != null) {
result.component = species.component;
result.props = species.props(actee);
}
}
return result;
},
details() {
Expand Down
44 changes: 44 additions & 0 deletions src/components/dataset/link.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!--
Copyright 2024 ODK Central Developers
See the NOTICE file at the top-level directory of this distribution and at
https://github.com/getodk/central-frontend/blob/master/NOTICE.

This file is part of ODK Central. It is subject to the license terms in
the LICENSE file found in the top-level directory of this distribution and at
https://www.apache.org/licenses/LICENSE-2.0. No part of ODK Central,
including this file, may be copied, modified, propagated, or distributed
except according to the terms contained in the LICENSE file.
-->

<!-- Specifying :key so that if `to` changes, the element will be replaced. If a
hover card is shown next to the element, it will be hidden. -->
<template>
<router-link ref="link" :key="to" :to="to">{{ name }}</router-link>
</template>

<script setup>
import { computed, ref } from 'vue';

import useHoverCard from '../../composables/hover-card';
import useRoutes from '../../composables/routes';

defineOptions({
name: 'DatasetLink'
});
const props = defineProps({
projectId: {
type: [Number, String],
required: true
},
name: {
type: String,
required: true
}
});

const { datasetPath } = useRoutes();
const to = computed(() => datasetPath(props.projectId, props.name));

const link = ref(null);
useHoverCard(computed(() => link.value?.$el), 'dataset', () => props);
</script>
9 changes: 4 additions & 5 deletions src/components/dataset/row.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ except according to the terms contained in the LICENSE file.
<template>
<tr class="dataset-row">
<td class="name">
<router-link :to="datasetOverviewPage" v-tooltip.text>{{ dataset.name }}</router-link>
<dataset-link :project-id="dataset.projectId" :name="dataset.name"
v-tooltip.text/>
</td>
<td class="entities">
<span>{{ $n(dataset.entities, 'default') }}</span>
Expand All @@ -39,14 +40,15 @@ except according to the terms contained in the LICENSE file.
</template>

<script>
import DatasetLink from './link.vue';
import DateTime from '../date-time.vue';

import useRoutes from '../../composables/routes';
import { apiPaths } from '../../util/request';

export default {
name: 'DatasetRow',
components: { DateTime },
components: { DatasetLink, DateTime },
props: {
dataset: {
type: Object,
Expand All @@ -60,9 +62,6 @@ export default {
computed: {
href() {
return apiPaths.entities(this.dataset.projectId, this.dataset.name, '.csv');
},
datasetOverviewPage() {
return this.datasetPath(this.dataset.projectId, this.dataset.name);
}
}
};
Expand Down
3 changes: 1 addition & 2 deletions src/components/dataset/show.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ https://www.apache.org/licenses/LICENSE-2.0. No part of ODK Central,
including this file, may be copied, modified, propagated, or distributed
except according to the terms contained in the LICENSE file.
-->

<template>
<div id="dataset-show">
<breadcrumbs v-if="dataExists" :links="breadcrumbLinks"/>
Expand Down Expand Up @@ -84,7 +83,7 @@ export default {
const { tabPath, tabClass } = useTabs(datasetPath());
return {
project, dataset, ...resourceStates([project, dataset]),
projectPath, datasetPath, tabPath, tabClass, canRoute
projectPath, tabPath, tabClass, canRoute
};
},
computed: {
Expand Down
14 changes: 4 additions & 10 deletions src/components/dataset/summary/row.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ except according to the terms contained in the LICENSE file.
<div class="row">
<div class="col-xs-6 dataset-name-wrap">
<div class="dataset-name text-overflow-ellipsis" v-tooltip.text>
<router-link v-if="!dataset.isNew" :to="datasetPath(projectId, dataset.name)" v-tooltip.text>
{{ dataset.name }}
</router-link>
<dataset-link v-if="!dataset.isNew" :project-id="projectId"
:name="dataset.name"/>
<template v-else>
{{ dataset.name }}
</template>
Expand Down Expand Up @@ -50,13 +49,12 @@ except according to the terms contained in the LICENSE file.
</template>

<script>
import DatasetLink from '../link.vue';
import I18nList from '../../i18n/list.vue';

import useRoutes from '../../../composables/routes';

export default {
name: 'DatasetSummaryRow',
components: { I18nList },
components: { DatasetLink, I18nList },
props: {
dataset: {
type: Object,
Expand All @@ -67,10 +65,6 @@ export default {
required: true
}
},
setup() {
const { datasetPath } = useRoutes();
return { datasetPath };
},
data() {
return {
expanded: false
Expand Down
11 changes: 4 additions & 7 deletions src/components/entity/basic-details.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ except according to the terms contained in the LICENSE file.
<div v-if="submission != null">
<dt>{{ $t('creatingSubmission') }}</dt>
<dd id="entity-basic-details-creating-submission">
<router-link v-if="submission.currentVersion != null"
:to="submissionPath(projectId, submission.xmlFormId, submission.instanceId)">
{{ submission.currentVersion.instanceName ?? submission.instanceId }}
</router-link>
<submission-link v-if="submission.currentVersion != null"
:project-id="projectId" :xml-form-id="submission.xmlFormId"
:submission="submission"/>
<template v-else>
<span class="icon-trash" v-tooltip.sr-only></span>
<span>{{ submission.instanceId }}</span>
Expand Down Expand Up @@ -55,8 +54,8 @@ import { inject, ref, watchEffect } from 'vue';
import ActorLink from '../actor-link.vue';
import DateTime from '../date-time.vue';
import PageSection from '../page/section.vue';
import SubmissionLink from '../submission/link.vue';

import useRoutes from '../../composables/routes';
import { useRequestData } from '../../request-data';

defineOptions({
Expand All @@ -83,8 +82,6 @@ watchEffect(() => {
submission.value = audit.details.source?.submission;
source.value = audit.details.source;
});

const { submissionPath } = useRoutes();
</script>

<style lang="scss">
Expand Down
Loading

0 comments on commit dbf6458

Please sign in to comment.