mirror of
https://github.com/aelve/guide.git
synced 2024-12-23 04:42:24 +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"
|
:toc="value.toc"
|
||||||
:notes="value.notes"
|
:notes="value.notes"
|
||||||
:kind="value.kind"
|
:kind="value.kind"
|
||||||
|
:sections="category.sections"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<v-btn
|
<v-btn
|
||||||
|
@ -37,20 +37,23 @@
|
|||||||
class="mb-2"
|
class="mb-2"
|
||||||
/>
|
/>
|
||||||
<v-checkbox
|
<v-checkbox
|
||||||
v-model="checkboxSections"
|
:inputValue="checkboxSections"
|
||||||
label="Pros/cons enabled"
|
@click.native.capture.prevent.stop="updateSectionEnabling('ItemProsConsSection', 'Pros/Cons')"
|
||||||
|
label="Pros/cons section"
|
||||||
value="ItemProsConsSection"
|
value="ItemProsConsSection"
|
||||||
class="mt-0 hide-v-messages"
|
class="mt-0 hide-v-messages"
|
||||||
/>
|
/>
|
||||||
<v-checkbox
|
<v-checkbox
|
||||||
v-model="checkboxSections"
|
:inputValue="checkboxSections"
|
||||||
label="Ecosystem field enabled"
|
@click.native.capture.prevent.stop="updateSectionEnabling('ItemEcosystemSection', 'Ecosystem')"
|
||||||
|
label="Ecosystem section"
|
||||||
value="ItemEcosystemSection"
|
value="ItemEcosystemSection"
|
||||||
class="mt-0 hide-v-messages"
|
class="mt-0 hide-v-messages"
|
||||||
/>
|
/>
|
||||||
<v-checkbox
|
<v-checkbox
|
||||||
v-model="checkboxSections"
|
:inputValue="checkboxSections"
|
||||||
label="Notes field enabled"
|
@click.native.capture.prevent.stop="updateSectionEnabling('ItemNotesSection', 'Notes')"
|
||||||
|
label="Notes section"
|
||||||
value="ItemNotesSection"
|
value="ItemNotesSection"
|
||||||
class="mt-0 hide-v-messages"
|
class="mt-0 hide-v-messages"
|
||||||
/>
|
/>
|
||||||
@ -83,7 +86,6 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Component from 'vue-class-component'
|
import Component from 'vue-class-component'
|
||||||
import { Prop, Watch } from 'vue-property-decorator'
|
import { Prop, Watch } from 'vue-property-decorator'
|
||||||
import { CategoryStatus } from 'client/service/Category'
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class CategoryInfoEdit extends Vue {
|
export default class CategoryInfoEdit extends Vue {
|
||||||
@ -95,6 +97,13 @@ export default class CategoryInfoEdit extends Vue {
|
|||||||
checkboxSections: any[] = []
|
checkboxSections: any[] = []
|
||||||
isValid: boolean = false
|
isValid: boolean = false
|
||||||
|
|
||||||
|
// TODO replace ItemProsConsSection and other to constants
|
||||||
|
sectionDisableWarningAgreed = {
|
||||||
|
ItemProsConsSection: false,
|
||||||
|
ItemEcosystemSection: false,
|
||||||
|
ItemNotesSection: false
|
||||||
|
}
|
||||||
|
|
||||||
categoryStatuses = [
|
categoryStatuses = [
|
||||||
{ name: 'Complete', value: 'CategoryFinished' },
|
{ name: 'Complete', value: 'CategoryFinished' },
|
||||||
{ name: 'Work in progress', value: 'CategoryWIP' },
|
{ name: 'Work in progress', value: 'CategoryWIP' },
|
||||||
@ -118,19 +127,35 @@ export default class CategoryInfoEdit extends Vue {
|
|||||||
}
|
}
|
||||||
this.title = category.title
|
this.title = category.title
|
||||||
this.group = category.group
|
this.group = category.group
|
||||||
this.checkboxSections = category.sections
|
this.checkboxSections = category.sections.slice()
|
||||||
this.categoryStatus = category.status
|
this.categoryStatus = category.status
|
||||||
|
this.sectionDisableWarningAgreed = {
|
||||||
|
ItemProsConsSection: false,
|
||||||
|
ItemEcosystemSection: false,
|
||||||
|
ItemNotesSection: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transformCategoryStatus (status: string) {
|
async updateSectionEnabling (sectionValue, sectionName) {
|
||||||
switch (status) {
|
const index = this.checkboxSections.indexOf(sectionValue)
|
||||||
case CategoryStatus.finished:
|
const isSectionRemoved = index !== -1
|
||||||
return 'Complete'
|
if (!isSectionRemoved) {
|
||||||
case CategoryStatus.inProgress:
|
this.checkboxSections.push(sectionValue)
|
||||||
return 'Work in progress'
|
return
|
||||||
default:
|
|
||||||
return 'Stub'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 () {
|
close () {
|
||||||
|
@ -27,31 +27,40 @@
|
|||||||
/>
|
/>
|
||||||
</category-item-section>
|
</category-item-section>
|
||||||
|
|
||||||
<div class="category-item-traits">
|
<div
|
||||||
|
v-if="isSectionEnabled('ItemProsConsSection')"
|
||||||
|
class="category-item-traits"
|
||||||
|
>
|
||||||
<category-item-traits
|
<category-item-traits
|
||||||
type="Pro"
|
type="Pro"
|
||||||
:itemId="itemUid"
|
:itemId="itemUid"
|
||||||
:traits="pros"
|
:traits="pros"
|
||||||
|
:isAnyTraitEditing.sync="isPropsEditing"
|
||||||
/>
|
/>
|
||||||
<category-item-traits
|
<category-item-traits
|
||||||
type="Con"
|
type="Con"
|
||||||
:itemId="itemUid"
|
:itemId="itemUid"
|
||||||
:traits="cons"
|
:traits="cons"
|
||||||
|
:isAnyTraitEditing.sync="isConsEditing"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<category-item-section
|
<category-item-section
|
||||||
|
v-if="isSectionEnabled('ItemEcosystemSection')"
|
||||||
title="Ecosystem"
|
title="Ecosystem"
|
||||||
:editText="ecosystem.text"
|
:editText="ecosystem.text"
|
||||||
@save="updateEcosystem({original: ecosystem.text, modified: $event})"
|
@save="updateEcosystem({original: ecosystem.text, modified: $event})"
|
||||||
|
@toggleEdit="toggleItemEcosystemEditState"
|
||||||
>
|
>
|
||||||
<div v-html="ecosystem.html" />
|
<div v-html="ecosystem.html" />
|
||||||
</category-item-section>
|
</category-item-section>
|
||||||
|
|
||||||
<category-item-section
|
<category-item-section
|
||||||
|
v-if="isSectionEnabled('ItemNotesSection')"
|
||||||
title="Notes"
|
title="Notes"
|
||||||
:editText="notes.text"
|
:editText="notes.text"
|
||||||
@save="updateNotes({original: notes.text, modified: $event})"
|
@save="updateNotes({original: notes.text, modified: $event})"
|
||||||
|
@toggleEdit="toggleItemNotesEditState"
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
small
|
small
|
||||||
@ -102,7 +111,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Component from 'vue-class-component'
|
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 { ICategoryItem } from 'client/service/CategoryItem.ts'
|
||||||
import CategoryItemToolbar from 'client/components/CategoryItemToolbar.vue'
|
import CategoryItemToolbar from 'client/components/CategoryItemToolbar.vue'
|
||||||
import CategoryItemSection from 'client/components/CategoryItemSection.vue'
|
import CategoryItemSection from 'client/components/CategoryItemSection.vue'
|
||||||
@ -132,8 +141,26 @@ export default class CategoryItem extends Vue {
|
|||||||
@Prop(String) itemUid!: string
|
@Prop(String) itemUid!: string
|
||||||
@Prop(String) link!: string
|
@Prop(String) link!: string
|
||||||
@Prop(String) hackage!: string
|
@Prop(String) hackage!: string
|
||||||
|
@Prop(Array) sections!: string[]
|
||||||
|
|
||||||
isNoteExpanded: boolean = false
|
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 {
|
expandNotes (): void {
|
||||||
this.isNoteExpanded = true
|
this.isNoteExpanded = true
|
||||||
@ -143,6 +170,14 @@ export default class CategoryItem extends Vue {
|
|||||||
this.isNoteExpanded = false
|
this.isNoteExpanded = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleItemEcosystemEditState () {
|
||||||
|
this.$store.dispatch('category/toggleItemEcosystemSectionEdit', this.itemUid)
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleItemNotesEditState () {
|
||||||
|
this.$store.dispatch('category/toggleItemNotesSectionEdit', this.itemUid)
|
||||||
|
}
|
||||||
|
|
||||||
@CatchConflictDecorator
|
@CatchConflictDecorator
|
||||||
async updateSummary ({ original, modified }): Promise<void> {
|
async updateSummary ({ original, modified }): Promise<void> {
|
||||||
await this.$store.dispatch('categoryItem/updateItemSummary', {
|
await this.$store.dispatch('categoryItem/updateItemSummary', {
|
||||||
|
@ -64,8 +64,8 @@ export default class CategoryItemSection extends Vue {
|
|||||||
isEdit: boolean = false
|
isEdit: boolean = false
|
||||||
|
|
||||||
toggleEdit (): void {
|
toggleEdit (): void {
|
||||||
|
this.$emit('toggleEdit')
|
||||||
if (this.customEdit) {
|
if (this.customEdit) {
|
||||||
this.$emit('toggleEdit')
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.isEdit = !this.isEdit
|
this.isEdit = !this.isEdit
|
||||||
|
@ -118,27 +118,29 @@ export default class CategoryItemTraits extends Vue {
|
|||||||
@Prop(Array) traits!: any[]
|
@Prop(Array) traits!: any[]
|
||||||
@Prop(String) type!: string
|
@Prop(String) type!: string
|
||||||
@Prop(String) itemId: string
|
@Prop(String) itemId: string
|
||||||
|
@Prop(Boolean) isAnyTraitEditing: boolean
|
||||||
|
|
||||||
isEdit: boolean = false
|
|
||||||
isAddTrait: boolean = false
|
isAddTrait: boolean = false
|
||||||
traitsModel = []
|
traitsModel = []
|
||||||
|
|
||||||
get title () {
|
get title () {
|
||||||
return this.type + 's'
|
return this.type + 's'
|
||||||
}
|
}
|
||||||
|
get isAnyTraitEditingOrAdding () {
|
||||||
|
return this.traitsModel.some(x => x.isEdit) || this.isAddTrait
|
||||||
|
}
|
||||||
|
|
||||||
@Watch('traits', {
|
@Watch('isAnyTraitEditingOrAdding', { immediate: true })
|
||||||
immediate: true
|
updateIsEditing (newVal) {
|
||||||
})
|
this.$emit('update:isAnyTraitEditing', newVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Watch('traits', { immediate: true })
|
||||||
setTraitsModel (traits) {
|
setTraitsModel (traits) {
|
||||||
this.traitsModel = _cloneDeep(traits)
|
this.traitsModel = _cloneDeep(traits)
|
||||||
this.traitsModel.forEach(x => this.$set(x, 'isEdit', false))
|
this.traitsModel.forEach(x => this.$set(x, 'isEdit', false))
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleEdit () {
|
|
||||||
this.isEdit = !this.isEdit
|
|
||||||
}
|
|
||||||
|
|
||||||
@CatchConflictDecorator
|
@CatchConflictDecorator
|
||||||
async saveEdit ({ trait, original, modified }) {
|
async saveEdit ({ trait, original, modified }) {
|
||||||
await this.$store.dispatch('categoryItem/updateItemTrait', {
|
await this.$store.dispatch('categoryItem/updateItemTrait', {
|
||||||
|
@ -1,14 +1,25 @@
|
|||||||
import { ActionTree, GetterTree, MutationTree, ActionContext, Module } from 'vuex'
|
import { ActionTree, GetterTree, MutationTree, ActionContext, Module } from 'vuex'
|
||||||
import { ICategoryInfo, ICategoryFull, CategoryService } from 'client/service/Category'
|
import { ICategoryInfo, ICategoryFull, CategoryService } from 'client/service/Category'
|
||||||
|
import { ICategoryItem } from 'client/service/CategoryItem'
|
||||||
|
|
||||||
interface ICategoryState {
|
interface ICategoryState {
|
||||||
categoryList: ICategoryInfo[],
|
categoryList: ICategoryInfo[],
|
||||||
category: ICategoryFull
|
category: ICategoryFull,
|
||||||
|
itemsSectionsInEdit: {
|
||||||
|
ItemProsConsSection: Array<ICategoryItem['id']>
|
||||||
|
ItemEcosystemSection: Array<ICategoryItem['id']>
|
||||||
|
ItemNotesSection: Array<ICategoryItem['id']>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = (): ICategoryState => ({
|
const state = (): ICategoryState => ({
|
||||||
categoryList: [],
|
categoryList: [],
|
||||||
category: null
|
category: null,
|
||||||
|
itemsSectionsInEdit: {
|
||||||
|
ItemProsConsSection: [],
|
||||||
|
ItemEcosystemSection: [],
|
||||||
|
ItemNotesSection: []
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const getters: GetterTree<ICategoryState, any> = {}
|
const getters: GetterTree<ICategoryState, any> = {}
|
||||||
@ -44,15 +55,33 @@ const actions: ActionTree<ICategoryState, any> = {
|
|||||||
dispatch('loadCategoryList')
|
dispatch('loadCategoryList')
|
||||||
return createdId
|
return createdId
|
||||||
},
|
},
|
||||||
async updateCategoryInfo (context: ActionContext<ICategoryState, any>, {id, title, group, status, sections}) {
|
async updateCategoryInfo (context: ActionContext<ICategoryState, any>, { id, title, group, status, sections }) {
|
||||||
await CategoryService.updateCategoryInfo({id, title, group, status, sections})
|
await CategoryService.updateCategoryInfo({ id, title, group, status, sections })
|
||||||
},
|
},
|
||||||
async deleteCategory (
|
async deleteCategory (
|
||||||
{ dispatch }: ActionContext<ICategoryState, any>,
|
{ dispatch }: ActionContext<ICategoryState, any>,
|
||||||
id: ICategoryInfo['id']
|
id: ICategoryInfo['id']
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await CategoryService.deleteCategory(id)
|
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> = {
|
const mutations: MutationTree<ICategoryState> = {
|
||||||
@ -61,6 +90,16 @@ const mutations: MutationTree<ICategoryState> = {
|
|||||||
},
|
},
|
||||||
setCategory: (state: ICategoryState, payload: ICategoryFull) => {
|
setCategory: (state: ICategoryState, payload: ICategoryFull) => {
|
||||||
state.category = payload
|
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