mirror of
https://github.com/aelve/guide.git
synced 2024-12-22 20:31:31 +03:00
Front/fix/category sections enabling (#335)
* Formatting * Category sections enabling fixes #317; Warning when disabling editing secitons; * Removed unused import
This commit is contained in:
parent
59deb57474
commit
f0f9c458a5
@ -30,6 +30,7 @@
|
||||
:toc="value.toc"
|
||||
:notes="value.notes"
|
||||
:kind="value.kind"
|
||||
:sections="category.sections"
|
||||
/>
|
||||
</template>
|
||||
<v-btn
|
||||
|
@ -37,20 +37,23 @@
|
||||
class="mb-2"
|
||||
/>
|
||||
<v-checkbox
|
||||
v-model="checkboxSections"
|
||||
label="Pros/cons enabled"
|
||||
:inputValue="checkboxSections"
|
||||
@click.native.capture.prevent.stop="updateSectionEnabling('ItemProsConsSection', 'Pros/Cons')"
|
||||
label="Pros/cons section"
|
||||
value="ItemProsConsSection"
|
||||
class="mt-0 hide-v-messages"
|
||||
/>
|
||||
<v-checkbox
|
||||
v-model="checkboxSections"
|
||||
label="Ecosystem field enabled"
|
||||
:inputValue="checkboxSections"
|
||||
@click.native.capture.prevent.stop="updateSectionEnabling('ItemEcosystemSection', 'Ecosystem')"
|
||||
label="Ecosystem section"
|
||||
value="ItemEcosystemSection"
|
||||
class="mt-0 hide-v-messages"
|
||||
/>
|
||||
<v-checkbox
|
||||
v-model="checkboxSections"
|
||||
label="Notes field enabled"
|
||||
:inputValue="checkboxSections"
|
||||
@click.native.capture.prevent.stop="updateSectionEnabling('ItemNotesSection', 'Notes')"
|
||||
label="Notes section"
|
||||
value="ItemNotesSection"
|
||||
class="mt-0 hide-v-messages"
|
||||
/>
|
||||
@ -83,7 +86,6 @@
|
||||
import Vue from 'vue'
|
||||
import Component from 'vue-class-component'
|
||||
import { Prop, Watch } from 'vue-property-decorator'
|
||||
import { CategoryStatus } from 'client/service/Category'
|
||||
|
||||
@Component
|
||||
export default class CategoryInfoEdit extends Vue {
|
||||
@ -95,6 +97,13 @@ export default class CategoryInfoEdit extends Vue {
|
||||
checkboxSections: any[] = []
|
||||
isValid: boolean = false
|
||||
|
||||
// TODO replace ItemProsConsSection and other to constants
|
||||
sectionDisableWarningAgreed = {
|
||||
ItemProsConsSection: false,
|
||||
ItemEcosystemSection: false,
|
||||
ItemNotesSection: false
|
||||
}
|
||||
|
||||
categoryStatuses = [
|
||||
{ name: 'Complete', value: 'CategoryFinished' },
|
||||
{ name: 'Work in progress', value: 'CategoryWIP' },
|
||||
@ -118,19 +127,35 @@ export default class CategoryInfoEdit extends Vue {
|
||||
}
|
||||
this.title = category.title
|
||||
this.group = category.group
|
||||
this.checkboxSections = category.sections
|
||||
this.checkboxSections = category.sections.slice()
|
||||
this.categoryStatus = category.status
|
||||
this.sectionDisableWarningAgreed = {
|
||||
ItemProsConsSection: false,
|
||||
ItemEcosystemSection: false,
|
||||
ItemNotesSection: false
|
||||
}
|
||||
}
|
||||
|
||||
transformCategoryStatus (status: string) {
|
||||
switch (status) {
|
||||
case CategoryStatus.finished:
|
||||
return 'Complete'
|
||||
case CategoryStatus.inProgress:
|
||||
return 'Work in progress'
|
||||
default:
|
||||
return 'Stub'
|
||||
async updateSectionEnabling (sectionValue, sectionName) {
|
||||
const index = this.checkboxSections.indexOf(sectionValue)
|
||||
const isSectionRemoved = index !== -1
|
||||
if (!isSectionRemoved) {
|
||||
this.checkboxSections.push(sectionValue)
|
||||
return
|
||||
}
|
||||
|
||||
const isOriginallyEnabled = this.category.sections.includes(sectionValue)
|
||||
const isSectionInEdit = this.$store.state.category.itemsSectionsInEdit[sectionValue].length
|
||||
const wasAgreedOnce = this.sectionDisableWarningAgreed[sectionValue]
|
||||
if (isOriginallyEnabled && isSectionInEdit && !wasAgreedOnce) {
|
||||
const isConfirmed = await this._confirm({ fullText: `You have unsaved changes in one of items’ ${sectionName} section. If you disable this section, your changes will be lost.` })
|
||||
if (!isConfirmed) {
|
||||
return
|
||||
}
|
||||
this.sectionDisableWarningAgreed[sectionValue] = true
|
||||
}
|
||||
|
||||
this.checkboxSections.splice(index, 1)
|
||||
}
|
||||
|
||||
close () {
|
||||
|
@ -27,31 +27,40 @@
|
||||
/>
|
||||
</category-item-section>
|
||||
|
||||
<div class="category-item-traits">
|
||||
<div
|
||||
v-if="isSectionEnabled('ItemProsConsSection')"
|
||||
class="category-item-traits"
|
||||
>
|
||||
<category-item-traits
|
||||
type="Pro"
|
||||
:itemId="itemUid"
|
||||
:traits="pros"
|
||||
:isAnyTraitEditing.sync="isPropsEditing"
|
||||
/>
|
||||
<category-item-traits
|
||||
type="Con"
|
||||
:itemId="itemUid"
|
||||
:traits="cons"
|
||||
:isAnyTraitEditing.sync="isConsEditing"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<category-item-section
|
||||
v-if="isSectionEnabled('ItemEcosystemSection')"
|
||||
title="Ecosystem"
|
||||
:editText="ecosystem.text"
|
||||
@save="updateEcosystem({original: ecosystem.text, modified: $event})"
|
||||
@toggleEdit="toggleItemEcosystemEditState"
|
||||
>
|
||||
<div v-html="ecosystem.html" />
|
||||
</category-item-section>
|
||||
|
||||
<category-item-section
|
||||
v-if="isSectionEnabled('ItemNotesSection')"
|
||||
title="Notes"
|
||||
:editText="notes.text"
|
||||
@save="updateNotes({original: notes.text, modified: $event})"
|
||||
@toggleEdit="toggleItemNotesEditState"
|
||||
>
|
||||
<v-btn
|
||||
small
|
||||
@ -102,7 +111,7 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import Component from 'vue-class-component'
|
||||
import { Prop } from 'vue-property-decorator'
|
||||
import { Prop, Watch } from 'vue-property-decorator'
|
||||
import { ICategoryItem } from 'client/service/CategoryItem.ts'
|
||||
import CategoryItemToolbar from 'client/components/CategoryItemToolbar.vue'
|
||||
import CategoryItemSection from 'client/components/CategoryItemSection.vue'
|
||||
@ -132,8 +141,26 @@ export default class CategoryItem extends Vue {
|
||||
@Prop(String) itemUid!: string
|
||||
@Prop(String) link!: string
|
||||
@Prop(String) hackage!: string
|
||||
@Prop(Array) sections!: string[]
|
||||
|
||||
isNoteExpanded: boolean = false
|
||||
isPropsEditing: boolean = false
|
||||
isConsEditing: boolean = false
|
||||
|
||||
get isAnyTraitEditing () {
|
||||
return this.isPropsEditing || this.isConsEditing
|
||||
}
|
||||
|
||||
@Watch('isAnyTraitEditing', { immediate: true })
|
||||
updateItemTraitEditingState (newVal, prevVal) {
|
||||
if (newVal !== prevVal) {
|
||||
this.$store.dispatch('category/toggleItemProsConsSectionEdit', this.itemUid)
|
||||
}
|
||||
}
|
||||
|
||||
isSectionEnabled (section) {
|
||||
return this.sections.includes(section)
|
||||
}
|
||||
|
||||
expandNotes (): void {
|
||||
this.isNoteExpanded = true
|
||||
@ -143,6 +170,14 @@ export default class CategoryItem extends Vue {
|
||||
this.isNoteExpanded = false
|
||||
}
|
||||
|
||||
toggleItemEcosystemEditState () {
|
||||
this.$store.dispatch('category/toggleItemEcosystemSectionEdit', this.itemUid)
|
||||
}
|
||||
|
||||
toggleItemNotesEditState () {
|
||||
this.$store.dispatch('category/toggleItemNotesSectionEdit', this.itemUid)
|
||||
}
|
||||
|
||||
@CatchConflictDecorator
|
||||
async updateSummary ({ original, modified }): Promise<void> {
|
||||
await this.$store.dispatch('categoryItem/updateItemSummary', {
|
||||
|
@ -64,8 +64,8 @@ export default class CategoryItemSection extends Vue {
|
||||
isEdit: boolean = false
|
||||
|
||||
toggleEdit (): void {
|
||||
this.$emit('toggleEdit')
|
||||
if (this.customEdit) {
|
||||
this.$emit('toggleEdit')
|
||||
return
|
||||
}
|
||||
this.isEdit = !this.isEdit
|
||||
|
@ -118,27 +118,29 @@ export default class CategoryItemTraits extends Vue {
|
||||
@Prop(Array) traits!: any[]
|
||||
@Prop(String) type!: string
|
||||
@Prop(String) itemId: string
|
||||
@Prop(Boolean) isAnyTraitEditing: boolean
|
||||
|
||||
isEdit: boolean = false
|
||||
isAddTrait: boolean = false
|
||||
traitsModel = []
|
||||
|
||||
get title () {
|
||||
return this.type + 's'
|
||||
}
|
||||
get isAnyTraitEditingOrAdding () {
|
||||
return this.traitsModel.some(x => x.isEdit) || this.isAddTrait
|
||||
}
|
||||
|
||||
@Watch('traits', {
|
||||
immediate: true
|
||||
})
|
||||
@Watch('isAnyTraitEditingOrAdding', { immediate: true })
|
||||
updateIsEditing (newVal) {
|
||||
this.$emit('update:isAnyTraitEditing', newVal)
|
||||
}
|
||||
|
||||
@Watch('traits', { immediate: true })
|
||||
setTraitsModel (traits) {
|
||||
this.traitsModel = _cloneDeep(traits)
|
||||
this.traitsModel.forEach(x => this.$set(x, 'isEdit', false))
|
||||
}
|
||||
|
||||
toggleEdit () {
|
||||
this.isEdit = !this.isEdit
|
||||
}
|
||||
|
||||
@CatchConflictDecorator
|
||||
async saveEdit ({ trait, original, modified }) {
|
||||
await this.$store.dispatch('categoryItem/updateItemTrait', {
|
||||
|
@ -1,14 +1,25 @@
|
||||
import { ActionTree, GetterTree, MutationTree, ActionContext, Module } from 'vuex'
|
||||
import { ICategoryInfo, ICategoryFull, CategoryService } from 'client/service/Category'
|
||||
import { ICategoryItem } from 'client/service/CategoryItem'
|
||||
|
||||
interface ICategoryState {
|
||||
categoryList: ICategoryInfo[],
|
||||
category: ICategoryFull
|
||||
category: ICategoryFull,
|
||||
itemsSectionsInEdit: {
|
||||
ItemProsConsSection: Array<ICategoryItem['id']>
|
||||
ItemEcosystemSection: Array<ICategoryItem['id']>
|
||||
ItemNotesSection: Array<ICategoryItem['id']>
|
||||
}
|
||||
}
|
||||
|
||||
const state = (): ICategoryState => ({
|
||||
categoryList: [],
|
||||
category: null
|
||||
category: null,
|
||||
itemsSectionsInEdit: {
|
||||
ItemProsConsSection: [],
|
||||
ItemEcosystemSection: [],
|
||||
ItemNotesSection: []
|
||||
}
|
||||
})
|
||||
|
||||
const getters: GetterTree<ICategoryState, any> = {}
|
||||
@ -44,15 +55,33 @@ const actions: ActionTree<ICategoryState, any> = {
|
||||
dispatch('loadCategoryList')
|
||||
return createdId
|
||||
},
|
||||
async updateCategoryInfo (context: ActionContext<ICategoryState, any>, {id, title, group, status, sections}) {
|
||||
await CategoryService.updateCategoryInfo({id, title, group, status, sections})
|
||||
async updateCategoryInfo (context: ActionContext<ICategoryState, any>, { id, title, group, status, sections }) {
|
||||
await CategoryService.updateCategoryInfo({ id, title, group, status, sections })
|
||||
},
|
||||
async deleteCategory (
|
||||
{ dispatch }: ActionContext<ICategoryState, any>,
|
||||
id: ICategoryInfo['id']
|
||||
): Promise<void> {
|
||||
await CategoryService.deleteCategory(id)
|
||||
}
|
||||
},
|
||||
toggleItemProsConsSectionEdit (
|
||||
{ commit }: ActionContext<ICategoryState, any>,
|
||||
itemId: ICategoryItem['id']
|
||||
) {
|
||||
commit('toggleSectionEditState', { sectionName: 'ItemProsConsSection', itemId })
|
||||
},
|
||||
toggleItemEcosystemSectionEdit (
|
||||
{ commit }: ActionContext<ICategoryState, any>,
|
||||
itemId: ICategoryItem['id']
|
||||
) {
|
||||
commit('toggleSectionEditState', { sectionName: 'ItemEcosystemSection', itemId })
|
||||
},
|
||||
toggleItemNotesSectionEdit (
|
||||
{ commit }: ActionContext<ICategoryState, any>,
|
||||
itemId: ICategoryItem['id']
|
||||
) {
|
||||
commit('toggleSectionEditState', { sectionName: 'ItemNotesSection', itemId })
|
||||
},
|
||||
}
|
||||
|
||||
const mutations: MutationTree<ICategoryState> = {
|
||||
@ -61,6 +90,16 @@ const mutations: MutationTree<ICategoryState> = {
|
||||
},
|
||||
setCategory: (state: ICategoryState, payload: ICategoryFull) => {
|
||||
state.category = payload
|
||||
},
|
||||
toggleSectionEditState (state, { sectionName, itemId }) {
|
||||
const sectionEditState = state.itemsSectionsInEdit[sectionName]
|
||||
|
||||
if (sectionEditState.includes(itemId)) {
|
||||
const index = sectionEditState.indexOf(itemId)
|
||||
sectionEditState.splice(index, 1)
|
||||
} else {
|
||||
sectionEditState.push(itemId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user