-
Notifications
You must be signed in to change notification settings - Fork 254
[Remove Vuetify from Studio] Channel collections table (first draft version) #5535
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
base: unstable
Are you sure you want to change the base?
Changes from all commits
10227a6
5c4b746
aff2f08
5a337b2
7593d05
db1fc42
5e9cb5e
24cd3e0
daf9c36
6d4a9fe
7c8eb95
8e93066
14dcde2
c468647
0020582
cba9ba3
df764f1
0631afd
7ca728a
a8d3848
2f0fdad
89e1c81
64b8646
f2d33fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,345 @@ | ||
| <template> | ||
|
|
||
| <KPageContainer class="page-container"> | ||
| <div class="table-header"> | ||
| <div class="header-left"> | ||
| <KButton | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| appearance="basic-link" | ||
| class="info-link" | ||
| @click="infoDialog = true" | ||
| > | ||
| {{ $tr('aboutChannelSetsLink') }} | ||
| </KButton> | ||
|
|
||
| <KModal | ||
| v-if="infoDialog" | ||
| :title="$tr('aboutChannelSets')" | ||
| :cancelText="$tr('cancelButtonLabel')" | ||
| @cancel="infoDialog = false" | ||
| > | ||
| <div class="info-content"> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that |
||
| <p>{{ $tr('channelSetsDescriptionText') }}</p> | ||
| <p>{{ $tr('channelSetsInstructionsText') }}</p> | ||
| <p | ||
| class="disclaimer" | ||
| :style="{ color: $themeTokens.error }" | ||
| > | ||
| {{ $tr('channelSetsDisclaimer') }} | ||
| </p> | ||
| </div> | ||
| </KModal> | ||
| </div> | ||
|
|
||
| <div class="header-right"> | ||
| <KButton | ||
| v-if="!loading" | ||
| appearance="raised-button" | ||
| primary | ||
| data-test="add-channelset" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unused attribute |
||
| :text="$tr('addChannelSetTitle')" | ||
| @click="newChannelSet" | ||
| /> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div class="table-container"> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unused class and div |
||
| <KTable | ||
| class="collections-table" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unused class. There are many other unused classes in this file, I won't comment on all of them. Please check and cleanup all that are not needed. |
||
| :stickyColumns="stickyColumns" | ||
| caption="" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Caption is needed for accessibility. Would you preview https://design-system.learningequality.org/ktable#usage, MDN links, and KDS examples? That will guide you with creating a caption that describes concisely and accurately table content. Also please make it a translated string. |
||
| :headers="tableHeaders" | ||
| :rows="tableRows" | ||
| :dataLoading="loading" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you use See https://design-system.learningequality.org/usekshow for how&why, and you can search the codebase for similar existing implementations. This means we won't be utilizing (TODO for @MisRob open a KDS issue to apply |
||
| sortable | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you also use |
||
| disableBuiltinSorting | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs to be removed. Because of this |
||
| :emptyMessage="$tr('noChannelSetsFound')" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We've recently (#5543) updated link position to be within the empty message:
Would you update this file to achieve similar behavior (but within the new white page container)? Presence of link in the empty message text will mean that we won't be using (TODO for @MisRob: Open KDS |
||
| > | ||
| <template #cell="{ content, colIndex }"> | ||
| <!-- Column 0: Collection Name --> | ||
| <div | ||
| v-if="colIndex === 0" | ||
| class="collection-name-cell" | ||
| > | ||
| <div class="collection-info"> | ||
| <h3 | ||
| class="collection-title notranslate" | ||
| dir="auto" | ||
| > | ||
| {{ content }} | ||
| </h3> | ||
| </div> | ||
| </div> | ||
|
|
||
| <!-- Column 1: Tokens --> | ||
| <div | ||
| v-else-if="colIndex === 1" | ||
| class="tokens-cell" | ||
| > | ||
| <StudioCopyToken | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This will optimize how we use space and make rows height smaller.
|
||
| v-if="content" | ||
| :token="content" | ||
| class="token-item" | ||
| :loading="!content" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The loader will never show since |
||
| /> | ||
| <em | ||
| v-else | ||
| :style="{ color: $themeTokens.annotation }" | ||
| class="saving-text" | ||
| > | ||
| {{ $tr('saving') }} | ||
| </em> | ||
| </div> | ||
|
|
||
| <!-- Column 2: Channel Count --> | ||
| <div | ||
| v-else-if="colIndex === 2" | ||
| class="channel-count" | ||
| > | ||
| {{ $formatNumber(content) }} | ||
| </div> | ||
|
|
||
| <!-- Column 3: Actions --> | ||
| <div | ||
| v-else-if="colIndex === 3" | ||
| class="actions-cell" | ||
| > | ||
| <KIconButton | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is exactly as requested in the issue for draft version, thank you. I talked about details with designers meanwhile and the final behavior we'd like would be to:
but only as long as there is enough space on the screen.
Reasoning being that in contrast to Kolibri's Users table, Collections table has more space and so when we can, we will display the full button to benefit from a bit more clarity. You will need to use |
||
| icon="optionsVertical" | ||
| :aria-label="$tr('options')" | ||
| > | ||
| <template #menu> | ||
| <KDropdownMenu | ||
| :options="dropdownOptions" | ||
| :hasIcons="true" | ||
| @select="option => handleOptionSelect(option, content)" | ||
| /> | ||
| </template> | ||
| </KIconButton> | ||
| </div> | ||
| </template> | ||
| </KTable> | ||
| </div> | ||
|
|
||
| <!-- Delete Confirmation Modal --> | ||
| <KModal | ||
| v-if="deleteDialog" | ||
| :title="$tr('deleteChannelSetTitle')" | ||
| :submitText="$tr('delete')" | ||
| :cancelText="$tr('cancel')" | ||
| @submit="confirmDelete" | ||
| @cancel="deleteDialog = false" | ||
| > | ||
| <p>{{ $tr('deleteChannelSetText') }}</p> | ||
| </KModal> | ||
| </KPageContainer> | ||
|
|
||
| </template> | ||
|
|
||
|
|
||
| <script> | ||
| import { mapActions, mapGetters } from 'vuex'; | ||
| import { RouteNames } from '../../constants'; | ||
| import StudioCopyToken from '../../../settings/pages/Account/StudioCopyToken'; | ||
| export default { | ||
| name: 'StudioCollectionsTable', | ||
| components: { | ||
| StudioCopyToken, | ||
| }, | ||
| data() { | ||
| return { | ||
| loading: true, | ||
| infoDialog: false, | ||
| deleteDialog: false, | ||
| collectionToDelete: null, | ||
| }; | ||
| }, | ||
| computed: { | ||
| ...mapGetters('channelSet', ['channelSets', 'getChannelSet']), | ||
| tableHeaders() { | ||
| return [ | ||
| { | ||
| label: this.$tr('title'), | ||
| dataType: 'string', | ||
| minWidth: '200px', | ||
| width: '55%', | ||
| columnId: 'name', | ||
| }, | ||
| { | ||
| label: this.$tr('token'), | ||
| dataType: 'string', | ||
| minWidth: '200px', | ||
| width: '20%', | ||
| columnId: 'tokens', | ||
| }, | ||
| { | ||
| label: this.$tr('channelNumber'), | ||
| dataType: 'number', | ||
| minWidth: '100px', | ||
| width: '15%', | ||
| columnId: 'channel_count', | ||
| }, | ||
| { | ||
| label: '', | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add a descriptive label here and then visually hide it? After you have installed learningequality/kolibri-design-system#1169 as suggested in the other comment, |
||
| dataType: 'undefined', | ||
| width: '10%', | ||
| columnId: 'actions', | ||
| }, | ||
| ]; | ||
| }, | ||
| tableRows() { | ||
| if (!this.channelSets || !Array.isArray(this.channelSets)) { | ||
| return []; | ||
| } | ||
| return this.channelSets.map(collection => { | ||
| const channelSet = this.getChannelSet(collection.id); | ||
| const channelCount = channelSet?.channels?.length || 0; | ||
| return [ | ||
| collection.name || '', | ||
| collection.secret_token || null, | ||
| channelCount, | ||
| collection.id, | ||
| ]; | ||
| }); | ||
| }, | ||
| stickyColumns() { | ||
| return ['first', 'last']; | ||
| }, | ||
| dropdownOptions() { | ||
| return [ | ||
| { | ||
| label: this.$tr('edit'), | ||
| value: 'edit', | ||
| icon: 'edit', | ||
| }, | ||
| { | ||
| label: this.$tr('delete'), | ||
| value: 'delete', | ||
| icon: 'trash', | ||
| }, | ||
| ]; | ||
| }, | ||
| }, | ||
| mounted() { | ||
| this.loadChannelSetList().then(() => { | ||
| this.loading = false; | ||
| }); | ||
| }, | ||
| methods: { | ||
| ...mapActions('channelSet', ['loadChannelSetList', 'deleteChannelSet']), | ||
| handleOptionSelect(option, collectionId) { | ||
| if (option.value === 'edit') { | ||
| this.$router.push({ | ||
| name: RouteNames.CHANNEL_SET_DETAILS, | ||
| params: { channelSetId: collectionId }, | ||
| }); | ||
| } else if (option.value === 'delete') { | ||
| this.collectionToDelete = | ||
| this.getChannelSet(collectionId) || | ||
| this.channelSets.find(c => c.id === collectionId) || | ||
| null; | ||
| if (this.collectionToDelete) this.deleteDialog = true; | ||
| } | ||
| }, | ||
| confirmDelete() { | ||
| if (this.collectionToDelete) { | ||
| this.deleteChannelSet(this.collectionToDelete) | ||
| .then(() => { | ||
| this.loadChannelSetList(); | ||
| this.deleteDialog = false; | ||
| this.collectionToDelete = null; | ||
| this.$store.dispatch('showSnackbarSimple', this.$tr('collectionDeleted')); | ||
| }) | ||
| .catch(() => { | ||
| this.deleteDialog = false; | ||
| this.collectionToDelete = null; | ||
| this.$store.dispatch('showSnackbarSimple', this.$tr('deleteError')); | ||
| }); | ||
| } | ||
| }, | ||
| newChannelSet() { | ||
| this.$router.push({ | ||
| name: RouteNames.NEW_CHANNEL_SET, | ||
| }); | ||
| }, | ||
| }, | ||
| $trs: { | ||
| aboutChannelSetsLink: 'Learn about collections', | ||
| aboutChannelSets: 'About collections', | ||
| channelSetsDescriptionText: | ||
| 'A collection contains multiple Kolibri Studio channels that can be imported at one time to Kolibri with a single collection token.', | ||
| channelSetsInstructionsText: | ||
| 'You can make a collection by selecting the channels you want to be imported together.', | ||
| channelSetsDisclaimer: | ||
| 'You will need Kolibri version 0.12.0 or higher to import channel collections', | ||
| cancelButtonLabel: 'Close', | ||
| addChannelSetTitle: 'New collection', | ||
| noChannelSetsFound: | ||
| 'You can package together multiple channels to create a collection. The entire collection can then be imported to Kolibri at once by using a collection token.', | ||
| title: 'Collection name', | ||
| token: 'Token ID', | ||
| channelNumber: 'Number of channels', | ||
| options: 'Options', | ||
| deleteChannelSetTitle: 'Delete collection', | ||
| deleteChannelSetText: 'Are you sure you want to delete this collection?', | ||
| cancel: 'Cancel', | ||
| edit: 'Edit collection', | ||
| delete: 'Delete collection', | ||
| saving: 'Saving', | ||
| collectionDeleted: 'Collection deleted', | ||
| deleteError: 'Error deleting collection', | ||
| }, | ||
| }; | ||
| </script> | ||
| <style lang="scss" scoped> | ||
| .page-container { | ||
| width: 100%; | ||
| max-width: 1440px; | ||
| margin: 0 auto; | ||
| text-align: center; | ||
| } | ||
| .table-header { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 16px; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| margin-bottom: 24px; | ||
| } | ||
| .header-left, | ||
| .header-right { | ||
| display: flex; | ||
| align-items: center; | ||
| } | ||
| .info-content p { | ||
| margin-bottom: 16px; | ||
| } | ||
| .actions-cell { | ||
| display: flex; | ||
| justify-content: flex-end; | ||
| } | ||
| @media (max-width: 500px) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We avoid CSS media queries in favor of our layout system - mostly for consistency. Can you use |
||
| .table-header { | ||
| justify-content: center; | ||
| } | ||
| } | ||
| </style> | ||




There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that
ChannelSetListandChannelSetItemfiles (+ related obsolete test suites) can be removed since they won't be used anymore from anywhere - can you check on it and delete if that is so?Before removing them, I recommend you merge latest
unstablesince we recently did some updates toChannelSetList(#5543) - that way you hopefully won't have any conflicts during the process.