diff --git a/frontend/assets/style/components/_buttons.scss b/frontend/assets/style/components/_buttons.scss
index 33756591c2..0aee63e4a4 100644
--- a/frontend/assets/style/components/_buttons.scss
+++ b/frontend/assets/style/components/_buttons.scss
@@ -202,11 +202,12 @@ button,
color: transparent;
// Delay the spin for 500ms, in case load is ultra fast.
// That way the user won't even see the loading
- transition: color 400ms 500ms;
+ // [1] !important so it works even when .js-reducedMotion
+ transition: color 400ms 500ms !important; // [1]
&::after {
opacity: 1;
- transition: opacity 400ms 500ms;
+ transition: opacity 400ms 500ms !important; // [1]
animation: loadSpin 1.75s infinite linear;
}
}
diff --git a/frontend/assets/style/components/_pills.scss b/frontend/assets/style/components/_pills.scss
index 0138726566..2e825b390b 100644
--- a/frontend/assets/style/components/_pills.scss
+++ b/frontend/assets/style/components/_pills.scss
@@ -1,29 +1,20 @@
.pill {
- font-weight: 600;
- border-radius: 3px;
- padding: 0.375rem $spacer-sm;
+ border-radius: $radius;
+ padding: 0.125rem 0.25rem;
line-height: 1;
- margin: 0 $spacer-xs;
display: inline-block;
white-space: nowrap;
+ text-transform: uppercase;
+ font-size: $size_5;
- &.is-small {
- padding: ($spacer / 8) $spacer-xs;
- text-transform: uppercase;
- font-size: $size_5;
- font-weight: 100;
- }
-
- &.has-background-dark {
- background: $text_0;
- color: $general_2;
+ &.is-neutral {
+ background-color: $general_0;
}
@each $name in $colors {
&.is-#{$name} {
- @extend .pill;
- @extend .has-background-#{$name};
- @extend .has-text-#{$name};
+ background-color: var(--#{$name}_2);
+ color: var(--#{$name}_0);
}
}
}
diff --git a/frontend/model/contracts/group.js b/frontend/model/contracts/group.js
index 6bfba76499..0bffed953c 100644
--- a/frontend/model/contracts/group.js
+++ b/frontend/model/contracts/group.js
@@ -62,10 +62,11 @@ function initMonthlyPayments () {
}
}
-function initGroupProfile (contractID: string) {
+function initGroupProfile (contractID: string, joined: ?string) {
return {
contractID: contractID,
- nonMonetaryContributions: []
+ nonMonetaryContributions: [],
+ joinedDate: joined
}
}
@@ -149,6 +150,19 @@ DefineContract({
groupMembersCount (state, getters) {
return getters.groupMembersByUsername.length
},
+ groupMembersPending (state, getters) {
+ const invites = getters.currentGroupState.invites
+ const pendingMembers = {}
+ for (const inviteId in invites) {
+ const invite = invites[inviteId]
+ if (invite.status === INVITE_STATUS.VALID && invite.creator !== INVITE_INITIAL_CREATOR) {
+ pendingMembers[invites[inviteId].invitee] = {
+ invitedBy: invites[inviteId].creator
+ }
+ }
+ }
+ return pendingMembers
+ },
groupShouldPropose (state, getters) {
return getters.groupMembersCount >= 3
},
@@ -199,7 +213,7 @@ DefineContract({
groupCreator: meta.username
},
profiles: {
- [meta.username]: initGroupProfile(meta.identityContractID)
+ [meta.username]: initGroupProfile(meta.identityContractID, meta.createdDate)
},
userPaymentsByMonth: {
[currentMonthTimestamp()]: initMonthlyPayments()
@@ -436,7 +450,7 @@ DefineContract({
if (Object.keys(invite.responses).length === invite.quantity) {
invite.status = INVITE_STATUS.USED
}
- Vue.set(state.profiles, meta.username, initGroupProfile(meta.identityContractID))
+ Vue.set(state.profiles, meta.username, initGroupProfile(meta.identityContractID, meta.createdDate))
// If we're triggered by handleEvent in state.js (and not latestContractState)
// then the asynchronous sideEffect function will get called next
// and we will subscribe to this new user's identity contract
diff --git a/frontend/views/components/Avatar.vue b/frontend/views/components/Avatar.vue
index 9fa64cb8f4..1d78d57926 100644
--- a/frontend/views/components/Avatar.vue
+++ b/frontend/views/components/Avatar.vue
@@ -1,11 +1,13 @@
img.c-avatar(
+ v-if='imageURL'
:class='`is-${size}`'
:src='imageURL'
:alt='alt'
ref='img'
v-on='$listeners'
)
+ .c-avatar.is-empty(v-else :class='`is-${size}`')
diff --git a/frontend/views/containers/payments/PaymentsList.vue b/frontend/views/containers/payments/PaymentsList.vue
index 76fde69626..1bf7b2a24f 100644
--- a/frontend/views/containers/payments/PaymentsList.vue
+++ b/frontend/views/containers/payments/PaymentsList.vue
@@ -29,7 +29,7 @@ table.table.table-in-card.c-payments(:class='{"is-editing": paymentsType === "ed
// TODO: replace condition to indicate whether or not the payment date is < or > than the current date using payment.paymentStatusText
i18n.c-user-month(
- :class='index === 0 ? "has-text-1" : "pill is-danger is-small"'
+ :class='index === 0 ? "has-text-1" : "pill is-danger"'
:args='{date: moment(payment.date).format("MMMM DD")}'
) Due {date}
td.c-payments-amount(v-if='paymentsType !== "edit"')
@@ -44,7 +44,7 @@ table.table.table-in-card.c-payments(:class='{"is-editing": paymentsType === "ed
:args='{partial_amount: `${currency(20)}`, partial_total: currency(payment.amount)}'
) {partial_amount} out of {partial_total}
- i18n.pill.is-primary.is-small Partial
+ i18n.pill.is-primary Partial
strong(v-else) {{currency(payment.amount)}}
@@ -62,12 +62,12 @@ table.table.table-in-card.c-payments(:class='{"is-editing": paymentsType === "ed
.button.is-icon-smaller.c-tip
i.icon-info
- i18n.pill.is-warning.is-small Not received
+ i18n.pill.is-warning Not received
td
.c-actions
- .c-actions-month(:class='!(index !== 0 && paymentsType === "todo") ? "has-text-1" : "pill is-danger is-small"') {{ moment(payment.date).format('MMMM D') }}
- payments-list-menu(
+ .c-actions-month(:class='!(index !== 0 && paymentsType === "todo") ? "has-text-1" : "pill is-danger"') {{ moment(payment.date).format('MMMM D') }}
+ payments-list-menu.c-actions-menu(
v-if='paymentsType !== "edit"'
:payment='payment'
:paymentsType='paymentsType'
@@ -258,6 +258,11 @@ export default {
.c-actions-month {
margin-left: 0;
+ white-space: nowrap;
+}
+
+.c-actions-menu {
+ margin-left: 1rem;
}
.c-name {
diff --git a/frontend/views/pages/DesignSystem.vue b/frontend/views/pages/DesignSystem.vue
index 22d7ff5d97..85338cd480 100644
--- a/frontend/views/pages/DesignSystem.vue
+++ b/frontend/views/pages/DesignSystem.vue
@@ -495,9 +495,9 @@ page(
th demo
tr
td
- pre .pill.has-background-dark
+ pre .pill.is-neutral
td
- span.pill.has-background-dark Pending
+ span.pill.is-neutral Pending
tr
td
@@ -523,36 +523,6 @@ page(
td
span.pill.is-danger Due march 08
- tr
- td
- pre .pill.has-background-dark.is-small
- td
- span.pill.has-background-dark.is-small Pending
-
- tr
- td
- pre .pill.is-success.is-small
- td
- span.pill.is-success.is-small Payment received
-
- tr
- td
- pre .pill.is-warning.is-small
- td
- span.pill.is-warning.is-small Not received
-
- tr
- td
- pre .pill.is-primary.is-small
- td
- span.pill.is-primary.is-small Partial
-
- tr
- td
- pre .pill.is-danger.is-small
- td
- span.pill.is-danger.is-small Due march 08
-
article#user-feedback
section.card
h2.is-title-2.card-header Feedback Banners
diff --git a/test/cypress/integration/group-large.spec.js b/test/cypress/integration/group-large.spec.js
index 437e10d112..0e159db4f0 100644
--- a/test/cypress/integration/group-large.spec.js
+++ b/test/cypress/integration/group-large.spec.js
@@ -34,16 +34,13 @@ describe('Large group', () => {
})
}
- cy.giLogin(`user1-${userId}`)
+ cy.giLogin(`user1-${userId}`, { bypassUI: true })
cy.giAddRandomIncome()
cy.get('.graph-bar')
.should('have.length', groupLength)
- cy.giLogout()
})
it('A search for "user1" should display 4 members', () => {
- cy.visit('/')
- cy.giLogin(`user1-${userId}`)
cy.getByDT('seeAllMembers').click()
cy.getByDT('memberCount')
.should('contain', '12 members')
diff --git a/test/cypress/integration/group-proposals.spec.js b/test/cypress/integration/group-proposals.spec.js
index e8d210801c..852dba84f4 100644
--- a/test/cypress/integration/group-proposals.spec.js
+++ b/test/cypress/integration/group-proposals.spec.js
@@ -163,6 +163,15 @@ describe('Proposals - Add members', () => {
cy.getByDT('sendLink').should('not.exist') // Only visible to who created the proposal
})
})
+
+ cy.log(`${username} is part of members list as "pending"`)
+
+ cy.getByDT('groupMembers').find('ul').within(() => {
+ cy.getByDT(`${username}-${userId}`, 'li').within(() => {
+ cy.getByDT('username').should('contain', `${username}-${userId}`)
+ cy.getByDT('pillPending').should('contain', 'pending')
+ })
+ })
}
voteForAndIsAccepted(0, 'user4')
@@ -239,7 +248,16 @@ describe('Proposals - Add members', () => {
cy.giSignup(`user4-${userId}`, { bypassUI: true })
cy.giAcceptGroupInvite(invitationLinks.user4, {
isLoggedIn: true,
- groupName
+ groupName,
+ actionBeforeLogout: () => {
+ cy.log('"New" tag does not appear for previous members')
+ cy.getByDT('groupMembers').find('ul > li')
+ .each(([member], index) => {
+ cy.get(member).within(() => {
+ cy.getByDT('pillNew').should('not.exist')
+ })
+ })
+ }
})
})
@@ -273,7 +291,7 @@ describe('Proposals - Add members', () => {
cy.getByDT('welcomeHome').should('contain', 'Welcome to GroupIncome')
})
- it('user1 logins and sees all 5 proposals correctly and the new member', () => {
+ it('user1 logins and sees all 5 proposals correctly and the new members', () => {
cy.giLogin(`user1-${userId}`, { bypassUI: true })
// A quick checkup that each proposal state is correct.
@@ -327,7 +345,14 @@ describe('Proposals - Add members', () => {
.each(([member], index) => {
cy.get(member).within(() => {
const usersMap = [1, 2, 3, 4, 6]
+
cy.getByDT('username').should('contain', `user${usersMap[index]}-${userId}`)
+
+ if (index === 0) {
+ cy.getByDT('username').should('contain', '(you)')
+ } else {
+ cy.getByDT('pillNew').should('contain', 'new')
+ }
})
})