-
Notifications
You must be signed in to change notification settings - Fork 262
Issue 5449 show license audit and special permissions checks #5563
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
Changes from 12 commits
7f440fc
e2601ef
6dfe37b
ce62b6f
0a77563
c4f5167
93cc4ad
c44d667
0de5ef7
2aafe21
3345082
778b79c
414a918
5d929ea
0f726f6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| <template> | ||
|
|
||
| <Box | ||
| kind="success" | ||
| data-test="compatible-licenses-notice" | ||
| > | ||
| <template #title> | ||
| {{ licenseCheckPassed$() }} | ||
| </template> | ||
| <template #description> | ||
| {{ descriptionText }} | ||
| </template> | ||
| </Box> | ||
|
|
||
| </template> | ||
|
|
||
|
|
||
| <script> | ||
|
|
||
| import { computed } from 'vue'; | ||
| import Box from './Box.vue'; | ||
| import { formatLicenseNames } from './composables/useLicenseNames'; | ||
| import { communityChannelsStrings } from 'shared/strings/communityChannelsStrings'; | ||
|
|
||
| export default { | ||
| name: 'CompatibleLicensesNotice', | ||
| components: { | ||
| Box, | ||
| }, | ||
| setup(props) { | ||
| const { licenseCheckPassed$, compatibleLicensesDescription$ } = communityChannelsStrings; | ||
| const includedLicenseNames = computed(() => { | ||
| return formatLicenseNames(props.licenses, { | ||
| excludes: ['Special Permissions'], | ||
| }); | ||
| }); | ||
|
|
||
| const descriptionText = computed(() => { | ||
| return compatibleLicensesDescription$({ | ||
| licenseNames: includedLicenseNames.value, | ||
| }); | ||
| }); | ||
|
|
||
| return { | ||
| licenseCheckPassed$, | ||
| descriptionText, | ||
| }; | ||
| }, | ||
| props: { | ||
| licenses: { | ||
| type: Array, | ||
| required: false, | ||
| default: () => [], | ||
| }, | ||
| }, | ||
| }; | ||
|
|
||
| </script> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| <template> | ||
|
|
||
| <Box | ||
| kind="warning" | ||
| data-test="invalid-licenses-notice" | ||
| > | ||
| <template #title> | ||
| {{ incompatibleLicensesDetected$() }} | ||
| </template> | ||
| <template #description> | ||
| {{ descriptionText }} | ||
| </template> | ||
| </Box> | ||
|
|
||
| </template> | ||
|
|
||
|
|
||
| <script> | ||
|
|
||
| import { computed } from 'vue'; | ||
| import Box from './Box.vue'; | ||
| import { formatLicenseNames } from './composables/useLicenseNames'; | ||
| import { communityChannelsStrings } from 'shared/strings/communityChannelsStrings'; | ||
|
|
||
| export default { | ||
| name: 'InvalidLicensesNotice', | ||
| components: { | ||
| Box, | ||
| }, | ||
| setup(props) { | ||
| const { incompatibleLicensesDetected$, incompatibleLicensesDescription$ } = | ||
| communityChannelsStrings; | ||
| const invalidLicenseNames = computed(() => formatLicenseNames(props.invalidLicenses)); | ||
|
|
||
| const descriptionText = computed(() => { | ||
| return incompatibleLicensesDescription$({ | ||
| licenseNames: invalidLicenseNames.value, | ||
| }); | ||
| }); | ||
|
|
||
| return { | ||
| incompatibleLicensesDetected$, | ||
| descriptionText, | ||
| }; | ||
| }, | ||
| props: { | ||
| invalidLicenses: { | ||
| type: Array, | ||
| required: true, | ||
| }, | ||
| }, | ||
| }; | ||
|
|
||
| </script> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,198 @@ | ||
| <template> | ||
|
|
||
| <div data-test="special-permissions-list"> | ||
| <div class="header-section"> | ||
| <div class="title"> | ||
| {{ specialPermissionsDetected$() }} | ||
| </div> | ||
| <div class="description"> | ||
| {{ confirmDistributionRights$() }} | ||
| </div> | ||
| </div> | ||
|
|
||
| <div | ||
| v-if="isLoading" | ||
| class="loader-wrapper" | ||
| > | ||
| <KCircularLoader /> | ||
| </div> | ||
|
|
||
| <template v-else-if="currentPagePermissions.length > 0"> | ||
| <div class="permissions-box"> | ||
| <KCheckbox | ||
| v-for="permission in currentPagePermissions" | ||
| :key="permission.id" | ||
| :checked="value.includes(permission.id)" | ||
| :label="permission.description" | ||
| class="permission-checkbox" | ||
| @change="togglePermission(permission.id)" | ||
| /> | ||
| </div> | ||
|
|
||
| <div | ||
| v-if="totalPages > 1" | ||
| class="pagination" | ||
| > | ||
| <KButton | ||
| :disabled="currentPage === 1" | ||
| appearance="flat-button" | ||
| class="nav-button" | ||
| icon="chevronLeft" | ||
| @click="previousPage" | ||
| > | ||
| {{ previousPageAction$() }} | ||
| </KButton> | ||
| <span class="page-indicator"> | ||
| {{ pageIndicator$({ currentPage, totalPages }) }} | ||
| </span> | ||
| <KButton | ||
| :disabled="currentPage === totalPages" | ||
| appearance="flat-button" | ||
| class="nav-button" | ||
| iconAfter="chevronRight" | ||
| @click="nextPage" | ||
| > | ||
| {{ nextPageAction$() }} | ||
| </KButton> | ||
| </div> | ||
| </template> | ||
| </div> | ||
|
|
||
| </template> | ||
|
|
||
|
|
||
| <script> | ||
|
|
||
| import { computed, watch } from 'vue'; | ||
| import { useSpecialPermissions } from './composables/useSpecialPermissions'; | ||
| import { communityChannelsStrings } from 'shared/strings/communityChannelsStrings'; | ||
|
|
||
| export default { | ||
| name: 'SpecialPermissionsList', | ||
| components: {}, | ||
| setup(props, { emit }) { | ||
| const { | ||
| specialPermissionsDetected$, | ||
| confirmDistributionRights$, | ||
| previousPageAction$, | ||
| nextPageAction$, | ||
| pageIndicator$, | ||
| } = communityChannelsStrings; | ||
|
|
||
| const { | ||
| permissions, | ||
| currentPagePermissions, | ||
| isLoading, | ||
| currentPage, | ||
| totalPages, | ||
| nextPage, | ||
| previousPage, | ||
| } = useSpecialPermissions(props.permissionIds); | ||
|
|
||
| function togglePermission(permissionId) { | ||
| const currentChecked = [...props.value]; | ||
| const index = currentChecked.indexOf(permissionId); | ||
| if (index === -1) { | ||
| currentChecked.push(permissionId); | ||
| } else { | ||
| currentChecked.splice(index, 1); | ||
| } | ||
| emit('input', currentChecked); | ||
| } | ||
|
|
||
| const allChecked = computed(() => { | ||
| return permissions.value.every(p => props.value.includes(p.id)); | ||
| }); | ||
|
|
||
| watch( | ||
| allChecked, | ||
| val => { | ||
| emit('update:allChecked', val); | ||
| }, | ||
| { immediate: true }, | ||
| ); | ||
|
|
||
| return { | ||
| currentPagePermissions, | ||
| isLoading, | ||
| currentPage, | ||
| totalPages, | ||
| togglePermission, | ||
| nextPage, | ||
| previousPage, | ||
| specialPermissionsDetected$, | ||
| confirmDistributionRights$, | ||
| previousPageAction$, | ||
| nextPageAction$, | ||
| pageIndicator$, | ||
| }; | ||
| }, | ||
| props: { | ||
| permissionIds: { | ||
| type: Array, | ||
| required: false, | ||
| default: () => [], | ||
| }, | ||
| value: { | ||
| type: Array, | ||
| required: false, | ||
| default: () => [], | ||
| }, | ||
| }, | ||
| emits: ['input', 'update:allChecked'], | ||
| }; | ||
|
|
||
| </script> | ||
|
|
||
|
|
||
| <style scoped lang="scss"> | ||
|
|
||
| .header-section { | ||
| margin-bottom: 8px; | ||
| } | ||
|
|
||
| .title { | ||
| margin-bottom: 4px; | ||
| font-weight: bold; | ||
| } | ||
|
|
||
| .description { | ||
| margin-bottom: 12px; | ||
| font-size: 14px; | ||
| } | ||
|
|
||
| .permissions-box { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 12px; | ||
| padding: 16px; | ||
|
||
| background-color: v-bind('$themePalette.grey.v_100'); | ||
| border: 1px solid v-bind('$themePalette.grey.v_200'); | ||
| border-radius: 4px; | ||
| } | ||
|
|
||
| .permission-checkbox { | ||
| margin: 0; | ||
| font-size: 14px; | ||
| } | ||
|
|
||
| .pagination { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| padding-top: 8px; | ||
|
||
| margin-top: 8px; | ||
| } | ||
|
|
||
| .page-indicator { | ||
| font-size: 14px; | ||
| color: v-bind('$themeTokens.text'); | ||
| } | ||
|
|
||
| .loader-wrapper { | ||
| display: flex; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
|
|
||
| </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.
It seems that there is a
titleclass in vuetify that is affecting this node. Could you please rename this class to prevent the conflict? thanks!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.
Thanks Alex. For const ITEMS_PER_PAGE = 5, You suggested changing to 3. But the figma shows it should be 5.

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.
Hey @taoerman! That five refers to the number of pages 😅, but the specs only show 3 per page.