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 {useRouter} from 'vue-router'
|
||||
import {useRouteQuery} from '@vueuse/router'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import isTouchDevice from 'is-touch-device'
|
||||
import {success} from '@/message'
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import {computed, ref, watch} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import flatPickr from 'vue-flatpickr-component'
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {computed} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import BaseButton from '@/components/base/BaseButton.vue'
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref, computed, onMounted, nextTick} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useRouter} from 'vue-router'
|
||||
|
||||
import {QUICK_ACTIONS_ACTIVE} from '@/store/mutation-types'
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
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 {useEventListener} from '@vueuse/core'
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import {computed} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import Logo from '@/components/home/Logo.vue'
|
||||
import PoweredByLink from './PoweredByLink.vue'
|
||||
|
|
|
@ -141,7 +141,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref, computed, onMounted, onBeforeMount} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import draggable from 'zhyswan-vuedraggable'
|
||||
import type {SortableEvent} from 'sortablejs'
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref, computed, watchEffect, type PropType} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import {getSavedFilterIdFromListId} from '@/helpers/savedFilter'
|
||||
import Dropdown from '@/components/misc/dropdown.vue'
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import {type PropType, ref, watch} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import ListService from '@/services/list'
|
||||
import {getBlobFromBlurHash} from '@/helpers/getBlobFromBlurHash'
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import Shortcut from '@/components/misc/shortcut.vue'
|
||||
import Message from '@/components/misc/message.vue'
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import {computed} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
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 Legal from '@/components/misc/legal.vue'
|
||||
import ApiConfig from '@/components/misc/api-config.vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {computed} from 'vue'
|
||||
import {useRoute} from 'vue-router'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import Logo from '@/assets/logo.svg?component'
|
||||
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 { NOTIFICATION_NAMES as names, type INotification} from '@/models/notification'
|
||||
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useRouter} from 'vue-router'
|
||||
import {formatDateLong, formatDateSince} from '@/helpers/time/formatDate'
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref, watch, computed, shallowReactive} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import {RIGHTS} from '@/models/constants/rights'
|
||||
|
|
|
@ -139,7 +139,7 @@ export default {name: 'userTeamShare'}
|
|||
<script setup lang="ts">
|
||||
import {ref, reactive, computed, shallowReactive, type ShallowReactive, type Ref} from 'vue'
|
||||
import type {PropType} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import UserNamespaceService from '@/services/userNamespace'
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
<script setup lang="ts">
|
||||
import {ref, watch, unref, shallowReactive} from 'vue'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {tryOnMounted, debouncedWatch, useWindowSize, type MaybeRef} from '@vueuse/core'
|
||||
|
||||
import TaskService from '@/services/task'
|
||||
|
|
|
@ -153,7 +153,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref, reactive, computed, shallowReactive, watch, nextTick} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import Editor from '@/components/input/AsyncEditor'
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
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 flatPickr from 'vue-flatpickr-component'
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref,computed, watch, type PropType} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import Editor from '@/components/input/AsyncEditor'
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref, shallowReactive, watch, type PropType} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import User from '@/components/misc/user.vue'
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {type PropType, ref, computed, shallowReactive, watch} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import LabelModel, { type ILabel } from '@/models/label'
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref, computed, type PropType} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import BaseButton from '@/components/base/BaseButton.vue'
|
||||
import Done from '@/components/misc/Done.vue'
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<script lang="ts" setup>
|
||||
import {reactive, ref, watch} from 'vue'
|
||||
import type {PropType} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import ListModel, { type IList } from '@/models/list'
|
||||
import Multiselect from '@/components/input/multiselect.vue'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {ref, computed} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
export function useNameSpaceSearch() {
|
||||
const query = ref('')
|
||||
|
|
|
@ -14,7 +14,7 @@ import Notifications from '@kyvg/vue3-notification'
|
|||
import './registerServiceWorker'
|
||||
|
||||
// Vuex
|
||||
import {store} from './store'
|
||||
import { store, key } from './store'
|
||||
// i18n
|
||||
import {i18n} from './i18n'
|
||||
|
||||
|
@ -104,7 +104,7 @@ if (window.SENTRY_ENABLED) {
|
|||
import('./sentry').then(sentry => sentry.default(app, router))
|
||||
}
|
||||
|
||||
app.use(store)
|
||||
app.use(store, key) // pass the injection key
|
||||
app.use(router)
|
||||
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 {
|
||||
BACKGROUND,
|
||||
|
@ -25,7 +28,14 @@ import ListModel from '@/models/list'
|
|||
import ListService from '../services/list'
|
||||
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>({
|
||||
strict: import.meta.env.DEV,
|
||||
|
|
|
@ -1,26 +1,29 @@
|
|||
import type { Module } from 'vuex'
|
||||
import {findIndexById} from '@/helpers/utils'
|
||||
|
||||
import type { AttachmentState } from '@/store/types'
|
||||
import type { AttachmentState, RootStoreState } from '@/store/types'
|
||||
import type { IAttachment } from '@/models/attachment'
|
||||
|
||||
export default {
|
||||
const store : Module<AttachmentState, RootStoreState> = {
|
||||
namespaced: true,
|
||||
state: (): AttachmentState => ({
|
||||
state: () => ({
|
||||
attachments: [],
|
||||
}),
|
||||
mutations: {
|
||||
set(state: AttachmentState, attachments: IAttachment[]) {
|
||||
set(state, attachments: IAttachment[]) {
|
||||
console.debug('Set attachments', attachments)
|
||||
state.attachments = attachments
|
||||
},
|
||||
add(state: AttachmentState, attachment: IAttachment) {
|
||||
add(state, attachment: IAttachment) {
|
||||
console.debug('Add attachement', attachment)
|
||||
state.attachments.push(attachment)
|
||||
},
|
||||
removeById(state: AttachmentState, id: IAttachment['id']) {
|
||||
removeById(state, id: IAttachment['id']) {
|
||||
const attachmentIndex = findIndexById<IAttachment>(state.attachments, id)
|
||||
state.attachments.splice(attachmentIndex, 1)
|
||||
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 {i18n, getCurrentLanguage, saveLanguage} from '@/i18n'
|
||||
|
@ -22,25 +22,25 @@ const defaultSettings = settings => {
|
|||
return settings
|
||||
}
|
||||
|
||||
export default {
|
||||
const authStore : Module<AuthState, RootStoreState> = {
|
||||
namespaced: true,
|
||||
state: (): AuthState => ({
|
||||
state: () => ({
|
||||
authenticated: false,
|
||||
isLinkShareAuth: false,
|
||||
info: null,
|
||||
needsTotpPasscode: false,
|
||||
avatarUrl: '',
|
||||
lastUserInfoRefresh: null,
|
||||
settings: {},
|
||||
settings: {}, // should be IUserSettings
|
||||
}),
|
||||
getters: {
|
||||
authUser(state: AuthState) {
|
||||
authUser(state) {
|
||||
return state.authenticated && (
|
||||
state.info &&
|
||||
state.info.type === AUTH_TYPES.USER
|
||||
)
|
||||
},
|
||||
authLinkShare(state: AuthState) {
|
||||
authLinkShare(state) {
|
||||
return state.authenticated && (
|
||||
state.info &&
|
||||
state.info.type === AUTH_TYPES.LINK_SHARE
|
||||
|
@ -48,7 +48,7 @@ export default {
|
|||
},
|
||||
},
|
||||
mutations: {
|
||||
info(state: AuthState, info: Info) {
|
||||
info(state, info: Info) {
|
||||
state.info = info
|
||||
if (info !== null) {
|
||||
state.avatarUrl = info.getAvatarUrl()
|
||||
|
@ -60,32 +60,32 @@ export default {
|
|||
state.isLinkShareAuth = info.id < 0
|
||||
}
|
||||
},
|
||||
setUserSettings(state: AuthState, settings: IUserSettings) {
|
||||
setUserSettings(state, settings: IUserSettings) {
|
||||
state.settings = defaultSettings(settings)
|
||||
const info = state.info !== null ? state.info : {} as Info
|
||||
info.name = settings.name
|
||||
state.info = info
|
||||
},
|
||||
authenticated(state: AuthState, authenticated: boolean) {
|
||||
authenticated(state, authenticated: boolean) {
|
||||
state.authenticated = authenticated
|
||||
},
|
||||
isLinkShareAuth(state: AuthState, isLinkShareAuth: boolean) {
|
||||
isLinkShareAuth(state, isLinkShareAuth: boolean) {
|
||||
state.isLinkShareAuth = isLinkShareAuth
|
||||
},
|
||||
needsTotpPasscode(state: AuthState, needsTotpPasscode: boolean) {
|
||||
needsTotpPasscode(state, needsTotpPasscode: boolean) {
|
||||
state.needsTotpPasscode = needsTotpPasscode
|
||||
},
|
||||
reloadAvatar(state: AuthState) {
|
||||
reloadAvatar(state) {
|
||||
if (!state.info) return
|
||||
state.avatarUrl = `${state.info.getAvatarUrl()}&=${+new Date()}`
|
||||
},
|
||||
lastUserRefresh(state: AuthState) {
|
||||
lastUserRefresh(state) {
|
||||
state.lastUserInfoRefresh = new Date()
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
// Logs a user in with a set of credentials.
|
||||
async login(ctx: ActionContext<AuthState, RootStoreState>, credentials) {
|
||||
async login(ctx, credentials) {
|
||||
const HTTP = HTTPFactory()
|
||||
ctx.commit(LOADING, true, {root: true})
|
||||
|
||||
|
@ -116,7 +116,7 @@ export default {
|
|||
|
||||
// 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.
|
||||
async register(ctx: ActionContext<AuthState, RootStoreState>, credentials) {
|
||||
async register(ctx, credentials) {
|
||||
const HTTP = HTTPFactory()
|
||||
ctx.commit(LOADING, true, {root: true})
|
||||
try {
|
||||
|
@ -133,7 +133,7 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
async openIdAuth(ctx: ActionContext<AuthState, RootStoreState>, {provider, code}) {
|
||||
async openIdAuth(ctx, {provider, code}) {
|
||||
const HTTP = HTTPFactory()
|
||||
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 response = await HTTP.post('/shares/' + hash + '/auth', {
|
||||
password: password,
|
||||
|
@ -166,7 +166,7 @@ export default {
|
|||
},
|
||||
|
||||
// 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.
|
||||
// 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
|
||||
if (
|
||||
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()
|
||||
if (!jwt) {
|
||||
return
|
||||
|
@ -244,7 +244,7 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
async saveUserSettings(ctx: ActionContext<AuthState, RootStoreState>, payload) {
|
||||
async saveUserSettings(ctx, payload) {
|
||||
const {settings} = payload
|
||||
const showMessage = payload.showMessage ?? true
|
||||
const userSettingsService = new UserSettingsService()
|
||||
|
@ -265,7 +265,7 @@ export default {
|
|||
},
|
||||
|
||||
// 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
|
||||
// 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.
|
||||
|
@ -286,10 +286,12 @@ export default {
|
|||
}
|
||||
}, 5000)
|
||||
},
|
||||
logout(ctx: ActionContext<AuthState, RootStoreState>) {
|
||||
logout(ctx) {
|
||||
removeToken()
|
||||
window.localStorage.clear() // Clear all settings and history we might have saved in local storage.
|
||||
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 {CONFIG} from '../mutation-types'
|
||||
|
@ -6,9 +6,9 @@ import {HTTPFactory} from '@/http-common'
|
|||
import {objectToCamelCase} from '@/helpers/case'
|
||||
import type { RootStoreState, ConfigState } from '@/store/types'
|
||||
|
||||
export default {
|
||||
const configStore : Module<ConfigState, RootStoreState> = {
|
||||
namespaced: true,
|
||||
state: (): ConfigState => ({
|
||||
state: () => ({
|
||||
// These are the api defaults.
|
||||
version: '',
|
||||
frontendUrl: '',
|
||||
|
@ -39,23 +39,25 @@ export default {
|
|||
},
|
||||
}),
|
||||
getters: {
|
||||
migratorsEnabled: (state: ConfigState) => state.availableMigrators?.length > 0,
|
||||
migratorsEnabled: (state) => state.availableMigrators?.length > 0,
|
||||
apiBase() {
|
||||
const {host, protocol} = parseURL(window.API_URL)
|
||||
return protocol + '//' + host
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
[CONFIG](state: ConfigState, config: ConfigState) {
|
||||
[CONFIG](state, config: ConfigState) {
|
||||
Object.assign(state, config)
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async update(ctx: ActionContext<ConfigState, RootStoreState>) {
|
||||
async update(ctx) {
|
||||
const HTTP = HTTPFactory()
|
||||
const {data: config} = await HTTP.get('info')
|
||||
ctx.commit(CONFIG, objectToCamelCase(config))
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default configStore
|
|
@ -1,3 +1,4 @@
|
|||
import type { Module } from 'vuex'
|
||||
import cloneDeep from 'lodash.clonedeep'
|
||||
|
||||
import {findById, findIndexById} from '@/helpers/utils'
|
||||
|
@ -7,7 +8,6 @@ import {success} from '@/message'
|
|||
import BucketService from '../../services/bucket'
|
||||
import {setLoading} from '../helper'
|
||||
import TaskCollectionService from '@/services/taskCollection'
|
||||
import type { ActionContext } from 'vuex'
|
||||
import type { RootStoreState, KanbanState } from '@/store/types'
|
||||
import type { ITask } from '@/models/task'
|
||||
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.
|
||||
* It should hold only the current buckets.
|
||||
*/
|
||||
export default {
|
||||
const kanbanStore : Module<KanbanState, RootStoreState> = {
|
||||
namespaced: true,
|
||||
|
||||
state: (): KanbanState => ({
|
||||
state: () => ({
|
||||
buckets: [],
|
||||
listId: 0,
|
||||
bucketLoading: {},
|
||||
|
@ -50,11 +50,11 @@ export default {
|
|||
}),
|
||||
|
||||
mutations: {
|
||||
setListId(state: KanbanState, listId: IList['id']) {
|
||||
setListId(state, listId: IList['id']) {
|
||||
state.listId = parseInt(listId)
|
||||
},
|
||||
|
||||
setBuckets(state: KanbanState, buckets: IBucket[]) {
|
||||
setBuckets(state, buckets: IBucket[]) {
|
||||
state.buckets = buckets
|
||||
buckets.forEach(b => {
|
||||
state.taskPagesPerBucket[b.id] = 1
|
||||
|
@ -62,21 +62,21 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
addBucket(state: KanbanState, bucket: IBucket) {
|
||||
addBucket(state, bucket: IBucket) {
|
||||
state.buckets.push(bucket)
|
||||
},
|
||||
|
||||
removeBucket(state: KanbanState, bucket: IBucket) {
|
||||
removeBucket(state, bucket: IBucket) {
|
||||
const bucketIndex = findIndexById(state.buckets, bucket.id)
|
||||
state.buckets.splice(bucketIndex, 1)
|
||||
},
|
||||
|
||||
setBucketById(state: KanbanState, bucket: IBucket) {
|
||||
setBucketById(state, bucket: IBucket) {
|
||||
const bucketIndex = findIndexById(state.buckets, bucket.id)
|
||||
state.buckets[bucketIndex] = bucket
|
||||
},
|
||||
|
||||
setBucketByIndex(state: KanbanState, {
|
||||
setBucketByIndex(state, {
|
||||
bucketIndex,
|
||||
bucket,
|
||||
} : {
|
||||
|
@ -86,7 +86,7 @@ export default {
|
|||
state.buckets[bucketIndex] = bucket
|
||||
},
|
||||
|
||||
setTaskInBucketByIndex(state: KanbanState, {
|
||||
setTaskInBucketByIndex(state, {
|
||||
bucketIndex,
|
||||
taskIndex,
|
||||
task,
|
||||
|
@ -100,7 +100,7 @@ export default {
|
|||
state.buckets[bucketIndex] = bucket
|
||||
},
|
||||
|
||||
setTasksInBucketByBucketId(state: KanbanState, {
|
||||
setTasksInBucketByBucketId(state, {
|
||||
bucketId,
|
||||
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 (state.buckets.length === 0) {
|
||||
return
|
||||
|
@ -158,7 +158,7 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
addTaskToBucket(state: KanbanState, task: ITask) {
|
||||
addTaskToBucket(state, task: ITask) {
|
||||
const bucketIndex = findIndexById(state.buckets, task.bucketId)
|
||||
const oldBucket = state.buckets[bucketIndex]
|
||||
const newBucket = {
|
||||
|
@ -171,7 +171,7 @@ export default {
|
|||
state.buckets[bucketIndex] = newBucket
|
||||
},
|
||||
|
||||
addTasksToBucket(state: KanbanState, {tasks, bucketId}: {
|
||||
addTasksToBucket(state, {tasks, bucketId}: {
|
||||
tasks: ITask[];
|
||||
bucketId: IBucket['id'];
|
||||
}) {
|
||||
|
@ -187,7 +187,7 @@ export default {
|
|||
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 (state.buckets.length === 0) {
|
||||
return
|
||||
|
@ -207,7 +207,7 @@ export default {
|
|||
state.buckets[bucketIndex].tasks.splice(taskIndex, 1)
|
||||
},
|
||||
|
||||
setBucketLoading(state: KanbanState, {bucketId, loading}) {
|
||||
setBucketLoading(state, {bucketId, loading}) {
|
||||
state.bucketLoading[bucketId] = loading
|
||||
},
|
||||
|
||||
|
@ -221,11 +221,11 @@ export default {
|
|||
},
|
||||
|
||||
getters: {
|
||||
getBucketById(state: KanbanState) {
|
||||
getBucketById(state) {
|
||||
return (bucketId) => findById(state.buckets, bucketId)
|
||||
},
|
||||
|
||||
getTaskById(state: KanbanState) {
|
||||
getTaskById(state) {
|
||||
return (id) => {
|
||||
const { bucketIndex, taskIndex } = getTaskIndicesById(state, id)
|
||||
|
||||
|
@ -240,7 +240,7 @@ export default {
|
|||
},
|
||||
|
||||
actions: {
|
||||
async loadBucketsForList(ctx: ActionContext<KanbanState, RootStoreState>, {listId, params}) {
|
||||
async loadBucketsForList(ctx, {listId, params}) {
|
||||
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
|
||||
|
@ -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
|
||||
if (isLoading) {
|
||||
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 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 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 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)
|
||||
|
||||
if (bucket?.title === title) {
|
||||
|
@ -387,4 +387,6 @@ export default {
|
|||
success({message: i18n.global.t('list.kanban.bucketTitleSavedSuccess')})
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default kanbanStore
|
|
@ -1,4 +1,4 @@
|
|||
import type { ActionContext } from 'vuex'
|
||||
import type { Module } from 'vuex'
|
||||
|
||||
import {i18n} from '@/i18n'
|
||||
import {success} from '@/message'
|
||||
|
@ -22,46 +22,46 @@ async function getAllLabels(page = 1): Promise<ILabel[]> {
|
|||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
const LabelStore : Module<LabelState, RootStoreState> = {
|
||||
namespaced: true,
|
||||
state: (): LabelState => ({
|
||||
state: () => ({
|
||||
labels: {},
|
||||
loaded: false,
|
||||
}),
|
||||
mutations: {
|
||||
setLabels(state: LabelState, labels: ILabel[]) {
|
||||
setLabels(state, labels: ILabel[]) {
|
||||
labels.forEach(l => {
|
||||
state.labels[l.id] = l
|
||||
add(l)
|
||||
})
|
||||
},
|
||||
setLabel(state: LabelState, label: ILabel) {
|
||||
setLabel(state, label: ILabel) {
|
||||
state.labels[label.id] = label
|
||||
update(label)
|
||||
},
|
||||
removeLabelById(state: LabelState, label: ILabel) {
|
||||
removeLabelById(state, label: ILabel) {
|
||||
remove(label)
|
||||
delete state.labels[label.id]
|
||||
},
|
||||
setLoaded(state: LabelState, loaded: boolean) {
|
||||
setLoaded(state, loaded: boolean) {
|
||||
state.loaded = loaded
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
getLabelsByIds(state: LabelState) {
|
||||
getLabelsByIds(state) {
|
||||
return (ids: ILabel['id'][]) => getLabelsByIds(state, ids)
|
||||
},
|
||||
filterLabelsByQuery(state: LabelState) {
|
||||
filterLabelsByQuery(state) {
|
||||
return (labelsToHide: ILabel[], query: string) => filterLabelsByQuery(state, labelsToHide, query)
|
||||
},
|
||||
getLabelsByExactTitles(state: LabelState) {
|
||||
getLabelsByExactTitles(state) {
|
||||
return labelTitles => Object
|
||||
.values(state.labels)
|
||||
.filter(({title}) => labelTitles.some(l => l.toLowerCase() === title.toLowerCase()))
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async loadAllLabels(ctx: ActionContext<LabelState, RootStoreState>, {forceLoad} = {}) {
|
||||
async loadAllLabels(ctx, {forceLoad} = {}) {
|
||||
if (ctx.state.loaded && !forceLoad) {
|
||||
return
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ export default {
|
|||
cancel()
|
||||
}
|
||||
},
|
||||
async deleteLabel(ctx: ActionContext<LabelState, RootStoreState>, label: ILabel) {
|
||||
async deleteLabel(ctx, label: ILabel) {
|
||||
const cancel = setLoading(ctx, 'labels')
|
||||
const labelService = new LabelService()
|
||||
|
||||
|
@ -90,7 +90,7 @@ export default {
|
|||
cancel()
|
||||
}
|
||||
},
|
||||
async updateLabel(ctx: ActionContext<LabelState, RootStoreState>, label: ILabel) {
|
||||
async updateLabel(ctx, label: ILabel) {
|
||||
const cancel = setLoading(ctx, 'labels')
|
||||
const labelService = new LabelService()
|
||||
|
||||
|
@ -103,7 +103,7 @@ export default {
|
|||
cancel()
|
||||
}
|
||||
},
|
||||
async createLabel(ctx: ActionContext<LabelState, RootStoreState>, label: ILabel) {
|
||||
async createLabel(ctx, label: ILabel) {
|
||||
const cancel = setLoading(ctx, 'labels')
|
||||
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 {setLoading} from '@/store/helper'
|
||||
import {removeListFromHistory} from '@/modules/listHistory'
|
||||
import {createNewIndexer} from '@/indexes'
|
||||
import type {ListState, RootStoreState} from '@/store/types'
|
||||
import type {ActionContext} from 'vuex'
|
||||
import type {IList} from '@/models/list'
|
||||
|
||||
const {add, remove, search, update} = createNewIndexer('lists', ['title', 'description'])
|
||||
|
||||
const FavoriteListsNamespace = -2
|
||||
|
||||
export default {
|
||||
const listsStore : Module<ListState, RootStoreState>= {
|
||||
namespaced: true,
|
||||
// The state is an object which has the list ids as keys.
|
||||
state: (): ListState => ({}),
|
||||
state: () => ({}),
|
||||
mutations: {
|
||||
setList(state: ListState, list: IList) {
|
||||
setList(state, list: IList) {
|
||||
state[list.id] = list
|
||||
update(list)
|
||||
},
|
||||
setLists(state: ListState, lists: IList[]) {
|
||||
setLists(state, lists: IList[]) {
|
||||
lists.forEach(l => {
|
||||
state[l.id] = l
|
||||
add(l)
|
||||
})
|
||||
},
|
||||
removeListById(state: ListState, list: IList) {
|
||||
removeListById(state, list: IList) {
|
||||
remove(list)
|
||||
delete state[list.id]
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
getListById: (state: ListState) => (id: IList['id']) => {
|
||||
getListById: (state) => (id: IList['id']) => {
|
||||
if (typeof state[id] !== 'undefined') {
|
||||
return state[id]
|
||||
}
|
||||
return null
|
||||
},
|
||||
findListByExactname: (state: ListState) => (name: string) => {
|
||||
findListByExactname: (state) => (name: string) => {
|
||||
const list = Object.values(state).find(l => {
|
||||
return l.title.toLowerCase() === name.toLowerCase()
|
||||
})
|
||||
return typeof list === 'undefined' ? null : list
|
||||
},
|
||||
searchList: (state: ListState) => (query: string, includeArchived = false) => {
|
||||
searchList: (state) => (query: string, includeArchived = false) => {
|
||||
return search(query)
|
||||
?.filter(value => value > 0)
|
||||
.map(id => state[id])
|
||||
|
@ -52,14 +53,14 @@ export default {
|
|||
},
|
||||
},
|
||||
actions: {
|
||||
toggleListFavorite(ctx: ActionContext<ListState, RootStoreState>, list: IList) {
|
||||
toggleListFavorite(ctx, list: IList) {
|
||||
return ctx.dispatch('updateList', {
|
||||
...list,
|
||||
isFavorite: !list.isFavorite,
|
||||
})
|
||||
},
|
||||
|
||||
async createList(ctx: ActionContext<ListState, RootStoreState>, list: IList) {
|
||||
async createList(ctx, list: IList) {
|
||||
const cancel = setLoading(ctx, 'lists')
|
||||
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 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 listService = new ListService()
|
||||
|
||||
|
@ -124,4 +125,6 @@ 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 {setLoading} from '@/store/helper'
|
||||
|
@ -9,19 +9,19 @@ import type {IList} from '@/models/list'
|
|||
|
||||
const {add, remove, search, update} = createNewIndexer('namespaces', ['title', 'description'])
|
||||
|
||||
export default {
|
||||
const namespacesStore : Module<NamespaceState, RootStoreState> = {
|
||||
namespaced: true,
|
||||
state: (): NamespaceState => ({
|
||||
state: () => ({
|
||||
namespaces: [],
|
||||
}),
|
||||
mutations: {
|
||||
namespaces(state: NamespaceState, namespaces: INamespace[]) {
|
||||
namespaces(state, namespaces: INamespace[]) {
|
||||
state.namespaces = namespaces
|
||||
namespaces.forEach(n => {
|
||||
add(n)
|
||||
})
|
||||
},
|
||||
setNamespaceById(state: NamespaceState, namespace: INamespace) {
|
||||
setNamespaceById(state, namespace: INamespace) {
|
||||
const namespaceIndex = state.namespaces.findIndex(n => n.id === namespace.id)
|
||||
|
||||
if (namespaceIndex === -1) {
|
||||
|
@ -35,7 +35,7 @@ export default {
|
|||
state.namespaces[namespaceIndex] = namespace
|
||||
update(namespace)
|
||||
},
|
||||
setListInNamespaceById(state: NamespaceState, list: IList) {
|
||||
setListInNamespaceById(state, list: IList) {
|
||||
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.
|
||||
// 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)
|
||||
add(namespace)
|
||||
},
|
||||
removeNamespaceById(state: NamespaceState, namespaceId: INamespace['id']) {
|
||||
removeNamespaceById(state, namespaceId: INamespace['id']) {
|
||||
for (const n in state.namespaces) {
|
||||
if (state.namespaces[n].id === namespaceId) {
|
||||
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) {
|
||||
if (state.namespaces[n].id === list.namespaceId) {
|
||||
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) {
|
||||
// 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.
|
||||
|
@ -88,7 +88,7 @@ export default {
|
|||
},
|
||||
},
|
||||
getters: {
|
||||
getListAndNamespaceById: (state: NamespaceState) => (listId: IList['id'], ignorePseudoNamespaces = false) => {
|
||||
getListAndNamespaceById: (state) => (listId: IList['id'], ignorePseudoNamespaces = false) => {
|
||||
for (const n in state.namespaces) {
|
||||
|
||||
if (ignorePseudoNamespaces && state.namespaces[n].id < 0) {
|
||||
|
@ -106,10 +106,10 @@ export default {
|
|||
}
|
||||
return null
|
||||
},
|
||||
getNamespaceById: (state: NamespaceState) => (namespaceId: INamespace['id']) => {
|
||||
getNamespaceById: (state) => (namespaceId: INamespace['id']) => {
|
||||
return state.namespaces.find(({id}) => id == namespaceId) || null
|
||||
},
|
||||
searchNamespace: (state: NamespaceState, getters) => (query: string) => {
|
||||
searchNamespace: (state, getters) => (query: string) => {
|
||||
return search(query)
|
||||
?.filter(value => value > 0)
|
||||
.map(getters.getNamespaceById)
|
||||
|
@ -118,7 +118,7 @@ export default {
|
|||
},
|
||||
},
|
||||
actions: {
|
||||
async loadNamespaces(ctx: ActionContext<NamespaceState, RootStoreState>) {
|
||||
async loadNamespaces(ctx) {
|
||||
const cancel = setLoading(ctx, 'namespaces')
|
||||
|
||||
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
|
||||
if (ctx.state.namespaces[0].id !== -2 && ctx.state.namespaces[1]?.id !== -2) {
|
||||
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) {
|
||||
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 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 namespaceService = new NamespaceService()
|
||||
|
||||
|
@ -177,4 +177,6 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default namespacesStore
|
|
@ -1,5 +1,5 @@
|
|||
import type { Module } from 'vuex'
|
||||
import router from '@/router'
|
||||
import type { ActionContext } from 'vuex'
|
||||
import {formatISO} from 'date-fns'
|
||||
|
||||
import TaskService from '@/services/task'
|
||||
|
@ -65,11 +65,11 @@ async function findAssignees(parsedTaskAssignees) {
|
|||
}
|
||||
|
||||
|
||||
export default {
|
||||
const tasksStore : Module<TaskState, RootStoreState>= {
|
||||
namespaced: true,
|
||||
state: (): TaskState => ({}),
|
||||
state: () => ({}),
|
||||
actions: {
|
||||
async loadTasks(ctx: ActionContext<TaskState, RootStoreState>, params) {
|
||||
async loadTasks(ctx, params) {
|
||||
const taskService = new TaskService()
|
||||
|
||||
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 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 response = await taskService.delete(task)
|
||||
ctx.commit('kanban/removeTaskInBucket', task, {root: true})
|
||||
|
@ -104,7 +104,7 @@ export default {
|
|||
|
||||
// Adds a task attachment in store.
|
||||
// This is an action to be able to commit other mutations
|
||||
addTaskAttachment(ctx: ActionContext<TaskState, RootStoreState>, {
|
||||
addTaskAttachment(ctx, {
|
||||
taskId,
|
||||
attachment,
|
||||
}: {
|
||||
|
@ -130,7 +130,7 @@ export default {
|
|||
ctx.commit('attachments/add', attachment, {root: true})
|
||||
},
|
||||
|
||||
async addAssignee(ctx: ActionContext<TaskState, RootStoreState>, {
|
||||
async addAssignee(ctx, {
|
||||
user,
|
||||
taskId,
|
||||
}: {
|
||||
|
@ -165,7 +165,7 @@ export default {
|
|||
return r
|
||||
},
|
||||
|
||||
async removeAssignee(ctx: ActionContext<TaskState, RootStoreState>, {
|
||||
async removeAssignee(ctx, {
|
||||
user,
|
||||
taskId,
|
||||
}: {
|
||||
|
@ -198,7 +198,7 @@ export default {
|
|||
|
||||
},
|
||||
|
||||
async addLabel(ctx: ActionContext<TaskState, RootStoreState>, {
|
||||
async addLabel(ctx, {
|
||||
label,
|
||||
taskId,
|
||||
} : {
|
||||
|
@ -234,7 +234,7 @@ export default {
|
|||
return r
|
||||
},
|
||||
|
||||
async removeLabel(ctx: ActionContext<TaskState, RootStoreState>, {label, taskId}) {
|
||||
async removeLabel(ctx, {label, taskId}) {
|
||||
const labelTask = new LabelTaskModel({taskId, labelId: label.id})
|
||||
|
||||
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
|
||||
async addLabelsToTask({rootState, dispatch}: ActionContext<TaskState, RootStoreState>, {
|
||||
async addLabelsToTask({rootState, dispatch}, {
|
||||
task,
|
||||
parsedLabels,
|
||||
}) {
|
||||
|
@ -289,7 +289,7 @@ export default {
|
|||
return task
|
||||
},
|
||||
|
||||
findListId({ rootGetters }: ActionContext<TaskState, RootStoreState>, { list: listName, listId }: {
|
||||
findListId({ rootGetters }, { list: listName, listId }: {
|
||||
list: string,
|
||||
listId: IList['id']
|
||||
}) {
|
||||
|
@ -320,7 +320,7 @@ export default {
|
|||
return foundListId
|
||||
},
|
||||
|
||||
async createNewTask({dispatch, commit}: ActionContext<TaskState, RootStoreState>, {
|
||||
async createNewTask({dispatch, commit}, {
|
||||
title,
|
||||
bucketId,
|
||||
listId,
|
||||
|
@ -366,4 +366,6 @@ export default {
|
|||
return result
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default tasksStore
|
|
@ -15,16 +15,6 @@ export interface RootStoreState {
|
|||
menuActive: boolean,
|
||||
keyboardShortcutsActive: boolean,
|
||||
quickActionsActive: boolean,
|
||||
|
||||
// modules
|
||||
attachments: AttachmentState,
|
||||
auth: AuthState,
|
||||
config: ConfigState,
|
||||
kanban: KanbanState,
|
||||
labels: LabelState,
|
||||
lists: ListState,
|
||||
namespaces: NamespaceState,
|
||||
tasks: TaskState,
|
||||
}
|
||||
|
||||
export interface AttachmentState {
|
||||
|
@ -114,3 +104,15 @@ export interface NamespaceState {
|
|||
}
|
||||
|
||||
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
|
||||
import { Store } from 'vuex'
|
||||
|
||||
import type {
|
||||
RootStoreState,
|
||||
AttachmentState,
|
||||
AuthState,
|
||||
ConfigState,
|
||||
KanbanState,
|
||||
LabelState,
|
||||
ListState,
|
||||
NamespaceState,
|
||||
TaskState,
|
||||
} from '@/store/types'
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
// Declare your own store states.
|
||||
interface State {
|
||||
count: number
|
||||
}
|
||||
|
||||
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>
|
||||
import {ref, computed} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import Message from '@/components/misc/message.vue'
|
||||
import ShowTasks from '@/views/tasks/ShowTasks.vue'
|
||||
|
|
|
@ -69,7 +69,7 @@ import {ref, computed} from 'vue'
|
|||
import flatPickr from 'vue-flatpickr-component'
|
||||
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import ListWrapper from './ListWrapper.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 {saveListToHistory} from '@/modules/listHistory'
|
||||
import {useTitle} from '@/composables/useTitle'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
const props = defineProps({
|
||||
listId: {
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
import {ref, reactive, shallowReactive} from 'vue'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useRouter, useRoute} from 'vue-router'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import ListService from '@/services/list'
|
||||
import ListModel from '@/models/list'
|
||||
|
|
|
@ -17,7 +17,7 @@ export default {name: 'list-setting-archive'}
|
|||
|
||||
<script setup lang="ts">
|
||||
import {computed} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useRouter, useRoute} from 'vue-router'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
import {computed, ref, watchEffect} from 'vue'
|
||||
import {useTitle} from '@/composables/useTitle'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useRoute, useRouter} from 'vue-router'
|
||||
import {success} from '@/message'
|
||||
import TaskCollectionService from '@/services/taskCollection'
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<script setup lang="ts">
|
||||
import {ref, shallowReactive} from 'vue'
|
||||
import {useRoute, useRouter} from 'vue-router'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import ListDuplicateService from '@/services/listDuplicateService'
|
||||
|
|
|
@ -28,7 +28,7 @@ export default {name: 'list-setting-share'}
|
|||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, watchEffect} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useRoute} from 'vue-router'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useTitle} from '@vueuse/core'
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<script setup lang="ts">
|
||||
import {computed} from 'vue'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import {MIGRATORS} from './migrators'
|
||||
import {useTitle} from '@/composables/useTitle'
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import {nextTick, ref, watch} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {success} from '@/message'
|
||||
import router from '@/router'
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ export default { name: 'namespace-setting-share' }
|
|||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, watchEffect} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useRoute} from 'vue-router'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useTitle} from '@vueuse/core'
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useRoute, useRouter} from 'vue-router'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useTitle} from '@vueuse/core'
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {computed, ref, watchEffect} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useRoute, useRouter} from 'vue-router'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ import {computed, ref} from 'vue'
|
|||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import Editor from '@/components/input/AsyncEditor'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import TeamService from '@/services/team'
|
||||
import TeamMemberService from '@/services/teamMember'
|
||||
|
|
|
@ -15,7 +15,7 @@ export default { name: 'Auth' }
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref, computed, onMounted} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useRoute, useRouter} from 'vue-router'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ export default { name: 'user-settings-avatar' }
|
|||
<script setup lang="ts">
|
||||
import {computed, ref, shallowReactive} from 'vue'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {Cropper} from 'vue-advanced-cropper'
|
||||
import 'vue-advanced-cropper/dist/style.css'
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
<script lang="ts" setup>
|
||||
import {computed, ref, shallowReactive} from 'vue'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import {CALDAV_DOCS} from '@/urls'
|
||||
import {useTitle} from '@/composables/useTitle'
|
||||
|
|
|
@ -44,7 +44,7 @@ export default {name: 'user-settings-data-export'}
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref, computed, shallowReactive} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import DataExportService from '@/services/dataExport'
|
||||
|
|
|
@ -88,7 +88,7 @@ export default { name: 'user-settings-deletion' }
|
|||
|
||||
<script setup lang="ts">
|
||||
import {ref, shallowReactive, computed} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import AccountDeleteService from '@/services/accountDelete'
|
||||
|
|
|
@ -43,7 +43,7 @@ export default { name: 'user-settings-update-email' }
|
|||
<script setup lang="ts">
|
||||
import {reactive, computed, shallowReactive} from 'vue'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import EmailUpdateService from '@/services/emailUpdate'
|
||||
import EmailUpdateModel from '@/models/emailUpdate'
|
||||
|
|
|
@ -157,7 +157,7 @@ export default defineComponent({
|
|||
<script setup lang="ts">
|
||||
import {computed, watch, ref} from 'vue'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import {PrefixMode} from '@/modules/parseTaskText'
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ export default {name: 'user-settings-password-update'}
|
|||
<script setup lang="ts">
|
||||
import {ref, reactive, shallowReactive, computed} from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useStore } from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
|
||||
import PasswordUpdateService from '@/services/passwordUpdateService'
|
||||
import PasswordUpdateModel from '@/models/passwordUpdate'
|
||||
|
|
|
@ -70,7 +70,7 @@ export default { name: 'user-settings-totp' }
|
|||
|
||||
<script lang="ts" setup>
|
||||
import {computed, ref, shallowReactive} from 'vue'
|
||||
import {useStore} from 'vuex'
|
||||
import {useStore} from '@/store'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import TotpService from '@/services/totp'
|
||||
|
|
Loading…
Reference in a new issue