form listing new design + delete form modal (#30)
Co-authored-by: JhumanJ <julien@nahum.net>
This commit is contained in:
parent
b9ba6e1e29
commit
d8bf96501b
Binary file not shown.
After Width: | Height: | Size: 63 KiB |
|
@ -31,7 +31,7 @@ export default {
|
|||
},
|
||||
|
||||
props: {
|
||||
dropdownClass: { type: String, default: 'origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white dark:bg-gray-800 ring-1 ring-black ring-opacity-5 z-50' }
|
||||
dropdownClass: { type: String, default: 'origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white dark:bg-gray-800 ring-1 ring-black ring-opacity-5 z-20' }
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</div>
|
||||
<dropdown v-else class="inline" dusk="nav-dropdown">
|
||||
<template #trigger="{toggle}">
|
||||
<v-button color="light-gray" class="mr-2" @click="toggle">
|
||||
<v-button color="white" class="mr-2" @click="toggle">
|
||||
<svg class="w-4 h-4 inline -mt-1" viewBox="0 0 16 4" fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
|
@ -34,6 +34,26 @@
|
|||
</svg>
|
||||
View form
|
||||
</router-link>
|
||||
<router-link v-if="isMainPage" :to="{name:'forms.edit', params: {slug: form.slug}}"
|
||||
class="block block px-4 py-2 text-md text-gray-700 dark:text-white hover:bg-gray-100 hover:text-gray-900 dark:text-gray-100 dark:hover:text-white dark:hover:bg-gray-600 flex items-center"
|
||||
v-track.edit_form_click="{form_id:form.id, form_slug:form.slug}"
|
||||
>
|
||||
<svg class="w-4 h-4 mr-2" width="18" height="17" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M8.99998 15.6662H16.5M1.5 15.6662H2.89545C3.3031 15.6662 3.50693 15.6662 3.69874 15.6202C3.8688 15.5793 4.03138 15.512 4.1805 15.4206C4.34869 15.3175 4.49282 15.1734 4.78107 14.8852L15.25 4.4162C15.9404 3.72585 15.9404 2.60656 15.25 1.9162C14.5597 1.22585 13.4404 1.22585 12.75 1.9162L2.28105 12.3852C1.9928 12.6734 1.84867 12.8175 1.7456 12.9857C1.65422 13.1348 1.58688 13.2974 1.54605 13.4675C1.5 13.6593 1.5 13.8631 1.5 14.2708V15.6662Z"
|
||||
stroke="currentColor" stroke-width="1.67" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
Edit
|
||||
</router-link>
|
||||
<a href="#" v-if="isMainPage"
|
||||
class="block block px-4 py-2 text-md text-gray-700 dark:text-white hover:bg-gray-100 hover:text-gray-900 dark:text-gray-100 dark:hover:text-white dark:hover:bg-gray-600 flex items-center"
|
||||
@click.prevent="copyLink"
|
||||
>
|
||||
<svg class="w-4 h-4 mr-2" viewBox="0 0 16 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.00016 8.33317H4.66683C2.82588 8.33317 1.3335 6.84079 1.3335 4.99984C1.3335 3.15889 2.82588 1.6665 4.66683 1.6665H6.00016M10.0002 8.33317H11.3335C13.1744 8.33317 14.6668 6.84079 14.6668 4.99984C14.6668 3.15889 13.1744 1.6665 11.3335 1.6665H10.0002M4.66683 4.99984L11.3335 4.99984" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
Copy link to share
|
||||
</a>
|
||||
<a href="#"
|
||||
class="block block px-4 py-2 text-md text-gray-700 dark:text-white hover:bg-gray-100 hover:text-gray-900 dark:text-gray-100 dark:hover:text-white dark:hover:bg-gray-600 flex items-center"
|
||||
v-track.duplicate_form_click="{form_id:form.id, form_slug:form.slug}"
|
||||
|
@ -61,7 +81,7 @@
|
|||
<a href="#"
|
||||
class="block block px-4 py-2 text-md text-red-600 hover:bg-red-50 flex items-center"
|
||||
v-track.delete_form_click="{form_id:form.id, form_slug:form.slug}"
|
||||
@click.prevent="alertConfirm('Do you really want to delete this form?',deleteForm)"
|
||||
@click.prevent="showDeleteFormModal=true"
|
||||
>
|
||||
<svg class="w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
|
@ -73,6 +93,30 @@
|
|||
</a>
|
||||
</dropdown>
|
||||
|
||||
<!-- Delete Form Modal -->
|
||||
<modal :show="showDeleteFormModal" icon-color="red" @close="showDeleteFormModal=false" max-width="sm">
|
||||
<template #icon>
|
||||
<svg class="w-10 h-10" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
<template #title>
|
||||
Delete form
|
||||
</template>
|
||||
<div class="p-3">
|
||||
<p>
|
||||
If you want to permanently delete this form and all of its data, you can do so below.
|
||||
</p>
|
||||
<div class="flex mt-4">
|
||||
<v-button class="sm:w-1/2 mr-4" color="white" @click.prevent="showDeleteFormModal=false">Cancel</v-button>
|
||||
<v-button class="sm:w-1/2" color="red" :loading="loadingDelete" @click.prevent="deleteForm">Yes, delete it</v-button>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
|
||||
<create-template-modal :form="form" :show="showCreateTemplateModal" @close="showCreateTemplateModal=false"/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -87,12 +131,14 @@ export default {
|
|||
name: 'ExtraMenu',
|
||||
components: { Dropdown, CreateTemplateModal },
|
||||
props: {
|
||||
form: { type: Object, required: true }
|
||||
form: { type: Object, required: true },
|
||||
isMainPage: { type: Boolean, required: false, default: false }
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
loadingDuplicate: false,
|
||||
loadingDelete: false,
|
||||
showDeleteFormModal: false,
|
||||
showCreateTemplateModal: false
|
||||
}),
|
||||
|
||||
|
@ -104,6 +150,14 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
copyLink(){
|
||||
const el = document.createElement('textarea')
|
||||
el.value = this.form.share_url
|
||||
document.body.appendChild(el)
|
||||
el.select()
|
||||
document.execCommand('copy')
|
||||
document.body.removeChild(el)
|
||||
},
|
||||
duplicateForm() {
|
||||
if (this.loadingDuplicate) return
|
||||
this.loadingDuplicate = true
|
||||
|
|
|
@ -1,71 +1,89 @@
|
|||
<template>
|
||||
<div class="flex flex-col min-h-full mt-6">
|
||||
<div class="w-full flex-grow md:w-3/5 lg:w-1/2 md:mx-auto md:max-w-2xl px-4">
|
||||
<div>
|
||||
<div class="flex flex-wrap items-center mt-6 mb-4">
|
||||
<h2 class="text-nt-blue text-3xl font-bold flex-grow">
|
||||
Your Forms
|
||||
</h2>
|
||||
<v-button v-track.create_form_click class="mt-4 sm:mt-0" :to="{name:'forms.create'}" @click="showCreateFormModal=true">
|
||||
Create a new form
|
||||
</v-button>
|
||||
<div class="bg-white">
|
||||
<div class="flex bg-gray-50 pb-5">
|
||||
<div class="w-full md:w-4/5 lg:w-3/5 md:mx-auto md:max-w-4xl p-4">
|
||||
<div class="pt-4 pb-0">
|
||||
<div class="flex">
|
||||
<h2 class="flex-grow text-gray-900">
|
||||
Your Forms
|
||||
</h2>
|
||||
<v-button v-track.create_form_click :to="{name:'forms.create'}">
|
||||
<svg class="w-4 h-4 text-white inline mr-1 -mt-1" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.99996 1.1665V12.8332M1.16663 6.99984H12.8333" stroke="currentColor" stroke-width="1.67" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
Create a new form
|
||||
</v-button>
|
||||
</div>
|
||||
<small class="flex text-gray-500">Manage your forms and submissions.</small>
|
||||
</div>
|
||||
|
||||
<p v-if="!formsLoading && enrichedForms.length === 0 && !isFilteringForms">
|
||||
You don't have any form yet.
|
||||
</p>
|
||||
<div v-else-if="forms.length > 0" class="mb-10">
|
||||
<text-input v-if="forms.length > 5" class="mb-6" :form="searchForm" name="search" label="Search a form"
|
||||
placeholder="Name of form to search"
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex bg-white">
|
||||
<div class="w-full md:w-4/5 lg:w-3/5 md:mx-auto md:max-w-4xl px-4">
|
||||
<div class="mt-8 pb-0">
|
||||
<text-input v-if="forms.length > 0" class="mb-6" :form="searchForm" name="search" label="Search a form"
|
||||
placeholder="Name of form to search"
|
||||
/>
|
||||
<div v-if="allTags.length > 0" class="mb-6">
|
||||
<div v-for="tag in allTags" :key="tag"
|
||||
:class="['text-white p-2 text-xs inline rounded-lg font-semibold cursor-pointer mr-2',{'bg-gray-500 dark:bg-gray-400':selectedTags.includes(tag), 'bg-gray-300 dark:bg-gray-700':!selectedTags.includes(tag)}]"
|
||||
title="Click for filter by tag(s)"
|
||||
@click="onTagClick(tag)"
|
||||
:class="['text-white p-2 text-xs inline rounded-lg font-semibold cursor-pointer mr-2',{'bg-gray-500 dark:bg-gray-400':selectedTags.includes(tag), 'bg-gray-300 dark:bg-gray-700':!selectedTags.includes(tag)}]"
|
||||
title="Click for filter by tag(s)"
|
||||
@click="onTagClick(tag)"
|
||||
>
|
||||
{{ tag }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="enrichedForms && enrichedForms.length" class="border border border-gray-300 dark:bg-notion-dark-light rounded-md w-full">
|
||||
<div v-for="(form, index) in enrichedForms" :key="form.id"
|
||||
class="p-4 w-full mx-auto border-gray-300 hover:bg-blue-100 dark:hover:bg-blue-900 transition-colors cursor-pointer relative"
|
||||
:class="{'border-t':index!==0, 'bg-gray-50 dark:bg-gray-400':form.visibility=='draft'}"
|
||||
>
|
||||
<div class="items-center space-x-4 truncate">
|
||||
<p class="truncate float-left">
|
||||
{{ form.title }} <span v-if="form.submissions_count" class="text-gray-400 ml-1">- {{
|
||||
form.submissions_count
|
||||
}} Submission{{ form.submissions_count > 0 ? 's' : '' }}</span>
|
||||
</p>
|
||||
<div v-if="form.tags && form.tags.length > 0" class="float-right hidden sm:block">
|
||||
<template v-for="(tag,i) in form.tags">
|
||||
<div v-if="i<1" :key="tag"
|
||||
class="bg-gray-300 dark:bg-gray-700 text-white px-2 py-1 mr-2 text-xs inline rounded-lg font-semibold"
|
||||
>
|
||||
{{ tag }}
|
||||
</div>
|
||||
<div v-if="i==1" :key="tag"
|
||||
class="bg-gray-300 dark:bg-gray-700 text-white px-2 py-1 mr-2 text-xs inline rounded-lg font-semibold"
|
||||
>
|
||||
{{ form.tags.length-1 }} more
|
||||
</div>
|
||||
</template>
|
||||
<div v-if="!formsLoading && enrichedForms.length === 0" class="flex flex-wrap justify-center max-w-4xl">
|
||||
<img loading="lazy" class="w-56"
|
||||
:src="asset('img/pages/forms/search_notfound.png')" alt="search-not-found">
|
||||
<h3 class="w-full mt-4 text-center text-gray-900 font-semibold">No forms found</h3>
|
||||
<div v-if="isFilteringForms && enrichedForms.length === 0 && searchForm.search" class="mt-2 w-full text-center">
|
||||
Your search "{{searchForm.search}}" did not match any forms. Please try again.
|
||||
</div>
|
||||
<v-button v-if="forms.length === 0" class="mt-4" v-track.create_form_click :to="{name:'forms.create'}">
|
||||
<svg class="w-4 h-4 text-white inline mr-1 -mt-1" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.99996 1.1665V12.8332M1.16663 6.99984H12.8333" stroke="currentColor" stroke-width="1.67" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
Create a new form
|
||||
</v-button>
|
||||
</div>
|
||||
<div v-else-if="forms.length > 0" class="mb-10">
|
||||
<div v-if="enrichedForms && enrichedForms.length">
|
||||
<div v-for="(form) in enrichedForms" :key="form.id"
|
||||
class="mt-4 p-4 flex group bg-white hover:bg-gray-50 dark:bg-notion-dark items-center"
|
||||
>
|
||||
<div class="flex-grow items-center truncate cursor-pointer" role="button" @click.prevent="viewForm(form)">
|
||||
<span class="font-semibold text-gray-900 dark:text-white">{{ form.title }}</span>
|
||||
<ul class="flex text-gray-500">
|
||||
<li class="pr-1">{{ form.views_count }} view{{ form.views_count > 0 ? 's' : '' }}</li>
|
||||
<li class="list-disc ml-6 pr-1">{{ form.submissions_count }}
|
||||
submission{{ form.submissions_count > 0 ? 's' : '' }}
|
||||
</li>
|
||||
<li class="list-disc ml-6 pr-1 text-blue-500" v-if="form.visibility=='draft'">Draft (not public)</li>
|
||||
<li class="list-disc ml-6">Edited {{ form.last_edited_human }}</li>
|
||||
</ul>
|
||||
<div v-if="form.tags && form.tags.length > 0" class="mt-1">
|
||||
<template v-for="(tag,i) in form.tags">
|
||||
<div v-if="i<1" :key="tag"
|
||||
class="bg-gray-300 dark:bg-gray-700 text-white px-2 py-1 mr-2 text-xs inline rounded-lg font-semibold"
|
||||
>
|
||||
{{ tag }}
|
||||
</div>
|
||||
<div v-if="i==1" :key="tag"
|
||||
class="bg-gray-300 dark:bg-gray-700 text-white px-2 py-1 mr-2 text-xs inline rounded-lg font-semibold"
|
||||
>
|
||||
{{ form.tags.length-1 }} more
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<extra-menu :form="form" :isMainPage="true" />
|
||||
</div>
|
||||
<router-link class="absolute inset-0"
|
||||
:to="{params:{slug:form.slug},name:'forms.show'}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-gray-400 dark:text-gray-600 mt-2 px-4">
|
||||
You have {{ forms.length }} forms<template v-if="isFilteringForms">
|
||||
({{ enrichedForms.length }} matching search criteria)
|
||||
</template>.
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="formsLoading" class="text-center">
|
||||
<loader class="h-6 w-6 text-nt-blue mx-auto" />
|
||||
<div v-if="formsLoading" class="text-center">
|
||||
<loader class="h-6 w-6 text-nt-blue mx-auto" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -80,6 +98,7 @@ import Fuse from 'fuse.js'
|
|||
import Form from 'vform'
|
||||
import TextInput from '../components/forms/TextInput'
|
||||
import OpenFormFooter from '../components/pages/OpenFormFooter'
|
||||
import ExtraMenu from '../components/pages/forms/show/ExtraMenu'
|
||||
|
||||
const loadForms = function () {
|
||||
store.commit('open/forms/startLoading')
|
||||
|
@ -89,7 +108,7 @@ const loadForms = function () {
|
|||
}
|
||||
|
||||
export default {
|
||||
components: { OpenFormFooter, TextInput },
|
||||
components: { OpenFormFooter, TextInput, ExtraMenu },
|
||||
|
||||
beforeRouteEnter (to, from, next) {
|
||||
loadForms()
|
||||
|
@ -127,6 +146,9 @@ export default {
|
|||
} else {
|
||||
this.selectedTags.splice(idx, 1)
|
||||
}
|
||||
},
|
||||
viewForm (form) {
|
||||
this.$router.push({name: 'forms.show', params: {slug: form.slug}})
|
||||
}
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue