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

Feature/open budgets #58

Merged
merged 6 commits into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 54 additions & 10 deletions _index.html
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@
<a href="/" data-translate-id="back">Back</a>
</div>
<div class="visible-on-mobile">
<a id="participants-list-btn" data-translate-id="participants-list-button">Participants</a>
<a id="settings-btn" data-translate-id="settings-button">Settings</a>
</div>
</div>
<h4 class="budget-details__title"></h4>
<div class="budget-details__counters">
<div class="budget-details__counter-wrapper">
<span class="budget-details__counter budget-details__counter--my"></span>
Expand All @@ -145,6 +146,10 @@
<button class="budget-details__action btn-warning" id="decline-invite"
data-translate-id="budget-details-actions-decline">Decline</button>
</div>
<p class="text-muted budget-details__actions--isopen"
data-translate-id="budget-details-actions-open-notification">
This budget is open. Your request will be automatically approved.
</p>
<div class="budget-details__actions budget-details__actions--ask">
<span data-translate-id="budget-details-actions-ask">You can ask for invite</span>
<button class="budget-details__action btn-secondary" id="ask-invite"
Expand All @@ -157,15 +162,46 @@
</div>
<aside class="budget-details__aside">
<div class="visible-on-mobile">
<a id="participants-list-close-btn" data-translate-id="close">Close</a>
<a id="settings-close-btn" data-translate-id="close">Close</a>
</div>
<div class="budget-details__participants"></div>
<div class="budget-details__actions budget-details__actions--send-invite">
<button id="send-invite" class="budget-details__action button"
data-translate-id="budget-details-add-people">Add people</button>
<div class="row flex-spaces tabs">
<input id="tab1" type="radio" name="tabs" checked>
<label for="tab1" data-translate-id="participants-list-button">Participants</label>

<input id="tab2" type="radio" name="tabs">
<label for="tab2" data-translate-id="settings-btn">Settings</label>

<div class="content" id="content1">
<div class="budget-details__tab-content-wrapper">
<div class="budget-details__participants"></div>
<div class="budget-details__actions budget-details__actions--send-invite">
<button id="send-invite" class="budget-details__action button"
data-translate-id="budget-details-add-people">Add people</button>
</div>
</div>
</div>
<div class="content budget-details__settings" id="content2">
</div>
</div>
</aside>
</template>

<template id="budget-settings-template">
<form id="budget-settings" class="budget-settings">
<div class="budget-settings__fields">
<div class="flex col">
<div class="flex row flex-edges">
<label for="opened" data-translate-id="budget-details-settings-open">Open</label>
<input type="checkbox" name="opened" id="opened" />
</div>
<h6 class="text-muted" data-translate-id="budget-settings-isOpen">
In open budgets participation requests are being approved automatically.
</h6>
</div>
</div>
<button class="budget-settings__save-btn button" disabled data-translate-id="budget-settings-save-btn">Save</button>
</form>
</template>

