Skip to content

Commit

Permalink
Finish replacing modal mixin with modalData() (#990)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthew-white authored May 8, 2024
1 parent ed5162b commit a54cf7b
Show file tree
Hide file tree
Showing 19 changed files with 125 additions and 305 deletions.
4 changes: 0 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,6 @@ Most components are named according to the combination of a resource and an acti
* `Edit` or `Update`. 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.

### Vue Mixins

Each component may use one or more mixins. Each file in [`/src/mixins/`](/src/mixins/) exports a mixin factory for a single type of mixin. (We use factories so that the component can pass in options for the mixin. We don't use this pattern much anymore though, so we will likely change this when we move to Vue 3.)

### Composables

Each component may use one or more of the composables in [`/src/composables/`](/src/composables/). Most composables will reside in that directory, but if it makes sense to group a composable with other functionality, it may be defined elsewhere. For example, the `useSessions()` composable is defined in [`/src/util/session.js`](/src/util/session.js).
Expand Down
17 changes: 5 additions & 12 deletions src/components/analytics/list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ except according to the terms contained in the LICENSE file.
</div>
<loading :state="initiallyLoading"/>
<template v-if="dataExists">
<analytics-form @preview="showModal('preview')"/>
<analytics-form @preview="previewModal.show()"/>
<page-section v-if="audits.length !== 0">
<template #heading>
<span>{{ $t('auditsTitle') }}</span>
Expand All @@ -32,7 +32,7 @@ except according to the terms contained in the LICENSE file.
</template>
</page-section>
</template>
<analytics-preview v-bind="preview" @hide="hideModal('preview')"/>
<analytics-preview v-bind="previewModal" @hide="previewModal.hide()"/>
</div>
</template>

Expand All @@ -43,8 +43,8 @@ import AuditTable from '../audit/table.vue';
import Loading from '../loading.vue';
import PageSection from '../page/section.vue';

import modal from '../../mixins/modal';
import { apiPaths } from '../../util/request';
import { modalData } from '../../util/reactivity';
import { useRequestData } from '../../request-data';

export default {
Expand All @@ -56,19 +56,12 @@ export default {
Loading,
PageSection
},
mixins: [modal()],
setup() {
const { analyticsConfig, createResource, resourceStates } = useRequestData();
const audits = createResource('audits');
return {
analyticsConfig, audits, ...resourceStates([analyticsConfig, audits])
};
},
data() {
return {
preview: {
state: false
}
analyticsConfig, audits, ...resourceStates([analyticsConfig, audits]),
previewModal: modalData()
};
},
created() {
Expand Down
23 changes: 9 additions & 14 deletions src/components/form-attachment/link-dataset.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ except according to the terms contained in the LICENSE file.
<template #title>{{ $t('title') }}</template>
<template #body>
<div class="modal-introduction">
<p>
<span>{{ $t('introduction[0]') }}</span>
<sentence-separator/>
<template v-if="blobExists">{{ $t('introduction[1]') }}</template>
</p>
<p>
<span>{{ $t('introduction[0]') }}</span>
<sentence-separator/>
<template v-if="attachment != null && attachment.blobExists">
{{ $t('introduction[1]') }}
</template>
</p>
</div>
<div class="modal-actions">
<button type="button" class="btn btn-primary btn-link-dataset"
Expand Down Expand Up @@ -53,14 +55,7 @@ export default {
type: Boolean,
default: false
},
attachmentName: {
type: String,
required: true
},
blobExists: {
type: Boolean,
default: false
}
attachment: Object
},
emits: ['hide', 'success'],
setup() {
Expand All @@ -72,7 +67,7 @@ export default {
link() {
this.request({
method: 'PATCH',
url: apiPaths.formDraftAttachment(this.form.projectId, this.form.xmlFormId, this.attachmentName),
url: apiPaths.formDraftAttachment(this.form.projectId, this.form.xmlFormId, this.attachment.name),
data: { dataset: true }
})
.then(() => {
Expand Down
47 changes: 17 additions & 30 deletions src/components/form-attachment/list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ except according to the terms contained in the LICENSE file.
:styled="false" @dragenter="dragenter" @dragleave="dragleave" @drop="drop">
<div class="heading-with-button">
<button type="button" class="btn btn-primary"
@click="showModal('uploadFilesModal')">
@click="uploadFilesModal.show()">
<span class="icon-cloud-upload"></span>{{ $t('action.upload') }}&hellip;
</button>
<p>{{ $t('heading[0]') }}</p>
Expand Down Expand Up @@ -56,7 +56,7 @@ except according to the terms contained in the LICENSE file.
:planned-uploads="plannedUploads"
:updated-attachments="updatedAttachments" :data-name="attachment.name"
:linkable="attachment.type === 'file' && !!dsHashset && dsHashset.has(attachment.name.replace(/\.[^.]+$/i, ''))"
@link="showLinkDatasetModal($event)"/>
@link="linkDatasetModal.show({ attachment: $event })"/>
</tbody>
</table>
<form-attachment-popups
Expand All @@ -67,12 +67,12 @@ except according to the terms contained in the LICENSE file.
@confirm="uploadFiles" @cancel="cancelUploads"/>

<form-attachment-upload-files v-bind="uploadFilesModal"
@hide="hideModal('uploadFilesModal')" @select="afterFileInputSelection"/>
<form-attachment-name-mismatch :state="nameMismatch.state"
:planned-uploads="plannedUploads" @hide="hideModal('nameMismatch')"
@hide="uploadFilesModal.hide()" @select="afterFileInputSelection"/>
<form-attachment-name-mismatch v-bind="nameMismatch"
:planned-uploads="plannedUploads" @hide="nameMismatch.hide()"
@confirm="uploadFiles" @cancel="cancelUploads"/>
<form-attachment-link-dataset v-bind="linkDatasetModal" @hide="hideModal('linkDatasetModal')"
@success="afterLinkDataset"/>
<form-attachment-link-dataset v-bind="linkDatasetModal"
@hide="linkDatasetModal.hide()" @success="afterLinkDataset"/>
</file-drop-zone>
</template>

Expand All @@ -88,9 +88,9 @@ import FormAttachmentRow from './row.vue';
import FormAttachmentUploadFiles from './upload-files.vue';
import SentenceSeparator from '../sentence-separator.vue';

import modal from '../../mixins/modal';
import useRequest from '../../composables/request';
import { apiPaths } from '../../util/request';
import { modalData } from '../../util/reactivity';
import { noop } from '../../util/util';
import { useRequestData } from '../../request-data';

Expand All @@ -106,7 +106,6 @@ export default {
FormAttachmentUploadFiles,
SentenceSeparator
},
mixins: [modal()],
inject: ['alert'],
props: {
projectId: {
Expand Down Expand Up @@ -165,16 +164,9 @@ export default {
},
updatedAttachments: new Set(),
// Modals
uploadFilesModal: {
state: false
},
nameMismatch: {
state: false
},
linkDatasetModal: {
state: false,
attachmentName: ''
}
uploadFilesModal: modalData(),
nameMismatch: modalData(),
linkDatasetModal: modalData()
};
},
computed: {
Expand Down Expand Up @@ -203,7 +195,7 @@ export default {
// FILE INPUT

afterFileInputSelection(files) {
this.hideModal('uploadFilesModal');
this.uploadFilesModal.hide();
this.updatedAttachments.clear();
this.matchFilesToAttachments(files);
},
Expand Down Expand Up @@ -247,7 +239,7 @@ export default {
if (upload.file.name === upload.attachment.name)
this.uploadFiles();
else
this.showModal('nameMismatch');
this.nameMismatch.show();
} else {
// The else case can be reached even if this.countOfFilesOverDropZone
// was 1, if the drop was not over a row.
Expand Down Expand Up @@ -367,24 +359,19 @@ export default {
resend: false
}).catch(noop);
},
showLinkDatasetModal({ name, blobExists }) {
this.linkDatasetModal.attachmentName = name;
this.linkDatasetModal.blobExists = blobExists;
this.showModal('linkDatasetModal');
},
afterLinkDataset() {
const { attachment } = this.linkDatasetModal;
this.linkDatasetModal.hide();

this.alert.success(this.$t('alert.link', {
attachmentName: this.linkDatasetModal.attachmentName
attachmentName: attachment.name
}));

this.attachments.patch(() => {
const attachment = this.attachments.get(this.linkDatasetModal.attachmentName);
attachment.datasetExists = true;
attachment.blobExists = false;
attachment.exists = true;
});

this.hideModal('linkDatasetModal');
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/form-attachment/row.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ except according to the terms contained in the LICENSE file.
</template>
<template v-else-if="linkable && !attachment.datasetExists">
<button type="button" class="btn btn-primary btn-link-dataset"
@click="$emit('link', { name: attachment.name, blobExists: attachment.blobExists })">
@click="$emit('link', attachment)">
<span class="icon-link"></span>
<i18n-t keypath="action.linkDataset">
<template #datasetName>{{ datasetName }}</template>
Expand Down
11 changes: 4 additions & 7 deletions src/components/form/list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ except according to the terms contained in the LICENSE file.
<span>{{ $t('title') }}</span>
<button v-if="project.dataExists && project.permits('form.create')"
id="form-list-create-button" type="button" class="btn btn-primary"
@click="showModal('newForm')">
@click="createModal.show()">
<span class="icon-plus-circle"></span>{{ $t('action.create') }}&hellip;
</button>
<form-sort v-model="sortMode"/>
Expand All @@ -31,7 +31,7 @@ except according to the terms contained in the LICENSE file.
</p>
</template>
</page-section>
<form-new v-bind="newForm" @hide="hideModal('newForm')"
<form-new v-bind="createModal" @hide="createModal.hide()"
@success="afterCreate"/>
</div>
</template>
Expand All @@ -43,15 +43,14 @@ import Loading from '../loading.vue';
import PageSection from '../page/section.vue';
import FormSort from './sort.vue';

import modal from '../../mixins/modal';
import sortFunctions from '../../util/sort';
import useRoutes from '../../composables/routes';
import { modalData } from '../../util/reactivity';
import { useRequestData } from '../../request-data';

export default {
name: 'FormList',
components: { FormTable, FormNew, FormSort, Loading, PageSection },
mixins: [modal()],
inject: ['alert'],
setup() {
// The component does not assume that this data will exist when the
Expand All @@ -62,9 +61,7 @@ export default {
},
data() {
return {
newForm: {
state: false
},
createModal: modalData(),
sortMode: 'alphabetical'
};
},
Expand Down
16 changes: 4 additions & 12 deletions src/components/form/settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,42 +34,34 @@ except according to the terms contained in the LICENSE file.
<div class="panel-body">
<p>
<button type="button" class="btn btn-danger"
@click="showModal('deleteForm')">
@click="deleteModal.show()">
{{ $t('action.delete') }}&hellip;
</button>
</p>
</div>
</div>
</div>
</div>
<form-delete v-bind="deleteForm" @hide="hideModal('deleteForm')"
<form-delete v-bind="deleteModal" @hide="deleteModal.hide()"
@success="afterDelete"/>
</div>
</template>

<script>
import FormDelete from './delete.vue';

import modal from '../../mixins/modal';
import useRoutes from '../../composables/routes';
import { modalData } from '../../util/reactivity';
import { useRequestData } from '../../request-data';

export default {
name: 'FormSettings',
components: { FormDelete },
mixins: [modal()],
inject: ['alert'],
setup() {
const { form } = useRequestData();
const { projectPath } = useRoutes();
return { form, projectPath };
},
data() {
return {
deleteForm: {
state: false
}
};
return { form, deleteModal: modalData(), projectPath };
},
methods: {
afterDelete() {
Expand Down
18 changes: 5 additions & 13 deletions src/components/form/submissions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ except according to the terms contained in the LICENSE file.
</enketo-fill>
<odata-data-access :analyze-disabled="analyzeDisabled"
:analyze-disabled-message="analyzeDisabledMessage"
@analyze="showModal('analyze')"/>
@analyze="analyzeModal.show()"/>
</template>
<template #body>
<submission-list :project-id="projectId" :xml-form-id="xmlFormId" @fetch-keys="fetchData"/>
</template>
</page-section>
<odata-analyze v-bind="analyze" :odata-url="odataUrl"
@hide="hideModal('analyze')"/>
<odata-analyze v-bind="analyzeModal" :odata-url="odataUrl"
@hide="analyzeModal.hide()"/>
</div>
</template>

Expand All @@ -39,8 +39,8 @@ import OdataAnalyze from '../odata/analyze.vue';
import OdataDataAccess from '../odata/data-access.vue';
import SubmissionList from '../submission/list.vue';

import modal from '../../mixins/modal';
import { apiPaths } from '../../util/request';
import { modalData } from '../../util/reactivity';
import { noop } from '../../util/util';
import { useRequestData } from '../../request-data';

Expand All @@ -54,7 +54,6 @@ export default {
OdataDataAccess,
SubmissionList
},
mixins: [modal()],
props: {
projectId: {
type: String,
Expand All @@ -68,14 +67,7 @@ export default {
setup() {
const { project, form, createResource } = useRequestData();
const keys = createResource('keys');
return { project, form, keys };
},
data() {
return {
analyze: {
state: false
}
};
return { project, form, keys, analyzeModal: modalData() };
},
computed: {
rendersEnketoFill() {
Expand Down
Loading

0 comments on commit a54cf7b

Please sign in to comment.