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

src/components/coordinator: add component TableFeeApproval for coordinator page #444

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
131 changes: 131 additions & 0 deletions src/components/__tests__/TableFeeApproval.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// import { date } from 'quasar';
import TableFeeApproval from 'components/coordinator/TableFeeApproval.vue';
import { i18n } from '../../boot/i18n';
import tableFeeApproval from '../../../test/cypress/fixtures/tableFeeApproval.json';

// const { formatDate } = date;

// sort order
const dataByAmountAsc = [
tableFeeApproval[1],
tableFeeApproval[0],
tableFeeApproval[2],
tableFeeApproval[5],
tableFeeApproval[3],
tableFeeApproval[4],
]
const dataByAmountDesc = [
tableFeeApproval[4],
tableFeeApproval[3],
tableFeeApproval[5],
tableFeeApproval[2],
tableFeeApproval[0],
tableFeeApproval[1],
]
const dataByDateDesc = [
tableFeeApproval[5],
tableFeeApproval[4],
tableFeeApproval[3],
tableFeeApproval[2],
tableFeeApproval[1],
tableFeeApproval[0],
]

describe('<TableFeeApproval>', () => {
it('has translation for all strings', () => {
cy.testLanguageStringsInContext(
[
'buttonFeeApproval',
'labelAmount',
'labelDateRegistered',
'labelEmail',
'labelName',
'labelNickname',
'labelTeam',
'textEmptyTable',
'titleFeeApproval',
],
'table',
i18n,
);
});

context('desktop', () => {
beforeEach(() => {
cy.fixture('tableFeeApproval').then((rows) => {
cy.wrap(rows).as('rows');
cy.mount(TableFeeApproval, {
props: {},
});
cy.viewport('macbook-16');
});
});

coreTests();
});

context('mobile', () => {
beforeEach(() => {
cy.fixture('tableFeeApproval').then((rows) => {
cy.wrap(rows).as('rows');
cy.mount(TableFeeApproval, {
props: {},
});
cy.viewport('iphone-6');
});
});

coreTests();
});
});

function coreTests() {
it('renders component', () => {
// component
cy.dataCy('table-fee-approval').should('be.visible');
// title
cy.dataCy('table-fee-approval-title')
.should('be.visible')
.and('contain', i18n.global.t('table.titleFeeApproval'));
// button
cy.dataCy('table-fee-approval-button')
.should('be.visible')
.and('contain', i18n.global.t('table.buttonFeeApproval'));
});

it('sorts correctly by team', () => {
cy.get('@rows').then(rows => {
// default sorting by date ascending
cy.dataCy('table-fee-approval')
.find('.data-row')
.should('have.length', 5)
.each((tableRow, index) => {
cy.wrap(tableRow).should('contain', rows[index].email)
})
// sorting by date descending
cy.dataCy('table-fee-approval').find('th.sortable').last().click()
cy.dataCy('table-fee-approval')
.find('.data-row')
.should('have.length', 5)
.each((tableRow, index) => {
cy.wrap(tableRow).should('contain', dataByDateDesc[index].email)
})
// sorting by amount ascending
cy.dataCy('table-fee-approval').find('th.sortable').first().click()
cy.dataCy('table-fee-approval')
.find('.data-row')
.should('have.length', 5)
.each((tableRow, index) => {
cy.wrap(tableRow).should('contain', dataByAmountAsc[index].email)
})
// sorting by amount descending
cy.dataCy('table-fee-approval').find('th.sortable').first().click()
cy.dataCy('table-fee-approval')
.find('.data-row')
.should('have.length', 5)
.each((tableRow, index) => {
cy.wrap(tableRow).should('contain', dataByAmountDesc[index].email)
})
});
});
}
128 changes: 128 additions & 0 deletions src/components/coordinator/TableFeeApproval.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<script lang="ts">
/**
* TableFeeApproval Component
*
* @description * Use this component to display a table with fee payments for
* approval.
* Shown on `CompanyCoordinatoFees` page.
*
* @example
* <table-fee-approval />
*
* @see [Figma Design](https://www.figma.com/design/L8dVREySVXxh3X12TcFDdR/Do-pr%C3%A1ce-na-kole?node-id=4858-104283&t=MqCoIBTXNV4xkXVk-1)
*/

// libraries
import { QTable } from 'quasar';
import { defineComponent, onMounted, ref } from 'vue';

// composables
import { useTable, useTableFeeApproval } from '../../composables/useTable';

// fixtures
import tableFeeApproval from '../../../test/cypress/fixtures/tableFeeApproval.json';

export default defineComponent({
name: 'TableFeeApproval',

setup() {
// holds an array of currently selected rows
const selected = ref([]);
const tableRef = ref<QTable | null>(null);
onMounted(() => {
if (tableRef.value) {
tableRef.value.sort('dateCreated');
}
})

const { columns, visibleColumns } = useTableFeeApproval();
const { sortByTeam } = useTable();

return {
columns,
selected,
tableFeeApproval,
tableRef,
visibleColumns,
sortByTeam,
};
},
});
</script>

<template>
<div class="q-pa-md" data-cy="table-fee-approval">
<div>
<!-- Title -->
<h3
class="text-body1 text-bold text-black q-my-none"
data-cy="table-fee-approval-title"
>
{{ $t('table.titleFeeApproval') }}
</h3>
</div>
<div class="q-my-lg">
<!-- Table -->
<q-table
ref="tableRef"
flat
bordered
binary-state-sort
:rows="tableFeeApproval"
:columns="columns"
:visible-columns="visibleColumns"
row-key="name"
:sort-method="sortByTeam"
selection="multiple"
v-model:selected="selected"
:style="{ 'border-radius': '8px' }"
>
<template v-slot:body="props">
<q-tr v-if="props.row.isFirst" class="bg-blue-grey-2">
<q-td colspan="7" class="text-weight-bold">
{{ props.row.team }}
</q-td>
</q-tr>
<q-tr :props="props" class="data-row">
<q-td>
<q-checkbox v-model="props.selected" color="primary" />
</q-td>
<q-td key="amount" :props="props">
{{ props.row.amount }}
</q-td>
<q-td key="name" :props="props">
{{ props.row.name }}
</q-td>
<q-td key="email" :props="props">
{{ props.row.email }}
</q-td>
<q-td key="nickname" :props="props">
{{ props.row.nickname }}
</q-td>
<q-td key="team" :props="props">
{{ props.row.team }}
</q-td>
<q-td key="dateCreated" :props="props">
<!-- Custom loop to get formatted content -->
<template v-for="col in props.cols" :key="col.field">
<span v-if="col.field === 'dateCreated'">
{{ col.value }}
</span>
</template>
</q-td>
</q-tr>
</template>
</q-table>
</div>
<div class="q-mt-lg text-right">
<!-- Button -->
<q-btn
rounded
unelevated
:label="$t('table.buttonFeeApproval')"
color="primary"
data-cy="table-fee-approval-button"
/>
</div>
</div>
</template>
2 changes: 1 addition & 1 deletion src/components/types/Table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ export type TableColumn = {
};

export type TableRow = {
[key: string]: number | string | null;
[key: string]: number | string | null | boolean;
};
Loading
Loading