feat: improve store typing
This commit is contained in:
parent
a6b96f857d
commit
244478400a
60 changed files with 239 additions and 192 deletions
|
@ -18,7 +18,7 @@
|
||||||
import {computed, watch, type Ref} from 'vue'
|
import {computed, watch, type Ref} from 'vue'
|
||||||
import {useRouter} from 'vue-router'
|
import {useRouter} from 'vue-router'
|
||||||
import {useRouteQuery} from '@vueuse/router'
|
import {useRouteQuery} from '@vueuse/router'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import isTouchDevice from 'is-touch-device'
|
import isTouchDevice from 'is-touch-device'
|
||||||
import {success} from '@/message'
|
import {success} from '@/message'
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {computed, ref, watch} from 'vue'
|
import {computed, ref, watch} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import flatPickr from 'vue-flatpickr-component'
|
import flatPickr from 'vue-flatpickr-component'
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed} from 'vue'
|
import {computed} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import BaseButton from '@/components/base/BaseButton.vue'
|
import BaseButton from '@/components/base/BaseButton.vue'
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, computed, onMounted, nextTick} from 'vue'
|
import {ref, computed, onMounted, nextTick} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useRouter} from 'vue-router'
|
import {useRouter} from 'vue-router'
|
||||||
|
|
||||||
import {QUICK_ACTIONS_ACTIVE} from '@/store/mutation-types'
|
import {QUICK_ACTIONS_ACTIVE} from '@/store/mutation-types'
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {watch, computed, shallowRef, watchEffect, type VNode, h} from 'vue'
|
import {watch, computed, shallowRef, watchEffect, type VNode, h} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useRoute, useRouter} from 'vue-router'
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
import {useEventListener} from '@vueuse/core'
|
import {useEventListener} from '@vueuse/core'
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {computed} from 'vue'
|
import {computed} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import Logo from '@/components/home/Logo.vue'
|
import Logo from '@/components/home/Logo.vue'
|
||||||
import PoweredByLink from './PoweredByLink.vue'
|
import PoweredByLink from './PoweredByLink.vue'
|
||||||
|
|
|
@ -141,7 +141,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, computed, onMounted, onBeforeMount} from 'vue'
|
import {ref, computed, onMounted, onBeforeMount} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import draggable from 'zhyswan-vuedraggable'
|
import draggable from 'zhyswan-vuedraggable'
|
||||||
import type {SortableEvent} from 'sortablejs'
|
import type {SortableEvent} from 'sortablejs'
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, computed, watchEffect, type PropType} from 'vue'
|
import {ref, computed, watchEffect, type PropType} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import {getSavedFilterIdFromListId} from '@/helpers/savedFilter'
|
import {getSavedFilterIdFromListId} from '@/helpers/savedFilter'
|
||||||
import Dropdown from '@/components/misc/dropdown.vue'
|
import Dropdown from '@/components/misc/dropdown.vue'
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {type PropType, ref, watch} from 'vue'
|
import {type PropType, ref, watch} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import ListService from '@/services/list'
|
import ListService from '@/services/list'
|
||||||
import {getBlobFromBlurHash} from '@/helpers/getBlobFromBlurHash'
|
import {getBlobFromBlurHash} from '@/helpers/getBlobFromBlurHash'
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import Shortcut from '@/components/misc/shortcut.vue'
|
import Shortcut from '@/components/misc/shortcut.vue'
|
||||||
import Message from '@/components/misc/message.vue'
|
import Message from '@/components/misc/message.vue'
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {computed} from 'vue'
|
import {computed} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import BaseButton from '@/components/base/BaseButton.vue'
|
import BaseButton from '@/components/base/BaseButton.vue'
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ import Logo from '@/components/home/Logo.vue'
|
||||||
import Message from '@/components/misc/message.vue'
|
import Message from '@/components/misc/message.vue'
|
||||||
import Legal from '@/components/misc/legal.vue'
|
import Legal from '@/components/misc/legal.vue'
|
||||||
import ApiConfig from '@/components/misc/api-config.vue'
|
import ApiConfig from '@/components/misc/api-config.vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {computed} from 'vue'
|
import {computed} from 'vue'
|
||||||
import {useRoute} from 'vue-router'
|
import {useRoute} from 'vue-router'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, computed} from 'vue'
|
import {ref, computed} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import Logo from '@/assets/logo.svg?component'
|
import Logo from '@/assets/logo.svg?component'
|
||||||
import ApiConfig from '@/components/misc/api-config.vue'
|
import ApiConfig from '@/components/misc/api-config.vue'
|
||||||
|
|
|
@ -54,7 +54,7 @@ import BaseButton from '@/components/base/BaseButton.vue'
|
||||||
import User from '@/components/misc/user.vue'
|
import User from '@/components/misc/user.vue'
|
||||||
import { NOTIFICATION_NAMES as names, type INotification} from '@/models/notification'
|
import { NOTIFICATION_NAMES as names, type INotification} from '@/models/notification'
|
||||||
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
|
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useRouter} from 'vue-router'
|
import {useRouter} from 'vue-router'
|
||||||
import {formatDateLong, formatDateSince} from '@/helpers/time/formatDate'
|
import {formatDateLong, formatDateSince} from '@/helpers/time/formatDate'
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, watch, computed, shallowReactive} from 'vue'
|
import {ref, watch, computed, shallowReactive} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import {RIGHTS} from '@/models/constants/rights'
|
import {RIGHTS} from '@/models/constants/rights'
|
||||||
|
|
|
@ -139,7 +139,7 @@ export default {name: 'userTeamShare'}
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, reactive, computed, shallowReactive, type ShallowReactive, type Ref} from 'vue'
|
import {ref, reactive, computed, shallowReactive, type ShallowReactive, type Ref} from 'vue'
|
||||||
import type {PropType} from 'vue'
|
import type {PropType} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import UserNamespaceService from '@/services/userNamespace'
|
import UserNamespaceService from '@/services/userNamespace'
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, watch, unref, shallowReactive} from 'vue'
|
import {ref, watch, unref, shallowReactive} from 'vue'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {tryOnMounted, debouncedWatch, useWindowSize, type MaybeRef} from '@vueuse/core'
|
import {tryOnMounted, debouncedWatch, useWindowSize, type MaybeRef} from '@vueuse/core'
|
||||||
|
|
||||||
import TaskService from '@/services/task'
|
import TaskService from '@/services/task'
|
||||||
|
|
|
@ -153,7 +153,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, reactive, computed, shallowReactive, watch, nextTick} from 'vue'
|
import {ref, reactive, computed, shallowReactive, watch, nextTick} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import Editor from '@/components/input/AsyncEditor'
|
import Editor from '@/components/input/AsyncEditor'
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, shallowReactive, computed, watch, onMounted, onBeforeUnmount, type PropType} from 'vue'
|
import {ref, shallowReactive, computed, watch, onMounted, onBeforeUnmount, type PropType} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import flatPickr from 'vue-flatpickr-component'
|
import flatPickr from 'vue-flatpickr-component'
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref,computed, watch, type PropType} from 'vue'
|
import {ref,computed, watch, type PropType} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import Editor from '@/components/input/AsyncEditor'
|
import Editor from '@/components/input/AsyncEditor'
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, shallowReactive, watch, type PropType} from 'vue'
|
import {ref, shallowReactive, watch, type PropType} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import User from '@/components/misc/user.vue'
|
import User from '@/components/misc/user.vue'
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {type PropType, ref, computed, shallowReactive, watch} from 'vue'
|
import {type PropType, ref, computed, shallowReactive, watch} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import LabelModel, { type ILabel } from '@/models/label'
|
import LabelModel, { type ILabel } from '@/models/label'
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, computed, type PropType} from 'vue'
|
import {ref, computed, type PropType} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import BaseButton from '@/components/base/BaseButton.vue'
|
import BaseButton from '@/components/base/BaseButton.vue'
|
||||||
import Done from '@/components/misc/Done.vue'
|
import Done from '@/components/misc/Done.vue'
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {reactive, ref, watch} from 'vue'
|
import {reactive, ref, watch} from 'vue'
|
||||||
import type {PropType} from 'vue'
|
import type {PropType} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import ListModel, { type IList } from '@/models/list'
|
import ListModel, { type IList } from '@/models/list'
|
||||||
import Multiselect from '@/components/input/multiselect.vue'
|
import Multiselect from '@/components/input/multiselect.vue'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {ref, computed} from 'vue'
|
import {ref, computed} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
export function useNameSpaceSearch() {
|
export function useNameSpaceSearch() {
|
||||||
const query = ref('')
|
const query = ref('')
|
||||||
|
|
|
@ -14,7 +14,7 @@ import Notifications from '@kyvg/vue3-notification'
|
||||||
import './registerServiceWorker'
|
import './registerServiceWorker'
|
||||||
|
|
||||||
// Vuex
|
// Vuex
|
||||||
import {store} from './store'
|
import { store, key } from './store'
|
||||||
// i18n
|
// i18n
|
||||||
import {i18n} from './i18n'
|
import {i18n} from './i18n'
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ if (window.SENTRY_ENABLED) {
|
||||||
import('./sentry').then(sentry => sentry.default(app, router))
|
import('./sentry').then(sentry => sentry.default(app, router))
|
||||||
}
|
}
|
||||||
|
|
||||||
app.use(store)
|
app.use(store, key) // pass the injection key
|
||||||
app.use(router)
|
app.use(router)
|
||||||
app.use(i18n)
|
app.use(i18n)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import {createStore} from 'vuex'
|
import type {InjectionKey} from 'vue'
|
||||||
|
import {createStore, useStore as baseUseStore, Store} from 'vuex'
|
||||||
|
|
||||||
|
|
||||||
import {getBlobFromBlurHash} from '../helpers/getBlobFromBlurHash'
|
import {getBlobFromBlurHash} from '../helpers/getBlobFromBlurHash'
|
||||||
import {
|
import {
|
||||||
BACKGROUND,
|
BACKGROUND,
|
||||||
|
@ -25,7 +28,14 @@ import ListModel from '@/models/list'
|
||||||
import ListService from '../services/list'
|
import ListService from '../services/list'
|
||||||
import {checkAndSetApiUrl} from '@/helpers/checkAndSetApiUrl'
|
import {checkAndSetApiUrl} from '@/helpers/checkAndSetApiUrl'
|
||||||
|
|
||||||
import type { RootStoreState } from './types'
|
import type { RootStoreState, StoreState } from './types'
|
||||||
|
|
||||||
|
export const key: InjectionKey<Store<StoreState>> = Symbol()
|
||||||
|
|
||||||
|
// define your own `useStore` composition function
|
||||||
|
export function useStore () {
|
||||||
|
return baseUseStore(key)
|
||||||
|
}
|
||||||
|
|
||||||
export const store = createStore<RootStoreState>({
|
export const store = createStore<RootStoreState>({
|
||||||
strict: import.meta.env.DEV,
|
strict: import.meta.env.DEV,
|
||||||
|
|
|
@ -1,26 +1,29 @@
|
||||||
|
import type { Module } from 'vuex'
|
||||||
import {findIndexById} from '@/helpers/utils'
|
import {findIndexById} from '@/helpers/utils'
|
||||||
|
|
||||||
import type { AttachmentState } from '@/store/types'
|
import type { AttachmentState, RootStoreState } from '@/store/types'
|
||||||
import type { IAttachment } from '@/models/attachment'
|
import type { IAttachment } from '@/models/attachment'
|
||||||
|
|
||||||
export default {
|
const store : Module<AttachmentState, RootStoreState> = {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: (): AttachmentState => ({
|
state: () => ({
|
||||||
attachments: [],
|
attachments: [],
|
||||||
}),
|
}),
|
||||||
mutations: {
|
mutations: {
|
||||||
set(state: AttachmentState, attachments: IAttachment[]) {
|
set(state, attachments: IAttachment[]) {
|
||||||
console.debug('Set attachments', attachments)
|
console.debug('Set attachments', attachments)
|
||||||
state.attachments = attachments
|
state.attachments = attachments
|
||||||
},
|
},
|
||||||
add(state: AttachmentState, attachment: IAttachment) {
|
add(state, attachment: IAttachment) {
|
||||||
console.debug('Add attachement', attachment)
|
console.debug('Add attachement', attachment)
|
||||||
state.attachments.push(attachment)
|
state.attachments.push(attachment)
|
||||||
},
|
},
|
||||||
removeById(state: AttachmentState, id: IAttachment['id']) {
|
removeById(state, id: IAttachment['id']) {
|
||||||
const attachmentIndex = findIndexById<IAttachment>(state.attachments, id)
|
const attachmentIndex = findIndexById<IAttachment>(state.attachments, id)
|
||||||
state.attachments.splice(attachmentIndex, 1)
|
state.attachments.splice(attachmentIndex, 1)
|
||||||
console.debug('Remove attachement', id)
|
console.debug('Remove attachement', id)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default store
|
|
@ -1,4 +1,4 @@
|
||||||
import type { ActionContext } from 'vuex'
|
import type { Module } from 'vuex'
|
||||||
|
|
||||||
import {HTTPFactory, AuthenticatedHTTPFactory} from '@/http-common'
|
import {HTTPFactory, AuthenticatedHTTPFactory} from '@/http-common'
|
||||||
import {i18n, getCurrentLanguage, saveLanguage} from '@/i18n'
|
import {i18n, getCurrentLanguage, saveLanguage} from '@/i18n'
|
||||||
|
@ -22,25 +22,25 @@ const defaultSettings = settings => {
|
||||||
return settings
|
return settings
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
const authStore : Module<AuthState, RootStoreState> = {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: (): AuthState => ({
|
state: () => ({
|
||||||
authenticated: false,
|
authenticated: false,
|
||||||
isLinkShareAuth: false,
|
isLinkShareAuth: false,
|
||||||
info: null,
|
info: null,
|
||||||
needsTotpPasscode: false,
|
needsTotpPasscode: false,
|
||||||
avatarUrl: '',
|
avatarUrl: '',
|
||||||
lastUserInfoRefresh: null,
|
lastUserInfoRefresh: null,
|
||||||
settings: {},
|
settings: {}, // should be IUserSettings
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
authUser(state: AuthState) {
|
authUser(state) {
|
||||||
return state.authenticated && (
|
return state.authenticated && (
|
||||||
state.info &&
|
state.info &&
|
||||||
state.info.type === AUTH_TYPES.USER
|
state.info.type === AUTH_TYPES.USER
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
authLinkShare(state: AuthState) {
|
authLinkShare(state) {
|
||||||
return state.authenticated && (
|
return state.authenticated && (
|
||||||
state.info &&
|
state.info &&
|
||||||
state.info.type === AUTH_TYPES.LINK_SHARE
|
state.info.type === AUTH_TYPES.LINK_SHARE
|
||||||
|
@ -48,7 +48,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
info(state: AuthState, info: Info) {
|
info(state, info: Info) {
|
||||||
state.info = info
|
state.info = info
|
||||||
if (info !== null) {
|
if (info !== null) {
|
||||||
state.avatarUrl = info.getAvatarUrl()
|
state.avatarUrl = info.getAvatarUrl()
|
||||||
|
@ -60,32 +60,32 @@ export default {
|
||||||
state.isLinkShareAuth = info.id < 0
|
state.isLinkShareAuth = info.id < 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setUserSettings(state: AuthState, settings: IUserSettings) {
|
setUserSettings(state, settings: IUserSettings) {
|
||||||
state.settings = defaultSettings(settings)
|
state.settings = defaultSettings(settings)
|
||||||
const info = state.info !== null ? state.info : {} as Info
|
const info = state.info !== null ? state.info : {} as Info
|
||||||
info.name = settings.name
|
info.name = settings.name
|
||||||
state.info = info
|
state.info = info
|
||||||
},
|
},
|
||||||
authenticated(state: AuthState, authenticated: boolean) {
|
authenticated(state, authenticated: boolean) {
|
||||||
state.authenticated = authenticated
|
state.authenticated = authenticated
|
||||||
},
|
},
|
||||||
isLinkShareAuth(state: AuthState, isLinkShareAuth: boolean) {
|
isLinkShareAuth(state, isLinkShareAuth: boolean) {
|
||||||
state.isLinkShareAuth = isLinkShareAuth
|
state.isLinkShareAuth = isLinkShareAuth
|
||||||
},
|
},
|
||||||
needsTotpPasscode(state: AuthState, needsTotpPasscode: boolean) {
|
needsTotpPasscode(state, needsTotpPasscode: boolean) {
|
||||||
state.needsTotpPasscode = needsTotpPasscode
|
state.needsTotpPasscode = needsTotpPasscode
|
||||||
},
|
},
|
||||||
reloadAvatar(state: AuthState) {
|
reloadAvatar(state) {
|
||||||
if (!state.info) return
|
if (!state.info) return
|
||||||
state.avatarUrl = `${state.info.getAvatarUrl()}&=${+new Date()}`
|
state.avatarUrl = `${state.info.getAvatarUrl()}&=${+new Date()}`
|
||||||
},
|
},
|
||||||
lastUserRefresh(state: AuthState) {
|
lastUserRefresh(state) {
|
||||||
state.lastUserInfoRefresh = new Date()
|
state.lastUserInfoRefresh = new Date()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
// Logs a user in with a set of credentials.
|
// Logs a user in with a set of credentials.
|
||||||
async login(ctx: ActionContext<AuthState, RootStoreState>, credentials) {
|
async login(ctx, credentials) {
|
||||||
const HTTP = HTTPFactory()
|
const HTTP = HTTPFactory()
|
||||||
ctx.commit(LOADING, true, {root: true})
|
ctx.commit(LOADING, true, {root: true})
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ export default {
|
||||||
|
|
||||||
// Registers a new user and logs them in.
|
// Registers a new user and logs them in.
|
||||||
// Not sure if this is the right place to put the logic in, maybe a seperate js component would be better suited.
|
// Not sure if this is the right place to put the logic in, maybe a seperate js component would be better suited.
|
||||||
async register(ctx: ActionContext<AuthState, RootStoreState>, credentials) {
|
async register(ctx, credentials) {
|
||||||
const HTTP = HTTPFactory()
|
const HTTP = HTTPFactory()
|
||||||
ctx.commit(LOADING, true, {root: true})
|
ctx.commit(LOADING, true, {root: true})
|
||||||
try {
|
try {
|
||||||
|
@ -133,7 +133,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async openIdAuth(ctx: ActionContext<AuthState, RootStoreState>, {provider, code}) {
|
async openIdAuth(ctx, {provider, code}) {
|
||||||
const HTTP = HTTPFactory()
|
const HTTP = HTTPFactory()
|
||||||
ctx.commit(LOADING, true, {root: true})
|
ctx.commit(LOADING, true, {root: true})
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async linkShareAuth(ctx: ActionContext<AuthState, RootStoreState>, {hash, password}) {
|
async linkShareAuth(ctx, {hash, password}) {
|
||||||
const HTTP = HTTPFactory()
|
const HTTP = HTTPFactory()
|
||||||
const response = await HTTP.post('/shares/' + hash + '/auth', {
|
const response = await HTTP.post('/shares/' + hash + '/auth', {
|
||||||
password: password,
|
password: password,
|
||||||
|
@ -166,7 +166,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Populates user information from jwt token saved in local storage in store
|
// Populates user information from jwt token saved in local storage in store
|
||||||
checkAuth(ctx: ActionContext<AuthState, RootStoreState>) {
|
checkAuth(ctx) {
|
||||||
|
|
||||||
// This function can be called from multiple places at the same time and shortly after one another.
|
// This function can be called from multiple places at the same time and shortly after one another.
|
||||||
// To prevent hitting the api too frequently or race conditions, we check at most once per minute.
|
// To prevent hitting the api too frequently or race conditions, we check at most once per minute.
|
||||||
|
@ -198,7 +198,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
redirectToProviderIfNothingElseIsEnabled({rootState}: ActionContext<AuthState, RootStoreState>) {
|
redirectToProviderIfNothingElseIsEnabled({rootState}) {
|
||||||
const {auth} = rootState.config
|
const {auth} = rootState.config
|
||||||
if (
|
if (
|
||||||
auth.local.enabled === false &&
|
auth.local.enabled === false &&
|
||||||
|
@ -210,7 +210,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async refreshUserInfo({state, commit, dispatch}: ActionContext<AuthState, RootStoreState>) {
|
async refreshUserInfo({state, commit, dispatch}) {
|
||||||
const jwt = getToken()
|
const jwt = getToken()
|
||||||
if (!jwt) {
|
if (!jwt) {
|
||||||
return
|
return
|
||||||
|
@ -244,7 +244,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async saveUserSettings(ctx: ActionContext<AuthState, RootStoreState>, payload) {
|
async saveUserSettings(ctx, payload) {
|
||||||
const {settings} = payload
|
const {settings} = payload
|
||||||
const showMessage = payload.showMessage ?? true
|
const showMessage = payload.showMessage ?? true
|
||||||
const userSettingsService = new UserSettingsService()
|
const userSettingsService = new UserSettingsService()
|
||||||
|
@ -265,7 +265,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Renews the api token and saves it to local storage
|
// Renews the api token and saves it to local storage
|
||||||
renewToken(ctx: ActionContext<AuthState, RootStoreState>) {
|
renewToken(ctx) {
|
||||||
// FIXME: Timeout to avoid race conditions when authenticated as a user (=auth token in localStorage) and as a
|
// FIXME: Timeout to avoid race conditions when authenticated as a user (=auth token in localStorage) and as a
|
||||||
// link share in another tab. Without the timeout both the token renew and link share auth are executed at
|
// link share in another tab. Without the timeout both the token renew and link share auth are executed at
|
||||||
// the same time and one might win over the other.
|
// the same time and one might win over the other.
|
||||||
|
@ -286,10 +286,12 @@ export default {
|
||||||
}
|
}
|
||||||
}, 5000)
|
}, 5000)
|
||||||
},
|
},
|
||||||
logout(ctx: ActionContext<AuthState, RootStoreState>) {
|
logout(ctx) {
|
||||||
removeToken()
|
removeToken()
|
||||||
window.localStorage.clear() // Clear all settings and history we might have saved in local storage.
|
window.localStorage.clear() // Clear all settings and history we might have saved in local storage.
|
||||||
ctx.dispatch('checkAuth')
|
ctx.dispatch('checkAuth')
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default authStore
|
|
@ -1,4 +1,4 @@
|
||||||
import type { ActionContext } from 'vuex'
|
import type { Module } from 'vuex'
|
||||||
import {parseURL} from 'ufo'
|
import {parseURL} from 'ufo'
|
||||||
|
|
||||||
import {CONFIG} from '../mutation-types'
|
import {CONFIG} from '../mutation-types'
|
||||||
|
@ -6,9 +6,9 @@ import {HTTPFactory} from '@/http-common'
|
||||||
import {objectToCamelCase} from '@/helpers/case'
|
import {objectToCamelCase} from '@/helpers/case'
|
||||||
import type { RootStoreState, ConfigState } from '@/store/types'
|
import type { RootStoreState, ConfigState } from '@/store/types'
|
||||||
|
|
||||||
export default {
|
const configStore : Module<ConfigState, RootStoreState> = {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: (): ConfigState => ({
|
state: () => ({
|
||||||
// These are the api defaults.
|
// These are the api defaults.
|
||||||
version: '',
|
version: '',
|
||||||
frontendUrl: '',
|
frontendUrl: '',
|
||||||
|
@ -39,19 +39,19 @@ export default {
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
migratorsEnabled: (state: ConfigState) => state.availableMigrators?.length > 0,
|
migratorsEnabled: (state) => state.availableMigrators?.length > 0,
|
||||||
apiBase() {
|
apiBase() {
|
||||||
const {host, protocol} = parseURL(window.API_URL)
|
const {host, protocol} = parseURL(window.API_URL)
|
||||||
return protocol + '//' + host
|
return protocol + '//' + host
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
[CONFIG](state: ConfigState, config: ConfigState) {
|
[CONFIG](state, config: ConfigState) {
|
||||||
Object.assign(state, config)
|
Object.assign(state, config)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async update(ctx: ActionContext<ConfigState, RootStoreState>) {
|
async update(ctx) {
|
||||||
const HTTP = HTTPFactory()
|
const HTTP = HTTPFactory()
|
||||||
const {data: config} = await HTTP.get('info')
|
const {data: config} = await HTTP.get('info')
|
||||||
ctx.commit(CONFIG, objectToCamelCase(config))
|
ctx.commit(CONFIG, objectToCamelCase(config))
|
||||||
|
@ -59,3 +59,5 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default configStore
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Module } from 'vuex'
|
||||||
import cloneDeep from 'lodash.clonedeep'
|
import cloneDeep from 'lodash.clonedeep'
|
||||||
|
|
||||||
import {findById, findIndexById} from '@/helpers/utils'
|
import {findById, findIndexById} from '@/helpers/utils'
|
||||||
|
@ -7,7 +8,6 @@ import {success} from '@/message'
|
||||||
import BucketService from '../../services/bucket'
|
import BucketService from '../../services/bucket'
|
||||||
import {setLoading} from '../helper'
|
import {setLoading} from '../helper'
|
||||||
import TaskCollectionService from '@/services/taskCollection'
|
import TaskCollectionService from '@/services/taskCollection'
|
||||||
import type { ActionContext } from 'vuex'
|
|
||||||
import type { RootStoreState, KanbanState } from '@/store/types'
|
import type { RootStoreState, KanbanState } from '@/store/types'
|
||||||
import type { ITask } from '@/models/task'
|
import type { ITask } from '@/models/task'
|
||||||
import type { IList } from '@/models/list'
|
import type { IList } from '@/models/list'
|
||||||
|
@ -38,10 +38,10 @@ const addTaskToBucketAndSort = (state: KanbanState, task: ITask) => {
|
||||||
* This store is intended to hold the currently active kanban view.
|
* This store is intended to hold the currently active kanban view.
|
||||||
* It should hold only the current buckets.
|
* It should hold only the current buckets.
|
||||||
*/
|
*/
|
||||||
export default {
|
const kanbanStore : Module<KanbanState, RootStoreState> = {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
|
|
||||||
state: (): KanbanState => ({
|
state: () => ({
|
||||||
buckets: [],
|
buckets: [],
|
||||||
listId: 0,
|
listId: 0,
|
||||||
bucketLoading: {},
|
bucketLoading: {},
|
||||||
|
@ -50,11 +50,11 @@ export default {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mutations: {
|
mutations: {
|
||||||
setListId(state: KanbanState, listId: IList['id']) {
|
setListId(state, listId: IList['id']) {
|
||||||
state.listId = parseInt(listId)
|
state.listId = parseInt(listId)
|
||||||
},
|
},
|
||||||
|
|
||||||
setBuckets(state: KanbanState, buckets: IBucket[]) {
|
setBuckets(state, buckets: IBucket[]) {
|
||||||
state.buckets = buckets
|
state.buckets = buckets
|
||||||
buckets.forEach(b => {
|
buckets.forEach(b => {
|
||||||
state.taskPagesPerBucket[b.id] = 1
|
state.taskPagesPerBucket[b.id] = 1
|
||||||
|
@ -62,21 +62,21 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
addBucket(state: KanbanState, bucket: IBucket) {
|
addBucket(state, bucket: IBucket) {
|
||||||
state.buckets.push(bucket)
|
state.buckets.push(bucket)
|
||||||
},
|
},
|
||||||
|
|
||||||
removeBucket(state: KanbanState, bucket: IBucket) {
|
removeBucket(state, bucket: IBucket) {
|
||||||
const bucketIndex = findIndexById(state.buckets, bucket.id)
|
const bucketIndex = findIndexById(state.buckets, bucket.id)
|
||||||
state.buckets.splice(bucketIndex, 1)
|
state.buckets.splice(bucketIndex, 1)
|
||||||
},
|
},
|
||||||
|
|
||||||
setBucketById(state: KanbanState, bucket: IBucket) {
|
setBucketById(state, bucket: IBucket) {
|
||||||
const bucketIndex = findIndexById(state.buckets, bucket.id)
|
const bucketIndex = findIndexById(state.buckets, bucket.id)
|
||||||
state.buckets[bucketIndex] = bucket
|
state.buckets[bucketIndex] = bucket
|
||||||
},
|
},
|
||||||
|
|
||||||
setBucketByIndex(state: KanbanState, {
|
setBucketByIndex(state, {
|
||||||
bucketIndex,
|
bucketIndex,
|
||||||
bucket,
|
bucket,
|
||||||
} : {
|
} : {
|
||||||
|
@ -86,7 +86,7 @@ export default {
|
||||||
state.buckets[bucketIndex] = bucket
|
state.buckets[bucketIndex] = bucket
|
||||||
},
|
},
|
||||||
|
|
||||||
setTaskInBucketByIndex(state: KanbanState, {
|
setTaskInBucketByIndex(state, {
|
||||||
bucketIndex,
|
bucketIndex,
|
||||||
taskIndex,
|
taskIndex,
|
||||||
task,
|
task,
|
||||||
|
@ -100,7 +100,7 @@ export default {
|
||||||
state.buckets[bucketIndex] = bucket
|
state.buckets[bucketIndex] = bucket
|
||||||
},
|
},
|
||||||
|
|
||||||
setTasksInBucketByBucketId(state: KanbanState, {
|
setTasksInBucketByBucketId(state, {
|
||||||
bucketId,
|
bucketId,
|
||||||
tasks,
|
tasks,
|
||||||
} : {
|
} : {
|
||||||
|
@ -114,7 +114,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setTaskInBucket(state: KanbanState, task: ITask) {
|
setTaskInBucket(state, task: ITask) {
|
||||||
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
|
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
|
||||||
if (state.buckets.length === 0) {
|
if (state.buckets.length === 0) {
|
||||||
return
|
return
|
||||||
|
@ -158,7 +158,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addTaskToBucket(state: KanbanState, task: ITask) {
|
addTaskToBucket(state, task: ITask) {
|
||||||
const bucketIndex = findIndexById(state.buckets, task.bucketId)
|
const bucketIndex = findIndexById(state.buckets, task.bucketId)
|
||||||
const oldBucket = state.buckets[bucketIndex]
|
const oldBucket = state.buckets[bucketIndex]
|
||||||
const newBucket = {
|
const newBucket = {
|
||||||
|
@ -171,7 +171,7 @@ export default {
|
||||||
state.buckets[bucketIndex] = newBucket
|
state.buckets[bucketIndex] = newBucket
|
||||||
},
|
},
|
||||||
|
|
||||||
addTasksToBucket(state: KanbanState, {tasks, bucketId}: {
|
addTasksToBucket(state, {tasks, bucketId}: {
|
||||||
tasks: ITask[];
|
tasks: ITask[];
|
||||||
bucketId: IBucket['id'];
|
bucketId: IBucket['id'];
|
||||||
}) {
|
}) {
|
||||||
|
@ -187,7 +187,7 @@ export default {
|
||||||
state.buckets[bucketIndex] = newBucket
|
state.buckets[bucketIndex] = newBucket
|
||||||
},
|
},
|
||||||
|
|
||||||
removeTaskInBucket(state: KanbanState, task: ITask) {
|
removeTaskInBucket(state, task: ITask) {
|
||||||
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
|
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
|
||||||
if (state.buckets.length === 0) {
|
if (state.buckets.length === 0) {
|
||||||
return
|
return
|
||||||
|
@ -207,7 +207,7 @@ export default {
|
||||||
state.buckets[bucketIndex].tasks.splice(taskIndex, 1)
|
state.buckets[bucketIndex].tasks.splice(taskIndex, 1)
|
||||||
},
|
},
|
||||||
|
|
||||||
setBucketLoading(state: KanbanState, {bucketId, loading}) {
|
setBucketLoading(state, {bucketId, loading}) {
|
||||||
state.bucketLoading[bucketId] = loading
|
state.bucketLoading[bucketId] = loading
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -221,11 +221,11 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
getBucketById(state: KanbanState) {
|
getBucketById(state) {
|
||||||
return (bucketId) => findById(state.buckets, bucketId)
|
return (bucketId) => findById(state.buckets, bucketId)
|
||||||
},
|
},
|
||||||
|
|
||||||
getTaskById(state: KanbanState) {
|
getTaskById(state) {
|
||||||
return (id) => {
|
return (id) => {
|
||||||
const { bucketIndex, taskIndex } = getTaskIndicesById(state, id)
|
const { bucketIndex, taskIndex } = getTaskIndicesById(state, id)
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
async loadBucketsForList(ctx: ActionContext<KanbanState, RootStoreState>, {listId, params}) {
|
async loadBucketsForList(ctx, {listId, params}) {
|
||||||
const cancel = setLoading(ctx, 'kanban')
|
const cancel = setLoading(ctx, 'kanban')
|
||||||
|
|
||||||
// Clear everything to prevent having old buckets in the list if loading the buckets from this list takes a few moments
|
// Clear everything to prevent having old buckets in the list if loading the buckets from this list takes a few moments
|
||||||
|
@ -259,7 +259,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async loadNextTasksForBucket(ctx: ActionContext<KanbanState, RootStoreState>, {listId, ps = {}, bucketId}) {
|
async loadNextTasksForBucket(ctx, {listId, ps = {}, bucketId}) {
|
||||||
const isLoading = ctx.state.bucketLoading[bucketId] ?? false
|
const isLoading = ctx.state.bucketLoading[bucketId] ?? false
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return
|
return
|
||||||
|
@ -314,7 +314,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async createBucket(ctx: ActionContext<KanbanState, RootStoreState>, bucket: IBucket) {
|
async createBucket(ctx, bucket: IBucket) {
|
||||||
const cancel = setLoading(ctx, 'kanban')
|
const cancel = setLoading(ctx, 'kanban')
|
||||||
|
|
||||||
const bucketService = new BucketService()
|
const bucketService = new BucketService()
|
||||||
|
@ -327,7 +327,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async deleteBucket(ctx: ActionContext<KanbanState, RootStoreState>, {bucket, params}) {
|
async deleteBucket(ctx, {bucket, params}) {
|
||||||
const cancel = setLoading(ctx, 'kanban')
|
const cancel = setLoading(ctx, 'kanban')
|
||||||
|
|
||||||
const bucketService = new BucketService()
|
const bucketService = new BucketService()
|
||||||
|
@ -342,7 +342,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async updateBucket(ctx: ActionContext<KanbanState, RootStoreState>, updatedBucketData) {
|
async updateBucket(ctx, updatedBucketData) {
|
||||||
const cancel = setLoading(ctx, 'kanban')
|
const cancel = setLoading(ctx, 'kanban')
|
||||||
|
|
||||||
const bucketIndex = findIndexById(ctx.state.buckets, updatedBucketData.id)
|
const bucketIndex = findIndexById(ctx.state.buckets, updatedBucketData.id)
|
||||||
|
@ -370,7 +370,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async updateBucketTitle(ctx: ActionContext<KanbanState, RootStoreState>, { id, title }) {
|
async updateBucketTitle(ctx, { id, title }) {
|
||||||
const bucket = findById(ctx.state.buckets, id)
|
const bucket = findById(ctx.state.buckets, id)
|
||||||
|
|
||||||
if (bucket?.title === title) {
|
if (bucket?.title === title) {
|
||||||
|
@ -388,3 +388,5 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default kanbanStore
|
|
@ -1,4 +1,4 @@
|
||||||
import type { ActionContext } from 'vuex'
|
import type { Module } from 'vuex'
|
||||||
|
|
||||||
import {i18n} from '@/i18n'
|
import {i18n} from '@/i18n'
|
||||||
import {success} from '@/message'
|
import {success} from '@/message'
|
||||||
|
@ -22,46 +22,46 @@ async function getAllLabels(page = 1): Promise<ILabel[]> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
const LabelStore : Module<LabelState, RootStoreState> = {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: (): LabelState => ({
|
state: () => ({
|
||||||
labels: {},
|
labels: {},
|
||||||
loaded: false,
|
loaded: false,
|
||||||
}),
|
}),
|
||||||
mutations: {
|
mutations: {
|
||||||
setLabels(state: LabelState, labels: ILabel[]) {
|
setLabels(state, labels: ILabel[]) {
|
||||||
labels.forEach(l => {
|
labels.forEach(l => {
|
||||||
state.labels[l.id] = l
|
state.labels[l.id] = l
|
||||||
add(l)
|
add(l)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setLabel(state: LabelState, label: ILabel) {
|
setLabel(state, label: ILabel) {
|
||||||
state.labels[label.id] = label
|
state.labels[label.id] = label
|
||||||
update(label)
|
update(label)
|
||||||
},
|
},
|
||||||
removeLabelById(state: LabelState, label: ILabel) {
|
removeLabelById(state, label: ILabel) {
|
||||||
remove(label)
|
remove(label)
|
||||||
delete state.labels[label.id]
|
delete state.labels[label.id]
|
||||||
},
|
},
|
||||||
setLoaded(state: LabelState, loaded: boolean) {
|
setLoaded(state, loaded: boolean) {
|
||||||
state.loaded = loaded
|
state.loaded = loaded
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getLabelsByIds(state: LabelState) {
|
getLabelsByIds(state) {
|
||||||
return (ids: ILabel['id'][]) => getLabelsByIds(state, ids)
|
return (ids: ILabel['id'][]) => getLabelsByIds(state, ids)
|
||||||
},
|
},
|
||||||
filterLabelsByQuery(state: LabelState) {
|
filterLabelsByQuery(state) {
|
||||||
return (labelsToHide: ILabel[], query: string) => filterLabelsByQuery(state, labelsToHide, query)
|
return (labelsToHide: ILabel[], query: string) => filterLabelsByQuery(state, labelsToHide, query)
|
||||||
},
|
},
|
||||||
getLabelsByExactTitles(state: LabelState) {
|
getLabelsByExactTitles(state) {
|
||||||
return labelTitles => Object
|
return labelTitles => Object
|
||||||
.values(state.labels)
|
.values(state.labels)
|
||||||
.filter(({title}) => labelTitles.some(l => l.toLowerCase() === title.toLowerCase()))
|
.filter(({title}) => labelTitles.some(l => l.toLowerCase() === title.toLowerCase()))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async loadAllLabels(ctx: ActionContext<LabelState, RootStoreState>, {forceLoad} = {}) {
|
async loadAllLabels(ctx, {forceLoad} = {}) {
|
||||||
if (ctx.state.loaded && !forceLoad) {
|
if (ctx.state.loaded && !forceLoad) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ export default {
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async deleteLabel(ctx: ActionContext<LabelState, RootStoreState>, label: ILabel) {
|
async deleteLabel(ctx, label: ILabel) {
|
||||||
const cancel = setLoading(ctx, 'labels')
|
const cancel = setLoading(ctx, 'labels')
|
||||||
const labelService = new LabelService()
|
const labelService = new LabelService()
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ export default {
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async updateLabel(ctx: ActionContext<LabelState, RootStoreState>, label: ILabel) {
|
async updateLabel(ctx, label: ILabel) {
|
||||||
const cancel = setLoading(ctx, 'labels')
|
const cancel = setLoading(ctx, 'labels')
|
||||||
const labelService = new LabelService()
|
const labelService = new LabelService()
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ export default {
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async createLabel(ctx: ActionContext<LabelState, RootStoreState>, label: ILabel) {
|
async createLabel(ctx, label: ILabel) {
|
||||||
const cancel = setLoading(ctx, 'labels')
|
const cancel = setLoading(ctx, 'labels')
|
||||||
const labelService = new LabelService()
|
const labelService = new LabelService()
|
||||||
|
|
||||||
|
@ -117,3 +117,5 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default LabelStore
|
|
@ -1,49 +1,50 @@
|
||||||
|
import type { Module } from 'vuex'
|
||||||
|
|
||||||
import ListService from '@/services/list'
|
import ListService from '@/services/list'
|
||||||
import {setLoading} from '@/store/helper'
|
import {setLoading} from '@/store/helper'
|
||||||
import {removeListFromHistory} from '@/modules/listHistory'
|
import {removeListFromHistory} from '@/modules/listHistory'
|
||||||
import {createNewIndexer} from '@/indexes'
|
import {createNewIndexer} from '@/indexes'
|
||||||
import type {ListState, RootStoreState} from '@/store/types'
|
import type {ListState, RootStoreState} from '@/store/types'
|
||||||
import type {ActionContext} from 'vuex'
|
|
||||||
import type {IList} from '@/models/list'
|
import type {IList} from '@/models/list'
|
||||||
|
|
||||||
const {add, remove, search, update} = createNewIndexer('lists', ['title', 'description'])
|
const {add, remove, search, update} = createNewIndexer('lists', ['title', 'description'])
|
||||||
|
|
||||||
const FavoriteListsNamespace = -2
|
const FavoriteListsNamespace = -2
|
||||||
|
|
||||||
export default {
|
const listsStore : Module<ListState, RootStoreState>= {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
// The state is an object which has the list ids as keys.
|
// The state is an object which has the list ids as keys.
|
||||||
state: (): ListState => ({}),
|
state: () => ({}),
|
||||||
mutations: {
|
mutations: {
|
||||||
setList(state: ListState, list: IList) {
|
setList(state, list: IList) {
|
||||||
state[list.id] = list
|
state[list.id] = list
|
||||||
update(list)
|
update(list)
|
||||||
},
|
},
|
||||||
setLists(state: ListState, lists: IList[]) {
|
setLists(state, lists: IList[]) {
|
||||||
lists.forEach(l => {
|
lists.forEach(l => {
|
||||||
state[l.id] = l
|
state[l.id] = l
|
||||||
add(l)
|
add(l)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
removeListById(state: ListState, list: IList) {
|
removeListById(state, list: IList) {
|
||||||
remove(list)
|
remove(list)
|
||||||
delete state[list.id]
|
delete state[list.id]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getListById: (state: ListState) => (id: IList['id']) => {
|
getListById: (state) => (id: IList['id']) => {
|
||||||
if (typeof state[id] !== 'undefined') {
|
if (typeof state[id] !== 'undefined') {
|
||||||
return state[id]
|
return state[id]
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
findListByExactname: (state: ListState) => (name: string) => {
|
findListByExactname: (state) => (name: string) => {
|
||||||
const list = Object.values(state).find(l => {
|
const list = Object.values(state).find(l => {
|
||||||
return l.title.toLowerCase() === name.toLowerCase()
|
return l.title.toLowerCase() === name.toLowerCase()
|
||||||
})
|
})
|
||||||
return typeof list === 'undefined' ? null : list
|
return typeof list === 'undefined' ? null : list
|
||||||
},
|
},
|
||||||
searchList: (state: ListState) => (query: string, includeArchived = false) => {
|
searchList: (state) => (query: string, includeArchived = false) => {
|
||||||
return search(query)
|
return search(query)
|
||||||
?.filter(value => value > 0)
|
?.filter(value => value > 0)
|
||||||
.map(id => state[id])
|
.map(id => state[id])
|
||||||
|
@ -52,14 +53,14 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
toggleListFavorite(ctx: ActionContext<ListState, RootStoreState>, list: IList) {
|
toggleListFavorite(ctx, list: IList) {
|
||||||
return ctx.dispatch('updateList', {
|
return ctx.dispatch('updateList', {
|
||||||
...list,
|
...list,
|
||||||
isFavorite: !list.isFavorite,
|
isFavorite: !list.isFavorite,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async createList(ctx: ActionContext<ListState, RootStoreState>, list: IList) {
|
async createList(ctx, list: IList) {
|
||||||
const cancel = setLoading(ctx, 'lists')
|
const cancel = setLoading(ctx, 'lists')
|
||||||
const listService = new ListService()
|
const listService = new ListService()
|
||||||
|
|
||||||
|
@ -74,7 +75,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async updateList(ctx: ActionContext<ListState, RootStoreState>, list: IList) {
|
async updateList(ctx, list: IList) {
|
||||||
const cancel = setLoading(ctx, 'lists')
|
const cancel = setLoading(ctx, 'lists')
|
||||||
const listService = new ListService()
|
const listService = new ListService()
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async deleteList(ctx: ActionContext<ListState, RootStoreState>, list: IList) {
|
async deleteList(ctx, list: IList) {
|
||||||
const cancel = setLoading(ctx, 'lists')
|
const cancel = setLoading(ctx, 'lists')
|
||||||
const listService = new ListService()
|
const listService = new ListService()
|
||||||
|
|
||||||
|
@ -125,3 +126,5 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default listsStore
|
|
@ -1,4 +1,4 @@
|
||||||
import type {ActionContext} from 'vuex'
|
import type { Module } from 'vuex'
|
||||||
|
|
||||||
import NamespaceService from '../../services/namespace'
|
import NamespaceService from '../../services/namespace'
|
||||||
import {setLoading} from '@/store/helper'
|
import {setLoading} from '@/store/helper'
|
||||||
|
@ -9,19 +9,19 @@ import type {IList} from '@/models/list'
|
||||||
|
|
||||||
const {add, remove, search, update} = createNewIndexer('namespaces', ['title', 'description'])
|
const {add, remove, search, update} = createNewIndexer('namespaces', ['title', 'description'])
|
||||||
|
|
||||||
export default {
|
const namespacesStore : Module<NamespaceState, RootStoreState> = {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: (): NamespaceState => ({
|
state: () => ({
|
||||||
namespaces: [],
|
namespaces: [],
|
||||||
}),
|
}),
|
||||||
mutations: {
|
mutations: {
|
||||||
namespaces(state: NamespaceState, namespaces: INamespace[]) {
|
namespaces(state, namespaces: INamespace[]) {
|
||||||
state.namespaces = namespaces
|
state.namespaces = namespaces
|
||||||
namespaces.forEach(n => {
|
namespaces.forEach(n => {
|
||||||
add(n)
|
add(n)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setNamespaceById(state: NamespaceState, namespace: INamespace) {
|
setNamespaceById(state, namespace: INamespace) {
|
||||||
const namespaceIndex = state.namespaces.findIndex(n => n.id === namespace.id)
|
const namespaceIndex = state.namespaces.findIndex(n => n.id === namespace.id)
|
||||||
|
|
||||||
if (namespaceIndex === -1) {
|
if (namespaceIndex === -1) {
|
||||||
|
@ -35,7 +35,7 @@ export default {
|
||||||
state.namespaces[namespaceIndex] = namespace
|
state.namespaces[namespaceIndex] = namespace
|
||||||
update(namespace)
|
update(namespace)
|
||||||
},
|
},
|
||||||
setListInNamespaceById(state: NamespaceState, list: IList) {
|
setListInNamespaceById(state, list: IList) {
|
||||||
for (const n in state.namespaces) {
|
for (const n in state.namespaces) {
|
||||||
// We don't have the namespace id on the list which means we need to loop over all lists until we find it.
|
// We don't have the namespace id on the list which means we need to loop over all lists until we find it.
|
||||||
// FIXME: Not ideal at all - we should fix that at the api level.
|
// FIXME: Not ideal at all - we should fix that at the api level.
|
||||||
|
@ -51,11 +51,11 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addNamespace(state: NamespaceState, namespace: INamespace) {
|
addNamespace(state, namespace: INamespace) {
|
||||||
state.namespaces.push(namespace)
|
state.namespaces.push(namespace)
|
||||||
add(namespace)
|
add(namespace)
|
||||||
},
|
},
|
||||||
removeNamespaceById(state: NamespaceState, namespaceId: INamespace['id']) {
|
removeNamespaceById(state, namespaceId: INamespace['id']) {
|
||||||
for (const n in state.namespaces) {
|
for (const n in state.namespaces) {
|
||||||
if (state.namespaces[n].id === namespaceId) {
|
if (state.namespaces[n].id === namespaceId) {
|
||||||
remove(state.namespaces[n])
|
remove(state.namespaces[n])
|
||||||
|
@ -64,7 +64,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addListToNamespace(state: NamespaceState, list: IList) {
|
addListToNamespace(state, list: IList) {
|
||||||
for (const n in state.namespaces) {
|
for (const n in state.namespaces) {
|
||||||
if (state.namespaces[n].id === list.namespaceId) {
|
if (state.namespaces[n].id === list.namespaceId) {
|
||||||
state.namespaces[n].lists.push(list)
|
state.namespaces[n].lists.push(list)
|
||||||
|
@ -72,7 +72,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeListFromNamespaceById(state: NamespaceState, list: IList) {
|
removeListFromNamespaceById(state, list: IList) {
|
||||||
for (const n in state.namespaces) {
|
for (const n in state.namespaces) {
|
||||||
// We don't have the namespace id on the list which means we need to loop over all lists until we find it.
|
// We don't have the namespace id on the list which means we need to loop over all lists until we find it.
|
||||||
// FIXME: Not ideal at all - we should fix that at the api level.
|
// FIXME: Not ideal at all - we should fix that at the api level.
|
||||||
|
@ -88,7 +88,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getListAndNamespaceById: (state: NamespaceState) => (listId: IList['id'], ignorePseudoNamespaces = false) => {
|
getListAndNamespaceById: (state) => (listId: IList['id'], ignorePseudoNamespaces = false) => {
|
||||||
for (const n in state.namespaces) {
|
for (const n in state.namespaces) {
|
||||||
|
|
||||||
if (ignorePseudoNamespaces && state.namespaces[n].id < 0) {
|
if (ignorePseudoNamespaces && state.namespaces[n].id < 0) {
|
||||||
|
@ -106,10 +106,10 @@ export default {
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
getNamespaceById: (state: NamespaceState) => (namespaceId: INamespace['id']) => {
|
getNamespaceById: (state) => (namespaceId: INamespace['id']) => {
|
||||||
return state.namespaces.find(({id}) => id == namespaceId) || null
|
return state.namespaces.find(({id}) => id == namespaceId) || null
|
||||||
},
|
},
|
||||||
searchNamespace: (state: NamespaceState, getters) => (query: string) => {
|
searchNamespace: (state, getters) => (query: string) => {
|
||||||
return search(query)
|
return search(query)
|
||||||
?.filter(value => value > 0)
|
?.filter(value => value > 0)
|
||||||
.map(getters.getNamespaceById)
|
.map(getters.getNamespaceById)
|
||||||
|
@ -118,7 +118,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async loadNamespaces(ctx: ActionContext<NamespaceState, RootStoreState>) {
|
async loadNamespaces(ctx) {
|
||||||
const cancel = setLoading(ctx, 'namespaces')
|
const cancel = setLoading(ctx, 'namespaces')
|
||||||
|
|
||||||
const namespaceService = new NamespaceService()
|
const namespaceService = new NamespaceService()
|
||||||
|
@ -138,20 +138,20 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
loadNamespacesIfFavoritesDontExist(ctx: ActionContext<NamespaceState, RootStoreState>) {
|
loadNamespacesIfFavoritesDontExist(ctx) {
|
||||||
// The first or second namespace should be the one holding all favorites
|
// The first or second namespace should be the one holding all favorites
|
||||||
if (ctx.state.namespaces[0].id !== -2 && ctx.state.namespaces[1]?.id !== -2) {
|
if (ctx.state.namespaces[0].id !== -2 && ctx.state.namespaces[1]?.id !== -2) {
|
||||||
return ctx.dispatch('loadNamespaces')
|
return ctx.dispatch('loadNamespaces')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
removeFavoritesNamespaceIfEmpty(ctx: ActionContext<NamespaceState, RootStoreState>) {
|
removeFavoritesNamespaceIfEmpty(ctx) {
|
||||||
if (ctx.state.namespaces[0].id === -2 && ctx.state.namespaces[0].lists.length === 0) {
|
if (ctx.state.namespaces[0].id === -2 && ctx.state.namespaces[0].lists.length === 0) {
|
||||||
ctx.state.namespaces.splice(0, 1)
|
ctx.state.namespaces.splice(0, 1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async deleteNamespace(ctx: ActionContext<NamespaceState, RootStoreState>, namespace: INamespace) {
|
async deleteNamespace(ctx, namespace: INamespace) {
|
||||||
const cancel = setLoading(ctx, 'namespaces')
|
const cancel = setLoading(ctx, 'namespaces')
|
||||||
const namespaceService = new NamespaceService()
|
const namespaceService = new NamespaceService()
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async createNamespace(ctx: ActionContext<NamespaceState, RootStoreState>, namespace: INamespace) {
|
async createNamespace(ctx, namespace: INamespace) {
|
||||||
const cancel = setLoading(ctx, 'namespaces')
|
const cancel = setLoading(ctx, 'namespaces')
|
||||||
const namespaceService = new NamespaceService()
|
const namespaceService = new NamespaceService()
|
||||||
|
|
||||||
|
@ -178,3 +178,5 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default namespacesStore
|
|
@ -1,5 +1,5 @@
|
||||||
|
import type { Module } from 'vuex'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import type { ActionContext } from 'vuex'
|
|
||||||
import {formatISO} from 'date-fns'
|
import {formatISO} from 'date-fns'
|
||||||
|
|
||||||
import TaskService from '@/services/task'
|
import TaskService from '@/services/task'
|
||||||
|
@ -65,11 +65,11 @@ async function findAssignees(parsedTaskAssignees) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default {
|
const tasksStore : Module<TaskState, RootStoreState>= {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: (): TaskState => ({}),
|
state: () => ({}),
|
||||||
actions: {
|
actions: {
|
||||||
async loadTasks(ctx: ActionContext<TaskState, RootStoreState>, params) {
|
async loadTasks(ctx, params) {
|
||||||
const taskService = new TaskService()
|
const taskService = new TaskService()
|
||||||
|
|
||||||
const cancel = setLoading(ctx, 'tasks')
|
const cancel = setLoading(ctx, 'tasks')
|
||||||
|
@ -82,7 +82,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async update(ctx: ActionContext<TaskState, RootStoreState>, task: ITask) {
|
async update(ctx, task: ITask) {
|
||||||
const cancel = setLoading(ctx, 'tasks')
|
const cancel = setLoading(ctx, 'tasks')
|
||||||
|
|
||||||
const taskService = new TaskService()
|
const taskService = new TaskService()
|
||||||
|
@ -95,7 +95,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async delete(ctx: ActionContext<TaskState, RootStoreState>, task: ITask) {
|
async delete(ctx, task: ITask) {
|
||||||
const taskService = new TaskService()
|
const taskService = new TaskService()
|
||||||
const response = await taskService.delete(task)
|
const response = await taskService.delete(task)
|
||||||
ctx.commit('kanban/removeTaskInBucket', task, {root: true})
|
ctx.commit('kanban/removeTaskInBucket', task, {root: true})
|
||||||
|
@ -104,7 +104,7 @@ export default {
|
||||||
|
|
||||||
// Adds a task attachment in store.
|
// Adds a task attachment in store.
|
||||||
// This is an action to be able to commit other mutations
|
// This is an action to be able to commit other mutations
|
||||||
addTaskAttachment(ctx: ActionContext<TaskState, RootStoreState>, {
|
addTaskAttachment(ctx, {
|
||||||
taskId,
|
taskId,
|
||||||
attachment,
|
attachment,
|
||||||
}: {
|
}: {
|
||||||
|
@ -130,7 +130,7 @@ export default {
|
||||||
ctx.commit('attachments/add', attachment, {root: true})
|
ctx.commit('attachments/add', attachment, {root: true})
|
||||||
},
|
},
|
||||||
|
|
||||||
async addAssignee(ctx: ActionContext<TaskState, RootStoreState>, {
|
async addAssignee(ctx, {
|
||||||
user,
|
user,
|
||||||
taskId,
|
taskId,
|
||||||
}: {
|
}: {
|
||||||
|
@ -165,7 +165,7 @@ export default {
|
||||||
return r
|
return r
|
||||||
},
|
},
|
||||||
|
|
||||||
async removeAssignee(ctx: ActionContext<TaskState, RootStoreState>, {
|
async removeAssignee(ctx, {
|
||||||
user,
|
user,
|
||||||
taskId,
|
taskId,
|
||||||
}: {
|
}: {
|
||||||
|
@ -198,7 +198,7 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async addLabel(ctx: ActionContext<TaskState, RootStoreState>, {
|
async addLabel(ctx, {
|
||||||
label,
|
label,
|
||||||
taskId,
|
taskId,
|
||||||
} : {
|
} : {
|
||||||
|
@ -234,7 +234,7 @@ export default {
|
||||||
return r
|
return r
|
||||||
},
|
},
|
||||||
|
|
||||||
async removeLabel(ctx: ActionContext<TaskState, RootStoreState>, {label, taskId}) {
|
async removeLabel(ctx, {label, taskId}) {
|
||||||
const labelTask = new LabelTaskModel({taskId, labelId: label.id})
|
const labelTask = new LabelTaskModel({taskId, labelId: label.id})
|
||||||
|
|
||||||
const labelTaskService = new LabelTaskService()
|
const labelTaskService = new LabelTaskService()
|
||||||
|
@ -263,7 +263,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Do everything that is involved in finding, creating and adding the label to the task
|
// Do everything that is involved in finding, creating and adding the label to the task
|
||||||
async addLabelsToTask({rootState, dispatch}: ActionContext<TaskState, RootStoreState>, {
|
async addLabelsToTask({rootState, dispatch}, {
|
||||||
task,
|
task,
|
||||||
parsedLabels,
|
parsedLabels,
|
||||||
}) {
|
}) {
|
||||||
|
@ -289,7 +289,7 @@ export default {
|
||||||
return task
|
return task
|
||||||
},
|
},
|
||||||
|
|
||||||
findListId({ rootGetters }: ActionContext<TaskState, RootStoreState>, { list: listName, listId }: {
|
findListId({ rootGetters }, { list: listName, listId }: {
|
||||||
list: string,
|
list: string,
|
||||||
listId: IList['id']
|
listId: IList['id']
|
||||||
}) {
|
}) {
|
||||||
|
@ -320,7 +320,7 @@ export default {
|
||||||
return foundListId
|
return foundListId
|
||||||
},
|
},
|
||||||
|
|
||||||
async createNewTask({dispatch, commit}: ActionContext<TaskState, RootStoreState>, {
|
async createNewTask({dispatch, commit}, {
|
||||||
title,
|
title,
|
||||||
bucketId,
|
bucketId,
|
||||||
listId,
|
listId,
|
||||||
|
@ -367,3 +367,5 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default tasksStore
|
|
@ -15,16 +15,6 @@ export interface RootStoreState {
|
||||||
menuActive: boolean,
|
menuActive: boolean,
|
||||||
keyboardShortcutsActive: boolean,
|
keyboardShortcutsActive: boolean,
|
||||||
quickActionsActive: boolean,
|
quickActionsActive: boolean,
|
||||||
|
|
||||||
// modules
|
|
||||||
attachments: AttachmentState,
|
|
||||||
auth: AuthState,
|
|
||||||
config: ConfigState,
|
|
||||||
kanban: KanbanState,
|
|
||||||
labels: LabelState,
|
|
||||||
lists: ListState,
|
|
||||||
namespaces: NamespaceState,
|
|
||||||
tasks: TaskState,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttachmentState {
|
export interface AttachmentState {
|
||||||
|
@ -114,3 +104,15 @@ export interface NamespaceState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TaskState {}
|
export interface TaskState {}
|
||||||
|
|
||||||
|
|
||||||
|
export type StoreState = RootStoreState & {
|
||||||
|
config: ConfigState,
|
||||||
|
auth: AuthState,
|
||||||
|
namespaces: NamespaceState,
|
||||||
|
kanban: KanbanState,
|
||||||
|
tasks: TaskState,
|
||||||
|
lists: ListState,
|
||||||
|
attachments: AttachmentState,
|
||||||
|
labels: LabelState,
|
||||||
|
}
|
27
src/types/shims-vue.d.ts
vendored
27
src/types/shims-vue.d.ts
vendored
|
@ -1,13 +1,30 @@
|
||||||
// https://next.vuex.vuejs.org/guide/migrating-to-4-0-from-3-x.html#typescript-support
|
// https://next.vuex.vuejs.org/guide/migrating-to-4-0-from-3-x.html#typescript-support
|
||||||
import { Store } from 'vuex'
|
import { Store } from 'vuex'
|
||||||
|
|
||||||
|
import type {
|
||||||
|
RootStoreState,
|
||||||
|
AttachmentState,
|
||||||
|
AuthState,
|
||||||
|
ConfigState,
|
||||||
|
KanbanState,
|
||||||
|
LabelState,
|
||||||
|
ListState,
|
||||||
|
NamespaceState,
|
||||||
|
TaskState,
|
||||||
|
} from '@/store/types'
|
||||||
|
|
||||||
declare module '@vue/runtime-core' {
|
declare module '@vue/runtime-core' {
|
||||||
// Declare your own store states.
|
|
||||||
interface State {
|
|
||||||
count: number
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ComponentCustomProperties {
|
interface ComponentCustomProperties {
|
||||||
$store: Store<State>
|
$store: Store<RootStoreState & {
|
||||||
|
config: ConfigState,
|
||||||
|
auth: AuthState,
|
||||||
|
namespaces: NamespaceState,
|
||||||
|
kanban: KanbanState,
|
||||||
|
tasks: TaskState,
|
||||||
|
lists: ListState,
|
||||||
|
attachments: AttachmentState,
|
||||||
|
labels: LabelState,
|
||||||
|
}>
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -60,7 +60,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, computed} from 'vue'
|
import {ref, computed} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import Message from '@/components/misc/message.vue'
|
import Message from '@/components/misc/message.vue'
|
||||||
import ShowTasks from '@/views/tasks/ShowTasks.vue'
|
import ShowTasks from '@/views/tasks/ShowTasks.vue'
|
||||||
|
|
|
@ -69,7 +69,7 @@ import {ref, computed} from 'vue'
|
||||||
import flatPickr from 'vue-flatpickr-component'
|
import flatPickr from 'vue-flatpickr-component'
|
||||||
|
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import ListWrapper from './ListWrapper.vue'
|
import ListWrapper from './ListWrapper.vue'
|
||||||
import GanttChart from '@/components/tasks/gantt-component.vue'
|
import GanttChart from '@/components/tasks/gantt-component.vue'
|
||||||
|
|
|
@ -60,7 +60,7 @@ import {BACKGROUND, BLUR_HASH, CURRENT_LIST} from '@/store/mutation-types'
|
||||||
import {getListTitle} from '@/helpers/getListTitle'
|
import {getListTitle} from '@/helpers/getListTitle'
|
||||||
import {saveListToHistory} from '@/modules/listHistory'
|
import {saveListToHistory} from '@/modules/listHistory'
|
||||||
import {useTitle} from '@/composables/useTitle'
|
import {useTitle} from '@/composables/useTitle'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
listId: {
|
listId: {
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
import {ref, reactive, shallowReactive} from 'vue'
|
import {ref, reactive, shallowReactive} from 'vue'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useRouter, useRoute} from 'vue-router'
|
import {useRouter, useRoute} from 'vue-router'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import ListService from '@/services/list'
|
import ListService from '@/services/list'
|
||||||
import ListModel from '@/models/list'
|
import ListModel from '@/models/list'
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default {name: 'list-setting-archive'}
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed} from 'vue'
|
import {computed} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useRouter, useRoute} from 'vue-router'
|
import {useRouter, useRoute} from 'vue-router'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
import {computed, ref, watchEffect} from 'vue'
|
import {computed, ref, watchEffect} from 'vue'
|
||||||
import {useTitle} from '@/composables/useTitle'
|
import {useTitle} from '@/composables/useTitle'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useRoute, useRouter} from 'vue-router'
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
import {success} from '@/message'
|
import {success} from '@/message'
|
||||||
import TaskCollectionService from '@/services/taskCollection'
|
import TaskCollectionService from '@/services/taskCollection'
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, shallowReactive} from 'vue'
|
import {ref, shallowReactive} from 'vue'
|
||||||
import {useRoute, useRouter} from 'vue-router'
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import ListDuplicateService from '@/services/listDuplicateService'
|
import ListDuplicateService from '@/services/listDuplicateService'
|
||||||
|
|
|
@ -28,7 +28,7 @@ export default {name: 'list-setting-share'}
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, computed, watchEffect} from 'vue'
|
import {ref, computed, watchEffect} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useRoute} from 'vue-router'
|
import {useRoute} from 'vue-router'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useTitle} from '@vueuse/core'
|
import {useTitle} from '@vueuse/core'
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed} from 'vue'
|
import {computed} from 'vue'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import {MIGRATORS} from './migrators'
|
import {MIGRATORS} from './migrators'
|
||||||
import {useTitle} from '@/composables/useTitle'
|
import {useTitle} from '@/composables/useTitle'
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {nextTick, ref, watch} from 'vue'
|
import {nextTick, ref, watch} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {success} from '@/message'
|
import {success} from '@/message'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default { name: 'namespace-setting-share' }
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, computed, watchEffect} from 'vue'
|
import {ref, computed, watchEffect} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useRoute} from 'vue-router'
|
import {useRoute} from 'vue-router'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useTitle} from '@vueuse/core'
|
import {useTitle} from '@vueuse/core'
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, computed} from 'vue'
|
import {ref, computed} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useRoute, useRouter} from 'vue-router'
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useTitle} from '@vueuse/core'
|
import {useTitle} from '@vueuse/core'
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, ref, watchEffect} from 'vue'
|
import {computed, ref, watchEffect} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useRoute, useRouter} from 'vue-router'
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ import {computed, ref} from 'vue'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import Editor from '@/components/input/AsyncEditor'
|
import Editor from '@/components/input/AsyncEditor'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import TeamService from '@/services/team'
|
import TeamService from '@/services/team'
|
||||||
import TeamMemberService from '@/services/teamMember'
|
import TeamMemberService from '@/services/teamMember'
|
||||||
|
|
|
@ -15,7 +15,7 @@ export default { name: 'Auth' }
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, computed, onMounted} from 'vue'
|
import {ref, computed, onMounted} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useRoute, useRouter} from 'vue-router'
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ export default { name: 'user-settings-avatar' }
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, ref, shallowReactive} from 'vue'
|
import {computed, ref, shallowReactive} from 'vue'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {Cropper} from 'vue-advanced-cropper'
|
import {Cropper} from 'vue-advanced-cropper'
|
||||||
import 'vue-advanced-cropper/dist/style.css'
|
import 'vue-advanced-cropper/dist/style.css'
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {computed, ref, shallowReactive} from 'vue'
|
import {computed, ref, shallowReactive} from 'vue'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import {CALDAV_DOCS} from '@/urls'
|
import {CALDAV_DOCS} from '@/urls'
|
||||||
import {useTitle} from '@/composables/useTitle'
|
import {useTitle} from '@/composables/useTitle'
|
||||||
|
|
|
@ -44,7 +44,7 @@ export default {name: 'user-settings-data-export'}
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, computed, shallowReactive} from 'vue'
|
import {ref, computed, shallowReactive} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import DataExportService from '@/services/dataExport'
|
import DataExportService from '@/services/dataExport'
|
||||||
|
|
|
@ -88,7 +88,7 @@ export default { name: 'user-settings-deletion' }
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, shallowReactive, computed} from 'vue'
|
import {ref, shallowReactive, computed} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import AccountDeleteService from '@/services/accountDelete'
|
import AccountDeleteService from '@/services/accountDelete'
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default { name: 'user-settings-update-email' }
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {reactive, computed, shallowReactive} from 'vue'
|
import {reactive, computed, shallowReactive} from 'vue'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import EmailUpdateService from '@/services/emailUpdate'
|
import EmailUpdateService from '@/services/emailUpdate'
|
||||||
import EmailUpdateModel from '@/models/emailUpdate'
|
import EmailUpdateModel from '@/models/emailUpdate'
|
||||||
|
|
|
@ -157,7 +157,7 @@ export default defineComponent({
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, watch, ref} from 'vue'
|
import {computed, watch, ref} from 'vue'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import {PrefixMode} from '@/modules/parseTaskText'
|
import {PrefixMode} from '@/modules/parseTaskText'
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ export default {name: 'user-settings-password-update'}
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, reactive, shallowReactive, computed} from 'vue'
|
import {ref, reactive, shallowReactive, computed} from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useStore } from 'vuex'
|
import {useStore} from '@/store'
|
||||||
|
|
||||||
import PasswordUpdateService from '@/services/passwordUpdateService'
|
import PasswordUpdateService from '@/services/passwordUpdateService'
|
||||||
import PasswordUpdateModel from '@/models/passwordUpdate'
|
import PasswordUpdateModel from '@/models/passwordUpdate'
|
||||||
|
|
|
@ -70,7 +70,7 @@ export default { name: 'user-settings-totp' }
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {computed, ref, shallowReactive} from 'vue'
|
import {computed, ref, shallowReactive} from 'vue'
|
||||||
import {useStore} from 'vuex'
|
import {useStore} from '@/store'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import TotpService from '@/services/totp'
|
import TotpService from '@/services/totp'
|
||||||
|
|
Loading…
Reference in a new issue