Refactor ContentComponent
This commit is contained in:
parent
f3dc0e9b09
commit
a6974853ef
|
|
@ -2,16 +2,16 @@ import { CodegenConfig } from '@graphql-codegen/cli';
|
|||
|
||||
const config: CodegenConfig = {
|
||||
schema: ['../server/schema.graphql', './local.graphql'],
|
||||
documents: ['src/**/*.vue'],
|
||||
documents: ['src/**/*.vue', 'src/**/*.ts'],
|
||||
generates: {
|
||||
'src/__generated__/': {
|
||||
preset: 'client',
|
||||
plugins: [],
|
||||
presetConfig: {
|
||||
useTypeImports: true
|
||||
useTypeImports: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
ignoreNoDocuments: true
|
||||
ignoreNoDocuments: true,
|
||||
};
|
||||
export default config;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ const documents = {
|
|||
"\n fragment SnapshotTitleFragment on SnapshotNode {\n title\n }\n": types.SnapshotTitleFragmentFragmentDoc,
|
||||
"\n fragment SnapshotDetailsFragment on SnapshotNode {\n id\n title\n shared\n created\n creator\n mine\n }\n": types.SnapshotDetailsFragmentFragmentDoc,
|
||||
"\n query ModuleEditModeQuery($slug: String) {\n module(slug: $slug) {\n inEditMode @client\n slug\n }\n }\n": types.ModuleEditModeQueryDocument,
|
||||
"\n mutation UpdateInstrumentBookmark($input: UpdateInstrumentBookmarkInput!) {\n updateInstrumentBookmark(input: $input) {\n success\n }\n }\n ": types.UpdateInstrumentBookmarkDocument,
|
||||
"\n mutation UpdateContentBookmark($input: UpdateContentBookmarkInput!) {\n updateContentBookmark(input: $input) {\n success\n }\n }\n ": types.UpdateContentBookmarkDocument,
|
||||
"\n query ChapterQuery($id: ID!) {\n chapter(id: $id) {\n path\n }\n }\n ": types.ChapterQueryDocument,
|
||||
"\n query ContentBlockQuery($id: ID!) {\n contentBlock(id: $id) {\n path\n }\n }\n ": types.ContentBlockQueryDocument,
|
||||
"\n query MeLanguage {\n me {\n language @client\n }\n }\n ": types.MeLanguageDocument,
|
||||
|
|
@ -89,6 +91,14 @@ export function graphql(source: "\n fragment SnapshotDetailsFragment on Snapsho
|
|||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query ModuleEditModeQuery($slug: String) {\n module(slug: $slug) {\n inEditMode @client\n slug\n }\n }\n"): (typeof documents)["\n query ModuleEditModeQuery($slug: String) {\n module(slug: $slug) {\n inEditMode @client\n slug\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n mutation UpdateInstrumentBookmark($input: UpdateInstrumentBookmarkInput!) {\n updateInstrumentBookmark(input: $input) {\n success\n }\n }\n "): (typeof documents)["\n mutation UpdateInstrumentBookmark($input: UpdateInstrumentBookmarkInput!) {\n updateInstrumentBookmark(input: $input) {\n success\n }\n }\n "];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n mutation UpdateContentBookmark($input: UpdateContentBookmarkInput!) {\n updateContentBookmark(input: $input) {\n success\n }\n }\n "): (typeof documents)["\n mutation UpdateContentBookmark($input: UpdateContentBookmarkInput!) {\n updateContentBookmark(input: $input) {\n success\n }\n }\n "];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -12,143 +12,223 @@
|
|||
v-if="showBookmarkActions"
|
||||
@add-note="addNote(component.id)"
|
||||
@edit-note="editNote"
|
||||
@bookmark="bookmarkContent(component.id, !bookmarked)"
|
||||
/>
|
||||
<component
|
||||
v-bind="component"
|
||||
:parent="parent"
|
||||
:is="component.type"
|
||||
@bookmark="bookmarkContent(!bookmarked)"
|
||||
/>
|
||||
<component v-bind="component" :parent="parent" :is="componentType" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { constructContentComponentBookmarkMutation } from '@/helpers/update-content-bookmark-mutation';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
<script setup lang="ts">
|
||||
import { defineAsyncComponent, ref, computed, onMounted } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import { constructContentComponentBookmarkMutation } from "@/helpers/update-content-bookmark-mutation";
|
||||
import { useMutation } from "@vue/apollo-composable";
|
||||
|
||||
const TextBlock = defineAsyncComponent(() => import('@/components/content-blocks/TextBlock.vue'));
|
||||
const InstrumentWidget = defineAsyncComponent(() => import('@/components/content-blocks/InstrumentWidget.vue'));
|
||||
const ImageBlock = defineAsyncComponent(() => import('@/components/content-blocks/ImageBlock.vue'));
|
||||
const ImageUrlBlock = defineAsyncComponent(() => import('@/components/content-blocks/ImageUrlBlock.vue'));
|
||||
const VideoBlock = defineAsyncComponent(() => import('@/components/content-blocks/VideoBlock.vue'));
|
||||
const LinkBlock = defineAsyncComponent(() => import('@/components/content-blocks/LinkBlock.vue'));
|
||||
const DocumentBlock = defineAsyncComponent(() => import('@/components/content-blocks/DocumentBlock.vue'));
|
||||
const CmsDocumentBlock = defineAsyncComponent(() => import('@/components/content-blocks/CmsDocumentBlock.vue'));
|
||||
const InfogramBlock = defineAsyncComponent(() => import('@/components/content-blocks/InfogramBlock.vue'));
|
||||
const ThinglinkBlock = defineAsyncComponent(() => import('@/components/content-blocks/ThinglinkBlock.vue'));
|
||||
const GeniallyBlock = defineAsyncComponent(() => import('@/components/content-blocks/GeniallyBlock.vue'));
|
||||
const SubtitleBlock = defineAsyncComponent(() => import('@/components/content-blocks/SubtitleBlock.vue'));
|
||||
const SectionTitleBlock = defineAsyncComponent(() => import('@/components/content-blocks/SectionTitleBlock.vue'));
|
||||
const ContentListBlock = defineAsyncComponent(() => import('@/components/content-blocks/ContentListBlock.vue'));
|
||||
const ModuleRoomSlug = defineAsyncComponent(() => import('@/components/content-blocks/ModuleRoomSlug.vue'));
|
||||
const Assignment = defineAsyncComponent(() => import('@/components/content-blocks/assignment/Assignment.vue'));
|
||||
const Survey = defineAsyncComponent(() => import('@/components/content-blocks/SurveyBlock.vue'));
|
||||
const Solution = defineAsyncComponent(() => import('@/components/content-blocks/Solution.vue'));
|
||||
const Instruction = defineAsyncComponent(() => import('@/components/content-blocks/Instruction.vue'));
|
||||
const BookmarkActions = defineAsyncComponent(() => import('@/components/notes/BookmarkActions.vue'));
|
||||
export interface Props {
|
||||
component: any;
|
||||
parent: any;
|
||||
bookmarks: any[];
|
||||
notes: any[];
|
||||
root: string;
|
||||
editMode: boolean;
|
||||
}
|
||||
const TextBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/TextBlock.vue")
|
||||
);
|
||||
const InstrumentWidget = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/InstrumentWidget.vue")
|
||||
);
|
||||
const ImageBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/ImageBlock.vue")
|
||||
);
|
||||
const ImageUrlBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/ImageUrlBlock.vue")
|
||||
);
|
||||
const VideoBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/VideoBlock.vue")
|
||||
);
|
||||
const LinkBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/LinkBlock.vue")
|
||||
);
|
||||
const DocumentBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/DocumentBlock.vue")
|
||||
);
|
||||
const CmsDocumentBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/CmsDocumentBlock.vue")
|
||||
);
|
||||
const InfogramBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/InfogramBlock.vue")
|
||||
);
|
||||
const ThinglinkBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/ThinglinkBlock.vue")
|
||||
);
|
||||
const GeniallyBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/GeniallyBlock.vue")
|
||||
);
|
||||
const SubtitleBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/SubtitleBlock.vue")
|
||||
);
|
||||
const SectionTitleBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/SectionTitleBlock.vue")
|
||||
);
|
||||
const ContentListBlock = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/ContentListBlock.vue")
|
||||
);
|
||||
const ModuleRoomSlug = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/ModuleRoomSlug.vue")
|
||||
);
|
||||
const Assignment = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/assignment/Assignment.vue")
|
||||
);
|
||||
const Survey = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/SurveyBlock.vue")
|
||||
);
|
||||
const Solution = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/Solution.vue")
|
||||
);
|
||||
const Instruction = defineAsyncComponent(
|
||||
() => import("@/components/content-blocks/Instruction.vue")
|
||||
);
|
||||
const BookmarkActions = defineAsyncComponent(
|
||||
() => import("@/components/notes/BookmarkActions.vue")
|
||||
);
|
||||
|
||||
export default {
|
||||
props: {
|
||||
component: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
parent: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
bookmarks: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
notes: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
root: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
editMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
type ContentComponentType =
|
||||
| typeof TextBlock
|
||||
| typeof InstrumentWidget
|
||||
| typeof InstrumentWidget
|
||||
| typeof ImageBlock
|
||||
| typeof ImageUrlBlock
|
||||
| typeof VideoBlock
|
||||
| typeof LinkBlock
|
||||
| typeof DocumentBlock
|
||||
| typeof InfogramBlock
|
||||
| typeof GeniallyBlock
|
||||
| typeof SubtitleBlock
|
||||
| typeof SectionTitleBlock
|
||||
| typeof ContentListBlock
|
||||
| typeof ModuleRoomSlug
|
||||
| typeof ThinglinkBlock
|
||||
| typeof CmsDocumentBlock
|
||||
| typeof Survey
|
||||
| typeof Solution
|
||||
| typeof Instruction
|
||||
| typeof Assignment;
|
||||
|
||||
components: {
|
||||
text_block: TextBlock,
|
||||
basic_knowledge: InstrumentWidget, // for legacy
|
||||
instrument: InstrumentWidget,
|
||||
image_block: ImageBlock,
|
||||
image_url_block: ImageUrlBlock,
|
||||
video_block: VideoBlock,
|
||||
link_block: LinkBlock,
|
||||
document_block: DocumentBlock,
|
||||
infogram_block: InfogramBlock,
|
||||
genially_block: GeniallyBlock,
|
||||
subtitle: SubtitleBlock,
|
||||
section_title: SectionTitleBlock,
|
||||
content_list: ContentListBlock,
|
||||
module_room_slug: ModuleRoomSlug,
|
||||
thinglink_block: ThinglinkBlock,
|
||||
cms_document_block: CmsDocumentBlock,
|
||||
Survey,
|
||||
Solution,
|
||||
Instruction,
|
||||
Assignment,
|
||||
BookmarkActions,
|
||||
},
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
component: () => ({}),
|
||||
parent: () => ({}),
|
||||
bookmarks: () => [],
|
||||
notes: () => [],
|
||||
root: "",
|
||||
editMode: false,
|
||||
});
|
||||
|
||||
computed: {
|
||||
bookmarked() {
|
||||
return this.bookmarks && !!this.bookmarks.find((bookmark) => bookmark.uuid === this.component.id);
|
||||
},
|
||||
note() {
|
||||
const bookmark = this.bookmarks && this.bookmarks.find((bookmark) => bookmark.uuid === this.component.id);
|
||||
return bookmark && bookmark.note;
|
||||
},
|
||||
showBookmarkActions() {
|
||||
return this.component.type !== 'content_list' && this.component.type !== 'basic_knowledge' && !this.editMode;
|
||||
},
|
||||
componentClass() {
|
||||
let classes = ['content-component', `content-component--${this.component.type}`];
|
||||
if (this.bookmarked) {
|
||||
classes.push('content-component--bookmarked');
|
||||
}
|
||||
return classes;
|
||||
},
|
||||
},
|
||||
const store = useStore();
|
||||
|
||||
methods: {
|
||||
addNote(id) {
|
||||
const type = Object.prototype.hasOwnProperty.call(this.parent, '__typename')
|
||||
? this.parent.__typename
|
||||
: 'ContentBlockNode';
|
||||
const components: Record<string, ContentComponentType> = {
|
||||
text_block: TextBlock,
|
||||
basic_knowledge: InstrumentWidget, // for legacy
|
||||
instrument: InstrumentWidget,
|
||||
image_block: ImageBlock,
|
||||
image_url_block: ImageUrlBlock,
|
||||
video_block: VideoBlock,
|
||||
link_block: LinkBlock,
|
||||
document_block: DocumentBlock,
|
||||
infogram_block: InfogramBlock,
|
||||
genially_block: GeniallyBlock,
|
||||
subtitle: SubtitleBlock,
|
||||
section_title: SectionTitleBlock,
|
||||
content_list: ContentListBlock,
|
||||
module_room_slug: ModuleRoomSlug,
|
||||
thinglink_block: ThinglinkBlock,
|
||||
cms_document_block: CmsDocumentBlock,
|
||||
survey: Survey,
|
||||
solution: Solution,
|
||||
instruction: Instruction,
|
||||
assignment: Assignment,
|
||||
};
|
||||
|
||||
this.$store.dispatch('addNote', {
|
||||
content: id,
|
||||
type,
|
||||
block: this.root,
|
||||
});
|
||||
const componentType = computed(() => {
|
||||
return components[props.component.type] || "";
|
||||
});
|
||||
|
||||
const bookmarked = computed(
|
||||
() =>
|
||||
props.bookmarks &&
|
||||
!!props.bookmarks.find((bookmark) => bookmark.uuid === props.component.id)
|
||||
);
|
||||
const note = computed(() => {
|
||||
const bookmark =
|
||||
props.bookmarks &&
|
||||
props.bookmarks.find((bookmark) => bookmark.uuid === props.component.id);
|
||||
return bookmark && bookmark.note;
|
||||
});
|
||||
const showBookmarkActions = computed(
|
||||
() =>
|
||||
props.component.type !== "content_list" &&
|
||||
props.component.type !== "basic_knowledge" &&
|
||||
!props.editMode
|
||||
);
|
||||
const componentClass = computed(() => {
|
||||
let classes = [
|
||||
"content-component",
|
||||
`content-component--${props.component.type}`,
|
||||
];
|
||||
if (bookmarked.value) {
|
||||
classes.push("content-component--bookmarked");
|
||||
}
|
||||
return classes;
|
||||
});
|
||||
|
||||
const addNote = (id: string) => {
|
||||
const type = Object.prototype.hasOwnProperty.call(props.parent, "__typename")
|
||||
? props.parent.__typename
|
||||
: "ContentBlockNode";
|
||||
|
||||
store.dispatch("addNote", {
|
||||
content: id,
|
||||
type,
|
||||
block: props.root,
|
||||
});
|
||||
};
|
||||
|
||||
const editNote = () => {
|
||||
store.dispatch("editNote", note);
|
||||
};
|
||||
|
||||
const { mutation, variables, update, optimisticResponse } =
|
||||
constructContentComponentBookmarkMutation(
|
||||
props.component.id,
|
||||
bookmarked.value,
|
||||
props.parent,
|
||||
props.root
|
||||
);
|
||||
const { mutate: mutateBookmarkContent } = useMutation(mutation, {
|
||||
update,
|
||||
optimisticResponse,
|
||||
});
|
||||
|
||||
const bookmarkContent = (bookmarked: boolean) => {
|
||||
const newVars = {
|
||||
input: {
|
||||
...variables.input,
|
||||
bookmarked,
|
||||
},
|
||||
editNote() {
|
||||
this.$store.dispatch('editNote', this.note);
|
||||
},
|
||||
bookmarkContent(uuid, bookmarked) {
|
||||
this.$apollo.mutate(constructContentComponentBookmarkMutation(uuid, bookmarked, this.parent, this.root));
|
||||
},
|
||||
},
|
||||
};
|
||||
console.log(newVars);
|
||||
mutateBookmarkContent(newVars);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import 'styles/helpers';
|
||||
@import "styles/helpers";
|
||||
|
||||
.content-component {
|
||||
position: relative;
|
||||
|
||||
&--bookmarked {
|
||||
}
|
||||
// &--bookmarked {
|
||||
// }
|
||||
|
||||
&--subtitle {
|
||||
margin-top: 2 * $medium-spacing;
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
mutation UpdateContentBookmark($input: UpdateContentBookmarkInput!) {
|
||||
updateContentBookmark(input: $input) {
|
||||
success
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
mutation UpdateInstrumentBookmark($input: UpdateInstrumentBookmarkInput!) {
|
||||
updateInstrumentBookmark(input: $input) {
|
||||
success
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,34 @@
|
|||
import UPDATE_CONTENT_BOOKMARK from '@/graphql/gql/mutations/updateContentBookmark.gql';
|
||||
import UPDATE_INSTRUMENT_BOOKMARK from '@/graphql/gql/mutations/updateInstrumentBookmark.gql';
|
||||
import CONTENT_BLOCK_QUERY from '@/graphql/gql/queries/contentBlockQuery.gql';
|
||||
import INSTRUMENT_FRAGMENT from '@/graphql/gql/fragments/instrumentParts.gql';
|
||||
import { pushToArray, removeAtIndex } from '@/graphql/immutable-operations';
|
||||
import { graphql } from '@/__generated__';
|
||||
|
||||
const compareUuid = (uuid) => (element) => element.uuid === uuid;
|
||||
const compareUuid = (uuid: string) => (element) => element.uuid === uuid;
|
||||
|
||||
export const constructContentComponentBookmarkMutation = (uuid, bookmarked, parent, root) => {
|
||||
let mutation = {};
|
||||
interface Mutation {
|
||||
mutation: any;
|
||||
variables: any;
|
||||
update: (store: any) => void;
|
||||
optimisticResponse: any;
|
||||
}
|
||||
|
||||
export const constructContentComponentBookmarkMutation: (
|
||||
uuid: string,
|
||||
bookmarked: boolean,
|
||||
parent: any,
|
||||
root: any
|
||||
) => Mutation = (uuid, bookmarked, parent, root) => {
|
||||
let mutation: Mutation;
|
||||
|
||||
if (parent.__typename === 'InstrumentNode') {
|
||||
mutation = {
|
||||
mutation: UPDATE_INSTRUMENT_BOOKMARK,
|
||||
mutation: graphql(`
|
||||
mutation UpdateInstrumentBookmark($input: UpdateInstrumentBookmarkInput!) {
|
||||
updateInstrumentBookmark(input: $input) {
|
||||
success
|
||||
}
|
||||
}
|
||||
`),
|
||||
variables: {
|
||||
input: {
|
||||
uuid,
|
||||
|
|
@ -30,7 +47,7 @@ export const constructContentComponentBookmarkMutation = (uuid, bookmarked, pare
|
|||
id,
|
||||
});
|
||||
|
||||
let bookmarks;
|
||||
let bookmarks: any[];
|
||||
|
||||
if (bookmarked) {
|
||||
const element = {
|
||||
|
|
@ -40,7 +57,7 @@ export const constructContentComponentBookmarkMutation = (uuid, bookmarked, pare
|
|||
};
|
||||
bookmarks = pushToArray(instrument.bookmarks, element);
|
||||
} else {
|
||||
let index = instrument.bookmarks.findIndex(compareUuid(uuid));
|
||||
const index = instrument.bookmarks.findIndex(compareUuid(uuid));
|
||||
if (index > -1) {
|
||||
bookmarks = removeAtIndex(instrument.bookmarks, index);
|
||||
} else {
|
||||
|
|
@ -69,7 +86,13 @@ export const constructContentComponentBookmarkMutation = (uuid, bookmarked, pare
|
|||
};
|
||||
} else {
|
||||
mutation = {
|
||||
mutation: UPDATE_CONTENT_BOOKMARK,
|
||||
mutation: graphql(`
|
||||
mutation UpdateContentBookmark($input: UpdateContentBookmarkInput!) {
|
||||
updateContentBookmark(input: $input) {
|
||||
success
|
||||
}
|
||||
}
|
||||
`),
|
||||
variables: {
|
||||
input: {
|
||||
uuid,
|
||||
|
|
@ -86,17 +109,17 @@ export const constructContentComponentBookmarkMutation = (uuid, bookmarked, pare
|
|||
});
|
||||
|
||||
// const bookmarks = data.contentBlock.bookmarks;
|
||||
let bookmarks;
|
||||
let bookmarks: any[];
|
||||
|
||||
if (bookmarked) {
|
||||
let element = {
|
||||
const element = {
|
||||
note: null,
|
||||
uuid,
|
||||
__typename: 'ContentBlockBookmarkNode',
|
||||
};
|
||||
bookmarks = pushToArray(contentBlock.bookmarks, element);
|
||||
} else {
|
||||
let index = contentBlock.bookmarks.findIndex(compareUuid(uuid));
|
||||
const index = contentBlock.bookmarks.findIndex(compareUuid(uuid));
|
||||
if (index > -1) {
|
||||
bookmarks = removeAtIndex(contentBlock.bookmarks, index);
|
||||
} else {
|
||||
Loading…
Reference in New Issue