Skip to content

Commit

Permalink
Merge pull request getodk#358 from getodk/public-links
Browse files Browse the repository at this point in the history
Add public links
  • Loading branch information
matthew-white authored Aug 10, 2020
2 parents 35366bc + 4810478 commit 57f0268
Show file tree
Hide file tree
Showing 85 changed files with 2,571 additions and 842 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Most components are named according to the combination of a resource and an acti
* `Row`. A row of a `*Table` component.
* `Show`. A component that shows a single resource of a particular type.
* `Home`. A parent component of related components, for example, `SystemHome`.
* `New`. A modal used to create a new resource of a particular type.
* `Create` (or `New`). A modal used to create a new resource of a particular type.
* `Edit`. A component used to update an existing resource of a particular type.
* `Delete`. A modal used to delete an existing resource of a particular type.

Expand Down
8 changes: 8 additions & 0 deletions src/assets/scss/_mixins.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@import './variables';

// A list that shows descriptive text
@mixin text-list {
max-width: $max-width-p;

li { margin-bottom: 5px; }
}
4 changes: 4 additions & 0 deletions src/assets/scss/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ $color-page-background: #f7f7f7;
// Text
$color-text: #333;
$font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace;
// 15-17 words per line
$max-width-p: 600px;

// Icons
$margin-right-icon: 6px;

// Contextual colors
$color-success: #0d840f;
$color-success-light: #ddf1d5;
Expand Down
26 changes: 18 additions & 8 deletions src/assets/scss/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ including this file, may be copied, modified, propagated, or distributed
except according to the terms contained in the LICENSE file.
*/

@import './variables';
@import './mixins';

