diff --git a/backend/package.json b/backend/package.json index 427d1a491..e7d00cee3 100644 --- a/backend/package.json +++ b/backend/package.json @@ -71,7 +71,7 @@ "metascraper-image": "^5.9.5", "metascraper-lang": "^5.10.3", "metascraper-lang-detector": "^4.10.2", - "metascraper-logo": "^5.9.5", + "metascraper-logo": "^5.10.3", "metascraper-publisher": "^5.10.3", "metascraper-soundcloud": "^5.9.5", "metascraper-title": "^5.10.3", diff --git a/backend/yarn.lock b/backend/yarn.lock index f5ffb1b75..af96816a1 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -6020,12 +6020,12 @@ metascraper-lang@^5.10.3: dependencies: "@metascraper/helpers" "^5.10.3" -metascraper-logo@^5.9.5: - version "5.9.5" - resolved "https://registry.yarnpkg.com/metascraper-logo/-/metascraper-logo-5.9.5.tgz#1fee5b3de1c79380d50c8e2ecd3d102b6cb9f7d4" - integrity sha512-rbBLYVX4xSIzzeQJaUyibQYzjlNGlkyri14ixpIlCdlri3KQ0rRKnwQSeOSUlAu1rVsL7JlsMrhMDCb21dX9sQ== +metascraper-logo@^5.10.3: + version "5.10.3" + resolved "https://registry.yarnpkg.com/metascraper-logo/-/metascraper-logo-5.10.3.tgz#22847c9ba65d8ae8e8af05d838f1da0953215300" + integrity sha512-8bliBXhe638D5A1gFh3q07rxYMCD6WOgywKFKPLcgOb0YybOU0MlrHkInXaGLMGCinULw3cXCn67b/+11mbmHA== dependencies: - "@metascraper/helpers" "^5.9.5" + "@metascraper/helpers" "^5.10.3" metascraper-publisher@^5.10.3: version "5.10.3" diff --git a/webapp/assets/_new/styles/tokens.scss b/webapp/assets/_new/styles/tokens.scss index 3304c0e00..71114cf21 100644 --- a/webapp/assets/_new/styles/tokens.scss +++ b/webapp/assets/_new/styles/tokens.scss @@ -240,6 +240,13 @@ $size-height-xlarge: 60px; $size-height-footer: 64px; $size-tappable-square: 44px; +/** + * @tokens Size Width + * @presenter Spacing + */ + +$size-width-paginate: 100px; + /** * @tokens Size Avatar * @presenter Spacing @@ -259,7 +266,7 @@ $size-avatar-x-large: 114px; $size-button-small: 26px; /** - * @tokens Size Buttons + * @tokens Size Icons * @presenter Spacing */ diff --git a/webapp/assets/styles/main.scss b/webapp/assets/styles/main.scss index b59399b02..fbab1d78f 100644 --- a/webapp/assets/styles/main.scss +++ b/webapp/assets/styles/main.scss @@ -175,3 +175,7 @@ hr { overflow-wrap: break-word; word-wrap: break-word; } + +.dropdown-arrow { + font-size: $font-size-xx-small; +} diff --git a/webapp/components/DeleteData/DeleteData.spec.js b/webapp/components/DeleteData/DeleteData.spec.js index 739bbe732..3529c1b7b 100644 --- a/webapp/components/DeleteData/DeleteData.spec.js +++ b/webapp/components/DeleteData/DeleteData.spec.js @@ -81,7 +81,7 @@ describe('DeleteData.vue', () => { }) it('does not call the delete user mutation if deleteEnabled is false', () => { - deleteAccountBtn = wrapper.find('.ds-button-danger') + deleteAccountBtn = wrapper.find('[data-test="delete-button"]') deleteAccountBtn.trigger('click') expect(mocks.$apollo.mutate).not.toHaveBeenCalled() }) @@ -90,7 +90,7 @@ describe('DeleteData.vue', () => { beforeEach(() => { enableDeletionInput = wrapper.find('.enable-deletion-input input') enableDeletionInput.setValue(deleteAccountName) - deleteAccountBtn = wrapper.find('.ds-button-danger') + deleteAccountBtn = wrapper.find('[data-test="delete-button"]') }) it('if deleteEnabled is true and only deletes user by default', () => { @@ -169,7 +169,7 @@ describe('DeleteData.vue', () => { enableDeletionInput = wrapper.find('.enable-deletion-input input') enableDeletionInput.setValue(deleteAccountName) await Vue.nextTick() - deleteAccountBtn = wrapper.find('.ds-button-danger') + deleteAccountBtn = wrapper.find('[data-test="delete-button"]') await deleteAccountBtn.trigger('click') // second submission causes mutation to reject await deleteAccountBtn.trigger('click') diff --git a/webapp/components/DeleteData/DeleteData.vue b/webapp/components/DeleteData/DeleteData.vue index 9ecdbb850..66a31205a 100644 --- a/webapp/components/DeleteData/DeleteData.vue +++ b/webapp/components/DeleteData/DeleteData.vue @@ -55,22 +55,19 @@ - + - {{ $t('settings.deleteUserAccount.name') }} - + @@ -88,7 +85,6 @@ export default { return { deleteContributions: false, deleteComments: false, - deleteEnabled: false, enableDeletionValue: null, } }, @@ -96,16 +92,14 @@ export default { ...mapGetters({ currentUser: 'auth/user', }), + deleteEnabled() { + return this.enableDeletionValue === this.currentUser.name + }, }, methods: { ...mapActions({ logout: 'auth/logout', }), - enableDeletion() { - if (this.enableDeletionValue === this.currentUser.name) { - this.deleteEnabled = true - } - }, handleSubmit() { const resourceArgs = [] if (this.deleteContributions) { diff --git a/webapp/components/DropdownFilter/DropdownFilter.vue b/webapp/components/DropdownFilter/DropdownFilter.vue index bfa78e709..f7bcf507d 100644 --- a/webapp/components/DropdownFilter/DropdownFilter.vue +++ b/webapp/components/DropdownFilter/DropdownFilter.vue @@ -65,10 +65,6 @@ export default { } } -.dropdown-arrow { - font-size: $font-size-xx-small; -} - .dropdown-menu { user-select: none; display: flex; diff --git a/webapp/components/Editor/Editor.vue b/webapp/components/Editor/Editor.vue index 6c8a1908a..235437c32 100644 --- a/webapp/components/Editor/Editor.vue +++ b/webapp/components/Editor/Editor.vue @@ -326,85 +326,4 @@ li > p { margin: 0 0 $space-x-small; } } - -.ProseMirror[contenteditable='false'] { - .embed-close-button { - display: none; - } -} - -.embed-container { - position: relative; - padding: 0; - margin: $space-small auto; - overflow: hidden; - border-radius: $border-radius-base; - border: 1px solid $color-neutral-70; - background-color: $color-neutral-90; -} - -.embed-content { - width: 100%; - height: 100%; - - h4 { - margin: $space-small 0 0 $space-small; - } - - p, - a { - display: block; - margin: 0 0 0 $space-small; - } -} - -.embed-preview-image { - width: 100%; - height: auto; - max-height: 450px; -} - -.embed-preview-image--clickable { - cursor: pointer; -} - -.embed-html { - width: 100%; - - iframe { - width: 100%; - } -} - -.embed-overlay { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - - padding: $space-large; - background-color: $color-neutral-100; -} - -.embed-buttons { - button { - margin-right: $space-small; - } -} - -.embed-checkbox { - display: flex; - - input { - margin-right: $space-small; - } -} - -.embed-close-button { - position: absolute; - top: $space-x-small; - right: $space-x-small; - background-color: rgba(250, 249, 250, 0.6); -} diff --git a/webapp/components/Embed/EmbedComponent.spec.js b/webapp/components/Embed/EmbedComponent.spec.js index ab0f0c8fb..157b4f9c6 100644 --- a/webapp/components/Embed/EmbedComponent.spec.js +++ b/webapp/components/Embed/EmbedComponent.spec.js @@ -65,13 +65,13 @@ describe('EmbedComponent.vue', () => { }) it('shows the description', () => { - expect(wrapper.find('.embed-content p').text()).toBe( + expect(wrapper.find('.content p').text()).toBe( 'Salut tout le monde ! Aujourd’hui, une vidéo sur le scepticisme, nous allons parler médiumnité avec le cas de Bruno CHARVET : « Bruno, un nouveau message ». Merci de rester respectueux dans les commentaires : SOURCES : Les sources des vi...', ) }) it('shows preview Images for link', () => { - expect(wrapper.find('.embed-preview-image').exists()).toBe(true) + expect(wrapper.find('.preview').exists()).toBe(true) }) }) @@ -92,7 +92,7 @@ describe('EmbedComponent.vue', () => { }) it('show the desciption', () => { - expect(wrapper.find('.embed-content p').text()).toBe( + expect(wrapper.find('.content p').text()).toBe( 'She’s incapable of controlling her limbs when her kitty is around. The obsession grows every day. Ps. That’s a sleep sack she’s in. Not a starfish outfit. Al...', ) }) @@ -121,12 +121,12 @@ describe('EmbedComponent.vue', () => { }) it('shows a simple link when a user closes the embed preview', () => { - wrapper.find('.embed-close-button').trigger('click') + wrapper.find('.close-button').trigger('click') expect(wrapper.vm.showLinkOnly).toBe(true) }) it('opens the data privacy overlay when a user clicks on the preview image', () => { - wrapper.find('.embed-preview-image--clickable').trigger('click') + wrapper.find('.preview.--clickable').trigger('click') expect(wrapper.vm.showOverlay).toBe(true) }) @@ -135,19 +135,19 @@ describe('EmbedComponent.vue', () => { wrapper.setData({ showOverlay: true }) }) - it('when user agress', () => { - wrapper.find('.ds-button-primary').trigger('click') + it('when user agrees', () => { + wrapper.find('[data-test="play-now-button"]').trigger('click') expect(wrapper.vm.showEmbed).toBe(true) }) it('does not show iframe when user clicks to cancel', () => { - wrapper.find('.ds-button-ghost').trigger('click') + wrapper.find('[data-test="cancel-button"]').trigger('click') expect(wrapper.vm.showEmbed).toBe(false) }) describe("doesn't set permanently", () => { beforeEach(() => { - wrapper.find('.ds-button-primary').trigger('click') + wrapper.find('[data-test="play-now-button"]').trigger('click') }) it("if user doesn't give consent", () => { @@ -162,7 +162,7 @@ describe('EmbedComponent.vue', () => { describe('sets permanently', () => { beforeEach(() => { wrapper.find('input[type=checkbox]').trigger('click') - wrapper.find('.ds-button-primary').trigger('click') + wrapper.find('[data-test="play-now-button"]').trigger('click') }) it('changes setting permanetly when user requests', () => { @@ -194,7 +194,7 @@ describe('EmbedComponent.vue', () => { }) it('does not display image to click', () => { - expect(wrapper.find('.embed-preview-image--clickable').exists()).toBe(false) + expect(wrapper.find('.preview.--clickable').exists()).toBe(false) }) }) }) diff --git a/webapp/components/Embed/EmbedComponent.vue b/webapp/components/Embed/EmbedComponent.vue index f1790304e..7c08db87b 100644 --- a/webapp/components/Embed/EmbedComponent.vue +++ b/webapp/components/Embed/EmbedComponent.vue @@ -2,17 +2,17 @@ {{ dataEmbedUrl }} - -
-
+ +
+

{{ embedTitle }}

{{ embedDescription }}

@@ -20,25 +20,27 @@ {{ dataEmbedUrl }}
-
- + diff --git a/webapp/components/generic/SearchableInput/SearchableInput.spec.js b/webapp/components/generic/SearchableInput/SearchableInput.spec.js index 0ebcda63f..d606177a5 100644 --- a/webapp/components/generic/SearchableInput/SearchableInput.spec.js +++ b/webapp/components/generic/SearchableInput/SearchableInput.spec.js @@ -32,82 +32,78 @@ describe('SearchableInput.vue', () => { } describe('mount', () => { - describe('testing custom functions', () => { - let select + let select + beforeEach(() => { + select = wrapper.find('.ds-select') + select.trigger('focus') + select.element.value = 'abcd' + }) + + it('opens the dropdown when focused', () => { + expect(wrapper.find('.ds-select-dropdown').isVisible()).toBe(true) + }) + + it('closes the dropdown when blurred', () => { + select.trigger('blur') + expect(wrapper.find('.ds-select-is-open').exists()).toBe(false) + }) + + it('closes the dropdown when cleared with esc key', () => { + select.trigger('input') + select.trigger('keyup.esc') + expect(wrapper.find('.ds-select-is-open').exists()).toBe(false) + }) + + it('changes the unprocessedSearchInput as the value changes', () => { + select.trigger('input') + expect(select.element.value).toBe('abcd') + }) + + it('searches for the term when enter is pressed', async () => { + select.element.value = 'ab' + select.trigger('input') + select.trigger('keyup.enter') + await expect(wrapper.emitted().query[0]).toEqual(['ab']) + }) + + it('calls onDelete when the delete key is pressed', () => { + const spy = jest.spyOn(wrapper.vm, 'onDelete') + select.trigger('input') + select.trigger('keyup.delete') + expect(spy).toHaveBeenCalledTimes(1) + }) + + describe('navigating to resource', () => { beforeEach(() => { + propsData = { options: searchResults } + wrapper = Wrapper() select = wrapper.find('.ds-select') select.trigger('focus') - select.element.value = 'abcd' }) - it('opens the select dropdown when focused on', () => { - expect(wrapper.find('.is-open').exists()).toBe(true) - }) - - it('opens the select dropdown and blurs after focused on', async () => { - select.trigger('blur') + it('pushes to post page', async () => { + select.element.value = 'Post' + select.trigger('input') + const post = wrapper.find('.search-post') + post.trigger('click') await Vue.nextTick() - expect(wrapper.find('.is-open').exists()).toBe(false) + expect(mocks.$router.push).toHaveBeenCalledWith({ + name: 'post-id-slug', + params: { id: 'post-by-jenny', slug: 'user-post-by-jenny' }, + }) }) - it('is clearable', async () => { + it("pushes to user's profile", async () => { + select.element.value = 'Bob' select.trigger('input') - select.trigger('keyup.esc') + const users = wrapper.findAll('.userinfo') + const bob = users.filter(item => item.text() === '@bob-der-baumeister') + bob.trigger('click') await Vue.nextTick() - expect(wrapper.find('.is-open').exists()).toBe(false) - }) - - it('changes the unprocessedSearchInput as the value changes', () => { - select.trigger('input') - expect(select.element.value).toBe('abcd') - }) - - it('searches for the term when enter is pressed', async () => { - select.element.value = 'ab' - select.trigger('input') - select.trigger('keyup.enter') - await expect(wrapper.emitted().query[0]).toEqual(['ab']) - }) - - it('calls onDelete when the delete key is pressed', () => { - const spy = jest.spyOn(wrapper.vm, 'onDelete') - select.trigger('input') - select.trigger('keyup.delete') - expect(spy).toHaveBeenCalledTimes(1) - }) - - describe('navigating to resource', () => { - beforeEach(() => { - propsData = { options: searchResults } - wrapper = Wrapper() - select = wrapper.find('.ds-select') - select.trigger('focus') - }) - - it('pushes to post page', async () => { - select.element.value = 'Post' - select.trigger('input') - const post = wrapper.find('.search-post') - post.trigger('click') - await Vue.nextTick() - expect(mocks.$router.push).toHaveBeenCalledWith({ - name: 'post-id-slug', - params: { id: 'post-by-jenny', slug: 'user-post-by-jenny' }, - }) - }) - - it("pushes to user's profile", async () => { - select.element.value = 'Bob' - select.trigger('input') - const users = wrapper.findAll('.userinfo') - const bob = users.filter(item => item.text() === '@bob-der-baumeister') - bob.trigger('click') - await Vue.nextTick() - expect(mocks.$router.push).toHaveBeenCalledWith({ - name: 'profile-id-slug', - params: { id: 'u2', slug: 'bob-der-baumeister' }, - }) + expect(mocks.$router.push).toHaveBeenCalledWith({ + name: 'profile-id-slug', + params: { id: 'u2', slug: 'bob-der-baumeister' }, }) }) }) diff --git a/webapp/components/generic/SearchableInput/SearchableInput.vue b/webapp/components/generic/SearchableInput/SearchableInput.vue index cc9269ecf..a45f4104c 100644 --- a/webapp/components/generic/SearchableInput/SearchableInput.vue +++ b/webapp/components/generic/SearchableInput/SearchableInput.vue @@ -1,60 +1,46 @@ + + diff --git a/webapp/layouts/default.vue b/webapp/layouts/default.vue index 6be75cd35..de0e94af7 100644 --- a/webapp/layouts/default.vue +++ b/webapp/layouts/default.vue @@ -4,21 +4,21 @@
- - + - + @@ -26,8 +26,8 @@ -
@@ -164,17 +163,21 @@ export default { } .main-navigation-right { display: flex; - flex: 1; + justify-content: flex-end; } .main-navigation-right .desktop-view { float: right; } -@media only screen and (min-width: 960px) { +.ds-flex-item.mobile-hamburger-menu { + margin-left: auto; + text-align: right; +} +@media only screen and (min-width: 730px) { .mobile-hamburger-menu { display: none; } } -@media only screen and (max-width: 960px) { +@media only screen and (max-width: 730px) { #nav-search-box, .main-navigation-right { margin: 10px 0px; diff --git a/webapp/pages/admin/users.vue b/webapp/pages/admin/users.vue index e56be70ab..610307704 100644 --- a/webapp/pages/admin/users.vue +++ b/webapp/pages/admin/users.vue @@ -50,7 +50,7 @@ {{ scope.row.createdAt | dateTime }} - + {{ $t('admin.users.empty') }} @@ -62,11 +62,11 @@ import gql from 'graphql-tag' import { isEmail } from 'validator' import normalizeEmail from '~/components/utils/NormalizeEmail' -import HcPaginate from '~/components/Paginate/Paginate' +import PaginationButtons from '~/components/_new/generic/PaginationButtons/PaginationButtons' export default { components: { - HcPaginate, + PaginationButtons, }, data() { const pageSize = 15 diff --git a/webapp/pages/index.spec.js b/webapp/pages/index.spec.js index d5d677af1..f25f44ca0 100644 --- a/webapp/pages/index.spec.js +++ b/webapp/pages/index.spec.js @@ -126,11 +126,6 @@ describe('PostIndex', () => { .trigger('click') expect(mutations['posts/SELECT_ORDER']).toHaveBeenCalledWith({}, 'createdAt_asc') }) - - it('updates offset when a user clicks on the load more button', () => { - wrapper.find('.load-more button').trigger('click') - expect(wrapper.vm.offset).toEqual(12) - }) }) }) }) diff --git a/webapp/pages/index.vue b/webapp/pages/index.vue index c0b96ccbc..609c3d800 100644 --- a/webapp/pages/index.vue +++ b/webapp/pages/index.vue @@ -58,9 +58,7 @@ - - - +
@@ -70,7 +68,6 @@ import FilterMenu from '~/components/FilterMenu/FilterMenu.vue' import HcEmpty from '~/components/Empty/Empty' import HcPostCard from '~/components/PostCard/PostCard.vue' -import HcLoadMore from '~/components/LoadMore.vue' import MasonryGrid from '~/components/MasonryGrid/MasonryGrid.vue' import MasonryGridItem from '~/components/MasonryGrid/MasonryGridItem.vue' import { mapGetters, mapMutations } from 'vuex' @@ -83,7 +80,6 @@ export default { // DonationInfo, FilterMenu, HcPostCard, - HcLoadMore, HcEmpty, MasonryGrid, MasonryGridItem, diff --git a/webapp/pages/notifications/index.spec.js b/webapp/pages/notifications/index.spec.js index 66f68aac7..70592b467 100644 --- a/webapp/pages/notifications/index.spec.js +++ b/webapp/pages/notifications/index.spec.js @@ -3,7 +3,7 @@ import NotificationsPage from './index.vue' import DropdownFilter from '~/components/DropdownFilter/DropdownFilter' import NotificationsTable from '~/components/NotificationsTable/NotificationsTable' -import Paginate from '~/components/Paginate/Paginate' +import PaginationButtons from '~/components/_new/generic/PaginationButtons/PaginationButtons' const localVue = global.localVue @@ -122,14 +122,14 @@ describe('PostIndex', () => { }) }) - describe('Paginate', () => { + describe('PaginationButtons', () => { beforeEach(() => { wrapper = Wrapper() }) describe('next: given a user is on the first page', () => { it('adds offset to pageSize to skip first x notifications and display next page', () => { - wrapper.find(Paginate).vm.$emit('next') + wrapper.find(PaginationButtons).vm.$emit('next') expect(wrapper.vm.offset).toEqual(12) }) }) @@ -137,7 +137,7 @@ describe('PostIndex', () => { describe('back: given a user is on the third page', () => { it('sets offset when back is emitted', () => { wrapper.setData({ offset: 24 }) - wrapper.find(Paginate).vm.$emit('back') + wrapper.find(PaginationButtons).vm.$emit('back') expect(wrapper.vm.offset).toEqual(12) }) }) diff --git a/webapp/pages/notifications/index.vue b/webapp/pages/notifications/index.vue index aa002cec7..c49d208be 100644 --- a/webapp/pages/notifications/index.vue +++ b/webapp/pages/notifications/index.vue @@ -15,21 +15,21 @@ @markNotificationAsRead="markNotificationAsRead" :notifications="notifications" /> - +