Add more typescript definitions

This commit is contained in:
Ramon Wenger 2022-02-23 23:43:43 +01:00
parent 07ac265e43
commit cf9eb76ae2
13 changed files with 94 additions and 57 deletions

12
client/src/@types/graphql.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
declare module '*.graphql' {
import {DocumentNode} from "graphql";
const Schema: DocumentNode;
export = Schema;
}
declare module '*.gql' {
import {DocumentNode} from "graphql";
const content: DocumentNode;
export default content;
}

8
client/src/@types/vuejs-logger.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
import Vue from 'vue';
import {Log} from "vuejs-logger";
declare module 'vue/types/vue' {
interface Vue {
$log: Log
}
}

View File

@ -126,11 +126,11 @@
import AddContentLink from '@/components/content-block-form/AddContentLink.vue';
import ContentElement from '@/components/content-block-form/ContentElement.vue';
import {moveToIndex, removeAtIndex, replaceAtIndex, swapElements} from '@/graphql/immutable-operations.js';
import {moveToIndex, removeAtIndex, replaceAtIndex, swapElements} from '@/graphql/immutable-operations';
import {CHOOSER, transformInnerContents} from '@/components/content-block-form/helpers.js';
import ContentElementActions from '@/components/content-block-form/ContentElementActions.vue';
import {ContentBlock, numberOrUndefined} from "@/types";
import {ContentBlock, numberOrUndefined} from "@/@types";
// TODO: refactor this file, it's huuuuuge!
@ -170,7 +170,7 @@
},
},
methods: {
update(index: number, element: any, parent: numberOrUndefined = undefined) {
update(index: number, element: any, parent?: number) {
if (parent === undefined) {
// element is top level
this.localContentBlock.contents = [
@ -195,7 +195,7 @@
];
}
},
addBlock(afterOuterIndex: number, innerIndex: numberOrUndefined = undefined) {
addBlock(afterOuterIndex: number, innerIndex?: number) {
if (innerIndex !== undefined) {
const block = this.localContentBlock.contents[afterOuterIndex];
this.localContentBlock.contents = [
@ -225,7 +225,7 @@
];
}
},
remove(outer: number, inner: numberOrUndefined = undefined, askForConfirmation = true) {
remove(outer: number, inner?: number, askForConfirmation = true) {
if(askForConfirmation) {
this.$modal.open('confirm')
.then(() => {

View File

@ -55,7 +55,7 @@ import DELETE_PROJECT_MUTATION from '@/graphql/gql/mutations/deleteProject.gql';
import PROJECTS_QUERY from '@/graphql/gql/queries/allProjects.gql';
import updateProjectShareState from '@/mixins/update-project-share-state';
import {removeAtIndex} from '@/graphql/immutable-operations';
import {removeAtIndex} from '@/graphql/immutable-operations.ts';
const Ellipses = () => import(/* webpackChunkName: "icons" */'@/components/icons/Ellipses.vue');
export default {

View File

@ -52,7 +52,7 @@
import DELETE_PROJECT_ENTRY_MUTATION from '@/graphql/gql/mutations/deleteProjectEntry.gql';
import PROJECT_QUERY from '@/graphql/gql/queries/projectQuery.gql';
import {dateFilter, dateTimeFilter} from '@/filters/date-filter';
import {removeAtIndex} from '@/graphql/immutable-operations';
import {removeAtIndex} from '@/graphql/immutable-operations.ts';
const DocumentBlock = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/DocumentBlock');

View File

@ -1,24 +1,24 @@
// signature should be in order: arr, idx, el, for readability
export const pushToArray = (arr, el) => {
export const pushToArray = (arr: any[], el: any) => {
if (!arr) {
return [el];
}
return [...arr, el];
};
export const insertAtIndex = (arr, idx, el) => {
export const insertAtIndex = (arr: any[], idx: number, el: any) => {
return [
...arr.slice(0, idx),
el,
...arr.slice(idx)
];
};
export const removeAtIndex = (arr, idx) => {
export const removeAtIndex = (arr: any[], idx: number) => {
return [
...arr.slice(0, idx),
...arr.slice(idx + 1) ,
];
};
export const replaceAtIndex = (arr, idx, el) => {
export const replaceAtIndex = (arr: any[], idx: number, el: any) => {
//todo: check array index bounds, numbers
return [
...arr.slice(0, idx),
@ -26,7 +26,7 @@ export const replaceAtIndex = (arr, idx, el) => {
...arr.slice(idx+1)
];
};
export const swapElements = (arr, idx1, idx2)=>{
export const swapElements = (arr: any[], idx1: number, idx2: number)=>{
const maxLength = arr.length - 1;
if (idx1 < 0 || idx2 < 0 || idx1 > maxLength || idx2 > maxLength) {
return [...arr];
@ -42,7 +42,7 @@ export const swapElements = (arr, idx1, idx2)=>{
...arr.slice(larger+1)
];
};
export const moveToIndex = (arr, from, to) => {
export const moveToIndex = (arr: any[], from: number, to: number) => {
const maxLength = arr.length - 1;
if (from < 0 || to < 0 || from > maxLength || to > maxLength) {
throw new Error('Index out of bounds');

View File

@ -3,7 +3,7 @@ import Vue from 'vue';
import VueVimeoPlayer from 'vue-vimeo-player';
import apolloClientFactory from './graphql/client';
import VueApollo from 'vue-apollo';
import App from './App';
import App from './App.vue';
import {postLoginRedirectUrlKey, router} from './router';
import store from '@/store/index';
import VueScrollTo from 'vue-scrollto';
@ -15,6 +15,7 @@ import VueRemoveEdges from '@/plugins/edges';
import VueMatomo from 'vue-matomo';
import VueToast from 'vue-toast-notification';
import VueLogger from 'vuejs-logger';
import {joiningClass, loginRequired, unauthorizedAccess} from "@/router/guards";
Vue.config.productionTip = false;
const isProduction = process.env.NODE_ENV === 'production';
@ -60,20 +61,7 @@ const apolloProvider = new VueApollo({
/* guards */
function getCookieValue(cookieName) {
// https://stackoverflow.com/questions/5639346/what-is-the-shortest-function-for-reading-a-cookie-by-name-in-javascript
let cookieValue = document.cookie.match('(^|[^;]+)\\s*' + cookieName + '\\s*=\\s*([^;]+)');
return cookieValue ? cookieValue.pop() : '';
}
function loginRequired(to) {
// public pages have the meta.public property set to true
return !Object.prototype.hasOwnProperty.call(to, 'meta') || !Object.prototype.hasOwnProperty.call(to.meta ,'public') || !to.meta.public;
}
function unauthorizedAccess(to) {
return loginRequired(to) && getCookieValue('loginStatus') !== 'true';
}
function redirectUsersWithoutValidLicense() {
return privateApolloClient.query({
@ -100,9 +88,6 @@ function networkErrorCallback(statusCode) {
}
}
function joiningClass(to) {
return to.name && (to.name === 'join-class' || to.name === 'licenseActivation');
}
router.beforeEach(async (to, from, next) => {
Vue.$log.debug('navigation guard called', to, from);

View File

@ -1,13 +0,0 @@
import Vue from 'vue';
interface Modal {
confirm: (res: any) => void,
open: (component: string, payload?: any) => Promise<(resolve: () => any, reject: () => any) => void>,
cancel: () => void
}
declare module 'vue/types/vue' {
interface Vue {
$modal: Modal
}
}

View File

@ -1,8 +1,11 @@
// adapted from
// https://stackoverflow.com/questions/41791193/vuejs-reactive-binding-for-a-plugin-how-to/41801107#41801107
import Vue from 'vue';
import Vue, {VueConstructor} from 'vue';
class ModalStore {
vm: Vue;
class ModalStore {
constructor() {
this.vm = new Vue({
data: () => ({
@ -17,20 +20,37 @@ class ModalStore {
}
}
interface Modal {
state: any,
component: string,
payload?: any,
confirm: (res: any) => void,
open: (component: string, payload?: any) => Promise<(resolve: () => any, reject: () => any) => void>,
cancel: () => void,
_resolve: (r?: any) => any,
_reject: (r?: any) => any
}
declare module 'vue/types/vue' {
interface Vue {
$modal: Modal
}
}
const ModalPlugin = {
install(Vue) {
const store = new ModalStore({});
install(Vue: VueConstructor) {
const store = new ModalStore();
const reset = () => {
store.state.component = '';
store.state.payload = {};
};
Vue.prototype.$modal = {
const modal: Modal = {
state: store.state,
component: store.state.component,
payload: store.state.payload,
open: (component, payload) => {
open(component: string, payload?: any) {
store.state.payload = payload;
store.state.component = component;
return new Promise((resolve, reject) => {
@ -38,11 +58,11 @@ const ModalPlugin = {
this._reject = reject;
});
},
confirm: (res) => {
confirm(res: any) {
reset();
this._resolve(res);
},
cancel: () => {
cancel() {
reset();
this._reject();
},
@ -51,6 +71,8 @@ const ModalPlugin = {
_reject: () => {
},
};
Vue.prototype.$modal = modal;
}
};

View File

@ -0,0 +1,21 @@
import {Route} from "vue-router";
function getCookieValue(cookieName: string) {
// https://stackoverflow.com/questions/5639346/what-is-the-shortest-function-for-reading-a-cookie-by-name-in-javascript
const cookieValue = document.cookie.match('(^|[^;]+)\\s*' + cookieName + '\\s*=\\s*([^;]+)');
return cookieValue ? cookieValue.pop() : '';
}
export function loginRequired(to: Route) {
// public pages have the meta.public property set to true
const isPublic = to.meta && to.meta.public;
return !isPublic;
}
export function unauthorizedAccess(to: Route) {
return loginRequired(to) && getCookieValue('loginStatus') !== 'true';
}
export function joiningClass(to: Route) {
return to.name && (to.name === 'join-class' || to.name === 'licenseActivation');
}

8
client/src/router/router.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
import 'vue-router';
declare module 'vue-router' {
interface RouteMeta {
public?: boolean;
}
}

View File

@ -12,12 +12,6 @@
"paths": {
"@/*": ["./*"],
},
"types": [
"cypress"
],
"plugins": [{"name": "typescript-tslint-plugin"}]
},
"include": [
"**/*.*"
]
}