<template id="transactions-list-template">
<div id="transactions-list">
Expand Down Expand Up @@ -244,7 +280,7 @@ <h2 class="layout-login__prompt-detail" data-translate-id="layout-login-descript
<input type="text" name="name" autocomplete="off" autofocus required minlength="3" maxlength="20"
title="Only letters, digits and a space" placeholder="Budget's name"
data-translate-id="new-budget-title" data-translate-prop="placeholder" />
<strong data-translate-id="new-budget-currency">Select currency</strong>
<h4 data-translate-id="new-budget-currency">Select currency</h4>
<select name="currency" id="currency">
<option value="RUB" data-translate-id="currency-rub">Russian Rouble</option>
<option value="INR" data-translate-id="currency-inr">Indian Rupee</option>
Expand All @@ -253,13 +289,21 @@ <h2 class="layout-login__prompt-detail" data-translate-id="layout-login-descript
<option value="CNY" data-translate-id="currency-cny">Chinese Yuan</option>
<option value="JRD" data-translate-id="currency-jrd">Jordanian Dinar</option>
</select>
<strong data-translate-id="new-budget-suggested-participants">Suggested participants</strong>
<h4 data-translate-id="new-budget-suggested-participants">Suggested participants</h4>
<div class="new-budget__suggested-participants">
<div class="new-budget__suggested-participants-item">
<label for=""></label>
<div class="new-budget__suggested-participants-item new-budget__field--checkbox">
<input type="checkbox" name="" id="" />
<label for=""></label>
</div>
</div>
<h4 data-translate-id="new-budget-type">Budget type</h4>
<h6 class="text-muted" data-translate-id="new-budget-is-open-notice">
If you turn this setting on, any participation requests will be automatically approved.
</h6>
<div class="new-budget__field--checkbox">
<input type="checkbox" name="isOpen" id="isOpen" />
<label for="isOpen" data-translate-id="new-budget-is-open">Make this budget open</label>
</div>
</div>
<div class="new-budget__buttons">
<button type="submit" data-translate-id="new-budget-go">Go</button>
Expand Down
30 changes: 28 additions & 2 deletions src/containers/BudgetDetails/BudgetDetails.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,17 @@
opacity: 0;
}