html {
background-color: $color-accent-secondary;
Expand All @@ -31,10 +31,7 @@ h1, .h1 {
margin-bottom: 3px;
}

p {
// 15-17 words per line
max-width: 600px;
}
p { max-width: $max-width-p; }



Expand All @@ -49,7 +46,7 @@ p {
vertical-align: -1px;

.btn > &:first-child, a > &:first-child {
margin-right: 6px;
margin-right: $margin-right-icon;
+ .caret { margin-left: 0; }
}

Expand Down Expand Up @@ -338,13 +335,26 @@ a {
////////////////////////////////////////////////////////////////////////////////
// PAGE STRUCTURE

.heading-with-button {
/*
Most pages render a PageHead and a PageBody. The PageBody will often contain one
or more PageSection components. Some pages use .panel-simple, but this is an
older pattern: try to use PageSection instead.
The PageBody component may show a heading at the top. Right now we implement
this using the page-body-heading class, but we may create a component if it
becomes more complicated.
*/

// .heading-with-button is deprecated: use .page-body-heading instead.
.page-body-heading, .heading-with-button {
margin-bottom: 25px;

> button {
> .btn {
float: right;
margin-left: 20px;
}

ul { @include text-list; }
}


Expand Down
4 changes: 3 additions & 1 deletion src/components/audit/filters.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ export default {
</script>

<style lang="scss">
@import '../../assets/scss/variables';

#audit-filters {
.icon-filter {
color: #999;
margin-right: 6px;
margin-right: $margin-right-icon;
}

.form-group {
Expand Down
8 changes: 7 additions & 1 deletion src/components/audit/filters/action.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ const options = [
actionOption('form.update.publish'),
actionOption('form.update.draft.delete'),
actionOption('form.attachment.update'),
actionOption('form.delete')
actionOption('form.delete'),
categoryOption('field_key'),
actionOption('field_key.create'),
categoryOption('public_link'),
actionOption('public_link.create'),
categoryOption('session'),
actionOption('session.end')
];

export default {
Expand Down
8 changes: 1 addition & 7 deletions src/components/audit/list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ except according to the terms contained in the LICENSE file.
-->
<template>
<div>
<p id="audit-list-heading">{{ $t('heading[0]') }}</p>
<p class="page-body-heading">{{ $t('heading[0]') }}</p>
<audit-filters v-bind.sync="filters"/>
<audit-table :audits="audits"/>
<loading :state="$store.getters.initiallyLoading(['audits'])"/>
Expand Down Expand Up @@ -75,12 +75,6 @@ export default {
};
</script>

<style lang="scss">
#audit-list-heading {
margin-bottom: 20px;
}
</style>

<i18n lang="json5">
{
"en": {
Expand Down
69 changes: 32 additions & 37 deletions src/components/audit/row.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ except according to the terms contained in the LICENSE file.
<template>
<tr class="audit-row">
<td><date-time :iso="audit.loggedAt"/></td>
<td>
<td class="type">
{{ type[0] }}
<template v-if="type.length > 1">
<span class="icon-angle-right"></span> {{ type[1] }}
Expand All @@ -25,37 +25,44 @@ except according to the terms contained in the LICENSE file.
</router-link>
</td>
<td class="target">
<router-link v-if="target != null" :to="target.path"
:title="target.title">
{{ target.title }}
</router-link>
</td>
<td class="details">
<!-- Adding a <div> to work around a Firefox bug: see
https://bugzilla.mozilla.org/show_bug.cgi?id=386970. -->
<div ref="details" @click="selectDetails">{{ details }}</div>
<template v-if="target != null">
<router-link v-if="target.path != null" :to="target.path"
:title="target.title">
{{ target.title }}
</router-link>
<span v-else :title="target.title">{{ target.title }}</span>
</template>
</td>
<td><selectable>{{ details }}</selectable></td>
</tr>
</template>

<script>
import DateTime from '../date-time.vue';
import Form from '../../presenters/form';
import Selectable from '../selectable.vue';
import i18n from '../../i18n';
import routes from '../../mixins/routes';
import { auditActionMessage } from '../../util/i18n';

const typeByCategory = {
user: i18n.t('common.user'),
assignment: i18n.t('common.user'),
project: i18n.t('common.project'),
form: i18n.t('common.form'),
session: i18n.t('resource.session'),
user: i18n.t('resource.user'),
assignment: i18n.t('resource.user'),
project: i18n.t('resource.project'),
form: i18n.t('resource.form'),
public_link: i18n.t('resource.publicLink'),
field_key: i18n.t('resource.appUser'),
upgrade: i18n.t('audit.category.upgrade')
};

const getDisplayName = ({ displayName }) => displayName;
const acteeSpeciesByCategory = {
session: {
title: getDisplayName
},
user: {
title: ({ displayName }) => displayName,
title: getDisplayName,
path: ({ id }, vm) => vm.userPath(id)
},
project: {
Expand All @@ -65,6 +72,12 @@ const acteeSpeciesByCategory = {
form: {
title: (form) => new Form(form).nameOrId(),
path: (form, vm) => vm.primaryFormPath(form)
},
public_link: {
title: getDisplayName
},
field_key: {
title: getDisplayName
}
};
acteeSpeciesByCategory.assignment = acteeSpeciesByCategory.user;
Expand All @@ -75,7 +88,7 @@ acteeSpeciesByCategory.upgrade = acteeSpeciesByCategory.form;

export default {
name: 'AuditRow',
components: { DateTime },
components: { DateTime, Selectable },
mixins: [routes()],
props: {
audit: {
Expand All @@ -100,32 +113,20 @@ export default {
const species = acteeSpeciesByCategory[this.category];
if (species == null) return null;
const { actee } = this.audit;
return {
path: species.path(actee, this),
title: species.title(actee)
};
const result = { title: species.title(actee) };
if (species.path != null) result.path = species.path(actee, this);
return result;
},
details() {
return this.audit.details != null
? JSON.stringify(this.audit.details)
: '';
}
},
methods: {
selectDetails() {
if (this.audit.details == null) return;
const selection = window.getSelection();
// Select the entire JSON unless the user has selected specific text.
if (selection.isCollapsed)
selection.selectAllChildren(this.$refs.details);
}
}
};
</script>

<style lang="scss">
@import '../../assets/scss/variables';

.audit-row {
.table tbody & td {
vertical-align: middle;
Expand All @@ -141,11 +142,5 @@ export default {
text-overflow: ellipsis;
white-space: nowrap;
}

.details div {
font-family: $font-family-monospace;
overflow-x: auto;
white-space: nowrap;
}
}
</style>
4 changes: 0 additions & 4 deletions src/components/audit/table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ export default {
#audit-table {
table-layout: fixed;
}

#audit-table th.details {
width: 33.33333333%;
}
</style>

<i18n lang="json5">
Expand Down
Loading

0 comments on commit 57f0268

Please sign in to comment.