Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Accordion] Add "collapse all"/ "expand all" logic into AccordionContainer #11565

Original file line number Diff line number Diff line change
@@ -1,16 +1,49 @@
<template>

<div>
<div class="accordion">
<KGrid
:style="{
backgroundColor: $themePalette.grey.v_100,
}"
>
<KGridItem
:layout4="{ span: 2 }"
:layout8="{ span: 4 }"
:layout12="{ span: 6 }"
class="header-actions"
>
<div class="header-left-actions">
<slot name="left-actions"></slot>
</div>
</KGridItem>
<KGridItem
:layout4="{ span: 2 }"
:layout8="{ span: 4 }"
:layout12="{ span: 6 }"
class="header-actions"
>
<div class="header-right-actions">
<KIconButton
icon="expandAll"
:tooltip="expandAll$()"
:disabled="expandedItemIds.length === items.length"
@click="expandAll"
/>
<KIconButton
icon="collapseAll"
:tooltip="collapseAll$()"
:disabled="expandedItemIds.length === 0"
@click="collapseAll"
/>
<slot name="right-actions"></slot>
</div>
</KGridItem>
</KGrid>
<transition-group
tag="div"
name="list"
class="wrapper"
>
<slot
name="top"
:expandAll="expandAll"
:collapseAll="collapseAll"
></slot>
<slot
:toggleItemState="toggleItemState"
:isItemExpanded="isItemExpanded"
Expand All @@ -24,21 +57,34 @@

<script>

import { enhancedQuizManagementStrings } from 'kolibri-common/strings/enhancedQuizManagementStrings';

export default {
name: 'AccordionContainer',
data() {
setup() {
const { expandAll$, collapseAll$ } = enhancedQuizManagementStrings;
return {
expandedItemIds: [],
expandAll$,
collapseAll$,
};
},
watch: {
expandedItemIds() {
this.$emit('toggled', this.expandedItemIds);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By handling the collapse all and expand all within the AccordionComponent, I think we can handle the functionality of the expandedItemIds within the component without having to expose the entire array, and just expose the isItemExpanded method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed 👍🏻

props: {
items: {
type: Array,
required: true,
function(value) {
return value.every(item => typeof item === 'object' && 'id' in item);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL 🤯 'id' in { id: 1 } => true

So many times I've written Object.keys(theObj).includes(theKey) and I could have just used in

},
},
},
data() {
return {
expandedItemIds: [],
};
},
methods: {
expandAll(ids = []) {
this.expandedItemIds = ids;
expandAll() {
this.expandedItemIds = this.items.map(item => item.id);
},
collapseAll() {
this.expandedItemIds = [];
Expand All @@ -59,9 +105,44 @@
const index = this.expandedItemIds.indexOf(id);
this.expandedItemIds.splice(index, 1);
}
this.$emit('toggled', this.expandedItemIds);
},
},
};

</script>


<style lang="scss" scoped>

@import '~kolibri-design-system/lib/styles/definitions';

.accordion {
@extend %dropshadow-1dp;
}

.header-actions {
margin-top: auto;
margin-bottom: auto;
}

.header-left-actions {
display: flex;
}

.header-right-actions {
display: flex;
justify-content: flex-end;
}

.collapse-button {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-width: 40px;
padding-right: 0;
padding-left: 0;
border-radius: 50%;
}

</style>
Original file line number Diff line number Diff line change
Expand Up @@ -185,57 +185,34 @@
</KGrid>

<AccordionContainer
:items="quizForge.activeQuestions.value"
@toggled="items => expandedQuestionIds = items"
:items="quizForge.activeQuestions.value.map(i => ({
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest that we can make items a generic array of objects that contains, for example, the id attribute (instead of something specific like "question_id"), and that from this we have the criteria to know which items to choose expand when the "expand all" button is clicked.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent idea!

id: i.question_id,
}))"
>
<template #top="{ expandAll, collapseAll }">
<KGrid key="top-bar" :style="accordionTopBarStyles">
<KGridItem
class="left-side-heading"
:layout12="{ span: 6 }"
>
<KCheckbox
ref="selectAllCheckbox"
class="select-all-box"
:label="quizForge.selectAllLabel.value"
:checked="quizForge.allQuestionsSelected.value"
:indeterminate="quizForge.selectAllIsIndeterminate.value"
@change="() => quizForge.selectAllQuestions()"
/>
</KGridItem>

<KGridItem
class="right-side-heading"
:layout12="{ span: 6 }"
>
<KIconButton
icon="expandAll"
:tooltip="expandAll$()"
:disabled="expandedQuestionIds.length === quizForge.activeQuestions.value.length"
@click="expandAll(quizForge.activeQuestions.value.map(i => i.question_id))"
/>
<KIconButton
icon="collapseAll"
:tooltip="collapseAll$()"
:disabled="expandedQuestionIds.length === 0"
@click="collapseAll()"
/>
<KIconButton
icon="refresh"
:tooltip="replaceAction$()"
:disabled="quizForge.selectedActiveQuestions.value.length === 0"
@click="handleReplaceSelection"
/>
<KIconButton
icon="trash"
:tooltip="coreString('deleteAction')"
:aria-label="coreString('deleteAction')"
:disabled="quizForge.selectedActiveQuestions.value.length === 0"
@click="quizForge.deleteActiveSelectedQuestions"
/>
</KGridItem>

</KGrid>
<template #left-actions>
<KCheckbox
ref="selectAllCheckbox"
class="select-all-box"
:label="quizForge.selectAllLabel.value"
:checked="quizForge.allQuestionsSelected.value"
:indeterminate="quizForge.selectAllIsIndeterminate.value"
@change="() => quizForge.selectAllQuestions()"
/>
</template>
<template #right-actions>
<KIconButton
icon="refresh"
:tooltip="replaceAction$()"
:disabled="quizForge.selectedActiveQuestions.value.length === 0"
@click="handleReplaceSelection"
/>
<KIconButton
icon="trash"
:tooltip="coreString('deleteAction')"
:aria-label="coreString('deleteAction')"
:disabled="quizForge.selectedActiveQuestions.value.length === 0"
@click="quizForge.deleteActiveSelectedQuestions"
/>
</template>
<template #default="{ toggleItemState, isItemExpanded }">
<DragContainer
Expand Down Expand Up @@ -372,21 +349,15 @@
deleteSectionLabel$,
replaceAction$,
questionList$,
expandAll$,
collapseAll$,
} = enhancedQuizManagementStrings;

// The number we use for the default section title
const sectionCreationCount = ref(1);
const dragActive = ref(false);
const expandedQuestionIds = ref([]);

return {
expandedQuestionIds,
dragActive,
sectionCreationCount,
expandAll$,
collapseAll$,
sectionLabel$,
addQuizSections$,
quizSectionsLabel$,
Expand All @@ -411,11 +382,6 @@
userSelect: get(this.dragActive) ? 'none!important' : 'text',
};
},
accordionTopBarStyles() {
return {
backgroundColor: this.$themePalette.grey.v_100,
};
},
addQuizSectionsStyles() {
return {
margin: '0 0 1rem 0',
Expand Down