.budget-details__counters {
.budget-details__counters,
.budget-details__title {
display: flex;
justify-content: center;
flex-wrap: wrap;
}

.budget-details__title {
margin: 0.25rem;
}

.budget-details__counter-wrapper {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -80,8 +85,24 @@
margin: 0 auto;
}

.budget-details__participants {
.budget-details__aside .tabs {
flex-grow: 1;
margin-bottom: 0;
width: 100%;
}
.budget-details__aside .tabs label {
align-self: baseline;
}
.budget-details__aside .content {
align-self: flex-start;
height: 100%;
}

.budget-details__tab-content-wrapper {
display: flex;
flex-direction: column;
justify-content: space-between;
height: calc(100% - 2.75rem);
}

#budget-details #send-invite {
Expand All @@ -95,6 +116,11 @@
display: none;
}

.budget-details__actions--isopen {
justify-content: center;
display: none;
}

.budget-details__actions--visible {
display: flex;
}
Expand Down
38 changes: 26 additions & 12 deletions src/containers/BudgetDetails/BudgetDetails.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import { Alert } from "../Alert/Alert.mjs";
import { ParticipantsList } from "../ParticipantsList/ParticipantsList.mjs";
import { FeatureDetector } from "../../core/FeatureDetector.mjs";
import { Router } from '../../core/Router.mjs'
import { BudgetSettings } from "./components/Settings/BudgetSettings.mjs";

importStyle('/src/containers/BudgetDetails/BudgetDetails.css')

const template = document.querySelector('template#budget-details-template')
const Api = new RequestManager('budget')
const transactionsController = new TransactionsList()
const participantsController = new ParticipantsList()
const settingsController = new BudgetSettings()

const isMobile = FeatureDetector.isMobile

Expand Down Expand Up @@ -46,11 +48,11 @@ export class BudgetDetails extends AnimatedComponent {
transactionsController.data = mapArrayToObjectId(this.data?.transactions ?? [])
participantsController.data = mapArrayToObjectId(this.data?.participants ?? [], ({ userId }) => userId)
const data = await Api.get('details', `budgets/${id}`)
this.data = data
this.data = data
transactionsController.data = mapArrayToObjectId(data?.transactions ?? [])
participantsController.data = mapArrayToObjectId(data?.participants ?? [], ({ userId }) => userId)

if (this.data?.participants.length === 1 && Router.queryParams.has('fresh')) { // only the owner
if (this.data?.participants?.length === 1 && Router.queryParams.has('fresh')) { // only the owner
this.showInviteDialog()
}
}
Expand Down Expand Up @@ -96,8 +98,9 @@ export class BudgetDetails extends AnimatedComponent {
const container = template.content.cloneNode(true)
this.update(container)
parent.appendChild(container)
transactionsController.renderTo(this.getContainer()?.querySelector('.budget-details__transactions'))
participantsController.renderTo(this.getContainer()?.querySelector('.budget-details__participants'))
transactionsController.renderTo(this.getContainer()?.querySelector(`.${this.getCssClass('transactions')}`))
participantsController.renderTo(this.getContainer()?.querySelector(`.${this.getCssClass('participants')}`))
settingsController.renderTo(this.getContainer()?.querySelector(`.${this.getCssClass('settings')}`))
}

update = (target) => {
Expand All @@ -117,12 +120,17 @@ export class BudgetDetails extends AnimatedComponent {
this.addCssClassConditionally(
!allowedUserStatuses.includes(this.data?.currentUserStatus),
'hidden',
container.querySelector('#participants-list-btn')
container.querySelector('#settings-btn')
)
}

const { myBalance, totalBalance } = getBudgetBalanceFromTransactions(this.data.transactions, this.data.participants)
this.setAttr(container, `.${this.getCssClass('counter', 'my')}`, 'textContent', currencyFormatters.get(this.data.currency)?.format(Math.abs(myBalance)))
this.setAttr(container, `.${this.getCssClass('counter', 'my')}`, 'textContent', currencyFormatters.get(this.data.currency)?.format(Math.abs(myBalance)))
this.addCssClassConditionally(
!allowedUserStatuses.includes(this.data?.currentUserStatus) && this.data?.type === 'open',
'hidden',
container.querySelector(`.${this.getCssClass('counter', 'my')}`).parentElement
)
this.addCssClassConditionally(
myBalance > 0,
this.getCssClass('counter', 'positive'),
Expand All @@ -134,7 +142,13 @@ export class BudgetDetails extends AnimatedComponent {
container.querySelector(`.${this.getCssClass('counter', 'my')}`)
)
this.setAttr(container, `.${this.getCssClass('counter', 'total')}`, 'textContent', currencyFormatters.get(this.data.currency)?.format(totalBalance))
this.setAttr(container, `.${this.getCssClass('title')}`, 'textContent', this.data.name)

this.addCssClassConditionally(
!allowedUserStatuses.includes(this.data?.currentUserStatus) && this.data?.type === 'open',
this.getCssClass('actions', 'visible'),
container.querySelector(`.${this.getCssClass('actions', 'isopen')}`)
)
this.addCssClassConditionally(
this.data?.currentUserStatus === PARTICIPANT_STATUSES.INVITED,
this.getCssClass('actions', 'visible'),
Expand Down Expand Up @@ -222,7 +236,7 @@ export class BudgetDetails extends AnimatedComponent {
}
}

onShowParticipants = (e) => {
onShowSettings = (e) => {
e.stopPropagation()
this.addCssClassConditionally(
isMobile,
Expand All @@ -231,7 +245,7 @@ export class BudgetDetails extends AnimatedComponent {
)
}

onHideParticipants = (e) => {
onHideSettings = (e) => {
e.stopPropagation()
this.getContainer()?.querySelector(`.${this.getCssClass('aside')}`)?.classList.remove(
this.getCssClass('aside', 'visible')
Expand Down Expand Up @@ -260,14 +274,14 @@ export class BudgetDetails extends AnimatedComponent {
handler: this.showInviteDialog,
},
{
selector: '#participants-list-btn',
selector: '#settings-btn',
event: 'click',
handler: this.onShowParticipants,
handler: this.onShowSettings,
},
{
selector: '#participants-list-close-btn',
selector: '#settings-close-btn',
event: 'click',
handler: this.onHideParticipants,
handler: this.onHideSettings,
},
])
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.budget-settings {
min-height: calc(100% - 2.75rem);
display: flex;
flex-direction: column;
}
.budget-settings input {
display: initial;
}
.budget-settings input:checked + label {
border-bottom: 0;
}
.budget-settings label {
font-size: inherit;
font-weight: initial;
color: initial;
padding: 0;
flex-grow: 1;
text-align: left;
}
html[dir=rtl] .budget-settings label {
text-align: right;
}
.budget-settings__fields {
flex-grow: 1;
}
.budget-settings__save-btn {
width: 100%;
}
Loading