Add client linting to GitHub Actions workflow
Enhance CI/CD pipeline by introducing a new job to run ESLint on the client application. This ensures code quality and consistency for the frontend codebase.
This commit is contained in:
parent
a91c194161
commit
4a2adcf8f7
|
|
@ -50,6 +50,35 @@ jobs:
|
||||||
working-directory: ./api
|
working-directory: ./api
|
||||||
run: ./vendor/bin/pint --test
|
run: ./vendor/bin/pint --test
|
||||||
|
|
||||||
|
client_lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Run client linters
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ./client
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: "20"
|
||||||
|
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-
|
||||||
|
|
||||||
|
- name: Install npm dependencies
|
||||||
|
run: npm ci --no-audit --no-progress --silent
|
||||||
|
|
||||||
|
- name: Run ESLint
|
||||||
|
run: npm run lint
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
|
@ -199,7 +228,7 @@ jobs:
|
||||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
|
|
||||||
production-deploy:
|
production-deploy:
|
||||||
needs: [code_lint, tests, build-nuxt-app]
|
needs: [code_lint, client_lint, tests, build-nuxt-app]
|
||||||
if: success() && github.ref == 'refs/heads/main' && github.event_name == 'push'
|
if: success() && github.ref == 'refs/heads/main' && github.event_name == 'push'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Triggers Deployment (Vapor & Amplify)
|
name: Triggers Deployment (Vapor & Amplify)
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ export default {
|
||||||
src: this.getFileSrc(file)
|
src: this.getFileSrc(file)
|
||||||
})
|
})
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}).catch((error) => {
|
}).catch(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -297,7 +297,7 @@ export default {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch(() => {
|
||||||
this.clearAll()
|
this.clearAll()
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, watch, computed } from 'vue'
|
import { ref, onMounted, watch } from 'vue'
|
||||||
import { inputProps, useFormInput } from './useFormInput.js'
|
import { inputProps, useFormInput } from './useFormInput.js'
|
||||||
import InputWrapper from './components/InputWrapper.vue'
|
import InputWrapper from './components/InputWrapper.vue'
|
||||||
import MentionDropdown from './components/MentionDropdown.vue'
|
import MentionDropdown from './components/MentionDropdown.vue'
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
disableMention: { type: Boolean, default: false },
|
disableMention: { type: Boolean, default: false },
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
const { compVal, inputStyle, hasValidation, hasError, inputWrapperProps } = useFormInput(props, { emit })
|
const { compVal, inputStyle, hasError, inputWrapperProps } = useFormInput(props, { emit })
|
||||||
const editableDiv = ref(null)
|
const editableDiv = ref(null)
|
||||||
const savedRange = ref(null)
|
const savedRange = ref(null)
|
||||||
const subscriptionModalStore = useSubscriptionModalStore()
|
const subscriptionModalStore = useSubscriptionModalStore()
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ export default {
|
||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.file = null
|
this.file = null
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div
|
<div
|
||||||
v-html="processedContent"
|
v-html="processedContent"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps({
|
defineProps({
|
||||||
isChecked: {
|
isChecked: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</UPopover>
|
</UPopover>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, toRefs } from 'vue'
|
import { ref, toRefs } from 'vue'
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
ref="container"
|
ref="container"
|
||||||
class="quilly-editor"
|
class="quilly-editor"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import Quill from 'quill'
|
import Quill from 'quill'
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps({
|
defineProps({
|
||||||
isChecked: {
|
isChecked: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
:error="error"
|
:error="error"
|
||||||
:clear-error="clearError"
|
:clear-error="clearError"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const error = ref()
|
const error = ref()
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps({
|
defineProps({
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "slideInUp"
|
default: "slideInUp"
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ const props = defineProps({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['select-font'])
|
defineEmits(['select-font'])
|
||||||
|
|
||||||
const getFontUrl = computed(() => {
|
const getFontUrl = computed(() => {
|
||||||
const family = props.fontName.replace(/ /g, '+')
|
const family = props.fontName.replace(/ /g, '+')
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['close','apply'])
|
defineEmits(['close','apply'])
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const fonts = ref([])
|
const fonts = ref([])
|
||||||
const selectedFont = ref(props.font || null)
|
const selectedFont = ref(props.font || null)
|
||||||
|
|
|
||||||
|
|
@ -117,14 +117,14 @@
|
||||||
:admin-preview="adminPreview"
|
:admin-preview="adminPreview"
|
||||||
@submit="submitForm"
|
@submit="submitForm"
|
||||||
>
|
>
|
||||||
<template #submit-btn="{submitForm}">
|
<template #submit-btn="{rootSubmitForm}">
|
||||||
<open-form-button
|
<open-form-button
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:theme="theme"
|
:theme="theme"
|
||||||
:color="form.color"
|
:color="form.color"
|
||||||
class="mt-2 px-8 mx-1"
|
class="mt-2 px-8 mx-1"
|
||||||
:class="submitButtonClass"
|
:class="submitButtonClass"
|
||||||
@click.prevent="submitForm"
|
@click.prevent="rootSubmitForm"
|
||||||
>
|
>
|
||||||
{{ form.submit_button_text }}
|
{{ form.submit_button_text }}
|
||||||
</open-form-button>
|
</open-form-button>
|
||||||
|
|
@ -223,6 +223,8 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
emits: ['submitted', 'password-entered', 'restarted'],
|
||||||
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const { setLocale } = useI18n()
|
const { setLocale } = useI18n()
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ export default {
|
||||||
adminPreview: {type: Boolean, default: false} // If used in FormEditorPreview
|
adminPreview: {type: Boolean, default: false} // If used in FormEditorPreview
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props) {
|
setup() {
|
||||||
const workingFormStore = useWorkingFormStore()
|
const workingFormStore = useWorkingFormStore()
|
||||||
return {
|
return {
|
||||||
workingFormStore,
|
workingFormStore,
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ const props = defineProps({
|
||||||
show: { type: Boolean, required: true },
|
show: { type: Boolean, required: true },
|
||||||
form: { type: Object, required: true }
|
form: { type: Object, required: true }
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['close'])
|
defineEmits(['close'])
|
||||||
const confetti = useConfetti()
|
const confetti = useConfetti()
|
||||||
const crisp = useCrisp()
|
const crisp = useCrisp()
|
||||||
const amplitude = useAmplitude()
|
const amplitude = useAmplitude()
|
||||||
|
|
|
||||||
|
|
@ -33,20 +33,18 @@
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue'
|
const crisp = useCrisp()
|
||||||
const crisp = useCrisp()
|
const workingFormStore = useWorkingFormStore()
|
||||||
const workingFormStore = useWorkingFormStore()
|
const form = storeToRefs(workingFormStore).content
|
||||||
const authStore = useAuthStore()
|
|
||||||
const form = storeToRefs(workingFormStore).content
|
// Clear error and go back 1 step in history
|
||||||
const user = computed(() => authStore.user)
|
const clearEditorError = (error, clearError) => {
|
||||||
// Clear error and go back 1 step in history
|
|
||||||
const clearEditorError = (error, clearError) => {
|
|
||||||
crisp.enableChatbot()
|
crisp.enableChatbot()
|
||||||
workingFormStore.undo()
|
workingFormStore.undo()
|
||||||
clearError()
|
clearError()
|
||||||
}
|
}
|
||||||
const onFormEditorError = (error) => {
|
const onFormEditorError = (error) => {
|
||||||
console.error('Form Editor Error Handled', error)
|
console.error('Form Editor Error Handled', error)
|
||||||
crisp.pauseChatBot()
|
crisp.pauseChatBot()
|
||||||
const eventData = {
|
const eventData = {
|
||||||
|
|
@ -59,8 +57,8 @@
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to send event to crisp', e, eventData)
|
console.error('Failed to send event to crisp', e, eventData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const onErrorContact = (error) => {
|
const onErrorContact = (error) => {
|
||||||
crisp.pauseChatBot()
|
crisp.pauseChatBot()
|
||||||
let errorReport = 'Hi there, I have a technical issue with the form editor.'
|
let errorReport = 'Hi there, I have a technical issue with the form editor.'
|
||||||
if (form.value.slug) {
|
if (form.value.slug) {
|
||||||
|
|
@ -74,6 +72,6 @@
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Crisp error', e)
|
console.error('Crisp error', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -118,13 +118,4 @@ const onSubmit = () => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const isUrl = (str) => {
|
|
||||||
try {
|
|
||||||
new URL(str)
|
|
||||||
} catch (_) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, defineProps } from 'vue'
|
import { computed, defineProps } from 'vue'
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ const props = defineProps({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:field'])
|
defineEmits(['update:field'])
|
||||||
|
|
||||||
const options = ref([
|
const options = ref([
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<p class="font-semibold">Prefilled values</p>
|
<p class="font-semibold">
|
||||||
|
Prefilled values
|
||||||
|
</p>
|
||||||
<select-input
|
<select-input
|
||||||
v-for="row in matrixData"
|
v-for="row in matrixData"
|
||||||
:key="row.label"
|
:key="row.label"
|
||||||
|
v-model="selection[row.label]"
|
||||||
name="prefill"
|
name="prefill"
|
||||||
class="mt-3"
|
class="mt-3"
|
||||||
:options="row.options"
|
:options="row.options"
|
||||||
:label="row.label"
|
:label="row.label"
|
||||||
v-model="selection[row.label]"
|
|
||||||
@update:model-value="onSelection"
|
@update:model-value="onSelection"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,11 @@ import { default as _has } from 'lodash/has'
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
props: {
|
props: {
|
||||||
|
// eslint-disable-next-line vue/require-prop-types
|
||||||
property: {
|
property: {
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
// eslint-disable-next-line vue/require-prop-types
|
||||||
value: {
|
value: {
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps({
|
defineProps({
|
||||||
isWorkspaceAdmin: {},
|
isWorkspaceAdmin: { type: Boolean, default: false },
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ onMounted(() => {
|
||||||
loadingBillingEmail.value = false
|
loadingBillingEmail.value = false
|
||||||
userCreated.value = true
|
userCreated.value = true
|
||||||
form.billing_email = data.billing_email
|
form.billing_email = data.billing_email
|
||||||
}).catch(error => {
|
}).catch(() => {
|
||||||
loadingBillingEmail.value = false
|
loadingBillingEmail.value = false
|
||||||
userCreated.value = false
|
userCreated.value = false
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,8 @@
|
||||||
</UTable>
|
</UTable>
|
||||||
<div
|
<div
|
||||||
v-if="forms?.length > pageCount"
|
v-if="forms?.length > pageCount"
|
||||||
class="flex justify-end px-3 py-3.5 border-t border-gray-200 dark:border-gray-700">
|
class="flex justify-end px-3 py-3.5 border-t border-gray-200 dark:border-gray-700"
|
||||||
|
>
|
||||||
<UPagination
|
<UPagination
|
||||||
v-model="page"
|
v-model="page"
|
||||||
:page-count="pageCount"
|
:page-count="pageCount"
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import {watch, ref} from "vue"
|
import {watch, ref} from "vue"
|
||||||
|
|
||||||
|
// eslint-disable-next-line vue/require-prop-types
|
||||||
const props = defineProps(['user', 'showEditUserModal'])
|
const props = defineProps(['user', 'showEditUserModal'])
|
||||||
const emit = defineEmits(['close', 'fetchUsers'])
|
const emit = defineEmits(['close', 'fetchUsers'])
|
||||||
|
|
||||||
|
|
@ -73,7 +74,7 @@ const updateUserRole = () => {
|
||||||
useAlert().success("User role updated.")
|
useAlert().success("User role updated.")
|
||||||
emit('fetchUsers')
|
emit('fetchUsers')
|
||||||
emit('close')
|
emit('close')
|
||||||
}).catch((error) => {
|
}).catch(() => {
|
||||||
useAlert().error("There was an error updating user role")
|
useAlert().error("There was an error updating user role")
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
updatingUserRoleState.value = false
|
updatingUserRoleState.value = false
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
size="sm"
|
size="sm"
|
||||||
color="white"
|
color="white"
|
||||||
icon="i-heroicons-eye-16-solid"
|
icon="i-heroicons-eye-16-solid"
|
||||||
|
:loading="loading"
|
||||||
@click="impersonate"
|
@click="impersonate"
|
||||||
>
|
>
|
||||||
Impersonate User
|
Impersonate User
|
||||||
|
|
@ -18,13 +19,13 @@ const authStore = useAuthStore()
|
||||||
const formsStore = useFormsStore()
|
const formsStore = useFormsStore()
|
||||||
const workspacesStore = useWorkspacesStore()
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
|
||||||
let loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
const impersonate = () => {
|
const impersonate = () => {
|
||||||
loading = true
|
loading.value = true
|
||||||
authStore.startImpersonating()
|
authStore.startImpersonating()
|
||||||
opnFetch(`/moderator/impersonate/${props.user.id}`).then(async (data) => {
|
opnFetch(`/moderator/impersonate/${props.user.id}`).then(async (data) => {
|
||||||
loading = false
|
loading.value = false
|
||||||
|
|
||||||
// Save the token.
|
// Save the token.
|
||||||
authStore.setToken(data.token, false)
|
authStore.setToken(data.token, false)
|
||||||
|
|
@ -47,7 +48,7 @@ const impersonate = () => {
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
useAlert().error(error.data.message)
|
useAlert().error(error.data.message)
|
||||||
loading = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@
|
||||||
</UTable>
|
</UTable>
|
||||||
<div
|
<div
|
||||||
v-if="workspaces?.length > pageCount"
|
v-if="workspaces?.length > pageCount"
|
||||||
class="flex justify-end px-3 py-3.5 border-t border-gray-200 dark:border-gray-700">
|
class="flex justify-end px-3 py-3.5 border-t border-gray-200 dark:border-gray-700"
|
||||||
|
>
|
||||||
<UPagination
|
<UPagination
|
||||||
v-model="page"
|
v-model="page"
|
||||||
:page-count="pageCount"
|
:page-count="pageCount"
|
||||||
|
|
@ -30,7 +31,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</AdminCard>
|
</AdminCard>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,6 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, defineProps, computed } from "vue"
|
import { ref, defineProps, computed } from "vue"
|
||||||
import Dropdown from "~/components/global/Dropdown.vue"
|
|
||||||
import FormTemplateModal from "../../../open/forms/components/templates/FormTemplateModal.vue"
|
import FormTemplateModal from "../../../open/forms/components/templates/FormTemplateModal.vue"
|
||||||
import FormWorkspaceModal from "../../../open/forms/components/FormWorkspaceModal.vue"
|
import FormWorkspaceModal from "../../../open/forms/components/FormWorkspaceModal.vue"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ import {watch} from "vue"
|
||||||
const crisp = useCrisp()
|
const crisp = useCrisp()
|
||||||
const workspacesStore = useWorkspacesStore()
|
const workspacesStore = useWorkspacesStore()
|
||||||
const workspace = computed(() => workspacesStore.getCurrent)
|
const workspace = computed(() => workspacesStore.getCurrent)
|
||||||
const loading = computed(() => workspacesStore.loading)
|
|
||||||
|
|
||||||
const customDomainsForm = useForm({
|
const customDomainsForm = useForm({
|
||||||
custom_domain: "",
|
custom_domain: "",
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ const removeUser = (index) => {
|
||||||
).then(() => {
|
).then(() => {
|
||||||
useAlert().success("User successfully removed.")
|
useAlert().success("User successfully removed.")
|
||||||
getWorkspaceUsers()
|
getWorkspaceUsers()
|
||||||
}).catch((error) => {
|
}).catch(() => {
|
||||||
useAlert().error("There was an error removing user")
|
useAlert().error("There was an error removing user")
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
loadingUsers.value = false
|
loadingUsers.value = false
|
||||||
|
|
@ -319,7 +319,7 @@ const leaveWorkSpace = (workspaceId) => {
|
||||||
useAlert().success("You have left the workspace.")
|
useAlert().success("You have left the workspace.")
|
||||||
workspacesStore.remove(workspaceId)
|
workspacesStore.remove(workspaceId)
|
||||||
getWorkspaceUsers()
|
getWorkspaceUsers()
|
||||||
}).catch((error) => {
|
}).catch(() => {
|
||||||
useAlert().error("There was an error leaving the workspace.")
|
useAlert().error("There was an error leaving the workspace.")
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
leaveWorkspaceLoadingState.value = false
|
leaveWorkspaceLoadingState.value = false
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@ function redirectToMainDomain(details = {}) {
|
||||||
export default defineNuxtRouteMiddleware((to) => {
|
export default defineNuxtRouteMiddleware((to) => {
|
||||||
if (!customDomainUsed()) return
|
if (!customDomainUsed()) return
|
||||||
|
|
||||||
const config = useRuntimeConfig()
|
|
||||||
|
|
||||||
const customDomainHeaderValue = useRequestHeaders()[customDomainHeaderName]
|
const customDomainHeaderValue = useRequestHeaders()[customDomainHeaderName]
|
||||||
if (
|
if (
|
||||||
import.meta.server &&
|
import.meta.server &&
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
export default defineNuxtRouteMiddleware(() => {
|
export default defineNuxtRouteMiddleware(() => {
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
const runtimeConfig = useRuntimeConfig()
|
|
||||||
|
|
||||||
if (useFeatureFlag('self_hosted')) {
|
if (useFeatureFlag('self_hosted')) {
|
||||||
if (authStore.check && authStore.user?.email === 'admin@opnform.com') {
|
if (authStore.check && authStore.user?.email === 'admin@opnform.com') {
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,6 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from "vue"
|
import { computed } from "vue"
|
||||||
import VButton from "~/components/global/VButton.vue"
|
|
||||||
import ExtraMenu from "../../../components/pages/forms/show/ExtraMenu.vue"
|
import ExtraMenu from "../../../components/pages/forms/show/ExtraMenu.vue"
|
||||||
import FormCleanings from "../../../components/pages/forms/show/FormCleanings.vue"
|
import FormCleanings from "../../../components/pages/forms/show/FormCleanings.vue"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<template>
|
<template>
|
||||||
<template>
|
|
||||||
<div class="flex flex-grow mt-6 mb-10">
|
<div class="flex flex-grow mt-6 mb-10">
|
||||||
<div class="w-full md:w-2/3 md:mx-auto md:max-w-md px-4">
|
<div class="w-full md:w-2/3 md:mx-auto md:max-w-md px-4">
|
||||||
<div
|
<div
|
||||||
|
|
@ -26,13 +25,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useNuxtApp } from "nuxt/app";
|
import { useNuxtApp } from "nuxt/app"
|
||||||
|
|
||||||
const { $utm } = useNuxtApp();
|
const { $utm } = useNuxtApp()
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<modal :show="showModal" @close="logout" max-width="lg">
|
<modal
|
||||||
|
:show="showModal"
|
||||||
|
max-width="lg"
|
||||||
|
@close="logout"
|
||||||
|
>
|
||||||
<div class="">
|
<div class="">
|
||||||
<h2 class="font-medium text-3xl mb-3">Welcome to OpnForm!</h2>
|
<h2 class="font-medium text-3xl mb-3">
|
||||||
|
Welcome to OpnForm!
|
||||||
|
</h2>
|
||||||
<p class="text-sm text-gray-600">
|
<p class="text-sm text-gray-600">
|
||||||
You're using the self-hosted version of OpnForm and need to set up your account.
|
You're using the self-hosted version of OpnForm and need to set up your account.
|
||||||
Please enter your email and create a password to continue.
|
Please enter your email and create a password to continue.
|
||||||
|
|
@ -43,7 +49,10 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Submit Button -->
|
<!-- Submit Button -->
|
||||||
<v-button class="mx-auto" :loading="form.busy || loading">
|
<v-button
|
||||||
|
class="mx-auto"
|
||||||
|
:loading="form.busy || loading"
|
||||||
|
>
|
||||||
Update Credentials
|
Update Credentials
|
||||||
</v-button>
|
</v-button>
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -51,14 +60,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from "vue";
|
import { onMounted } from "vue"
|
||||||
|
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore()
|
||||||
const workspacesStore = useWorkspacesStore();
|
const workspacesStore = useWorkspacesStore()
|
||||||
const formsStore = useFormsStore();
|
const formsStore = useFormsStore()
|
||||||
const user = computed(() => authStore.user);
|
const user = computed(() => authStore.user)
|
||||||
const router = useRouter();
|
const router = useRouter()
|
||||||
const showModal = ref(true);
|
const showModal = ref(true)
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
name: "",
|
name: "",
|
||||||
email: "",
|
email: "",
|
||||||
|
|
@ -66,31 +75,31 @@ const form = useForm({
|
||||||
password_confirmation: "",
|
password_confirmation: "",
|
||||||
agree_terms: false,
|
agree_terms: false,
|
||||||
appsumo_license: null,
|
appsumo_license: null,
|
||||||
});
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
form.email = user?.value?.email;
|
form.email = user?.value?.email
|
||||||
});
|
})
|
||||||
|
|
||||||
const updateCredentials = () => {
|
const updateCredentials = () => {
|
||||||
form
|
form
|
||||||
.post("update-credentials")
|
.post("update-credentials")
|
||||||
.then(async (data) => {
|
.then(async (data) => {
|
||||||
authStore.setUser(data.user);
|
authStore.setUser(data.user)
|
||||||
const workspaces = await fetchAllWorkspaces();
|
const workspaces = await fetchAllWorkspaces()
|
||||||
workspacesStore.set(workspaces.data.value);
|
workspacesStore.set(workspaces.data.value)
|
||||||
formsStore.loadAll(workspacesStore.currentId);
|
formsStore.loadAll(workspacesStore.currentId)
|
||||||
router.push({ name: "home" });
|
router.push({ name: "home" })
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error)
|
||||||
useAlert().error(error.response._data.message);
|
useAlert().error(error.response._data.message)
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
authStore.logout();
|
authStore.logout()
|
||||||
showModal.value = false;
|
showModal.value = false
|
||||||
router.push({ name: "login" });
|
router.push({ name: "login" })
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -1,11 +1,3 @@
|
||||||
function parseBoolean(value, defaultValue = false) {
|
|
||||||
if (typeof value === 'string') {
|
|
||||||
value = value.toLowerCase().trim()
|
|
||||||
if (value === 'true' || value === '1') return true
|
|
||||||
if (value === 'false' || value === '0') return false
|
|
||||||
}
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseNumber(value, defaultValue = 0) {
|
function parseNumber(value, defaultValue = 0) {
|
||||||
const parsedValue = parseFloat(value)
|
const parsedValue = parseFloat(value)
|
||||||
|
|
|
||||||
|
|
@ -160,27 +160,6 @@ export const useWorkingFormStore = defineStore("working_form", {
|
||||||
this.content.properties.splice(index, 1)
|
this.content.properties.splice(index, 1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeField(field) {
|
|
||||||
this.internalRemoveField(field)
|
|
||||||
},
|
|
||||||
internalRemoveField(field) {
|
|
||||||
const index = this.objectToIndex(field)
|
|
||||||
|
|
||||||
if (index !== -1) {
|
|
||||||
useAlert().success('Ctrl + Z to undo',10000,{
|
|
||||||
title: 'Field removed',
|
|
||||||
actions: [{
|
|
||||||
label: 'Undo',
|
|
||||||
icon:"i-material-symbols-undo",
|
|
||||||
click: () => {
|
|
||||||
this.undo()
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
})
|
|
||||||
this.content.properties.splice(index, 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
moveField(oldIndex, newIndex) {
|
moveField(oldIndex, newIndex) {
|
||||||
const newFields = clonedeep(this.content.properties)
|
const newFields = clonedeep(this.content.properties)
|
||||||
const field = newFields.splice(oldIndex, 1)[0]
|
const field = newFields.splice(oldIndex, 1)[0]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue