Skip to content

Commit

Permalink
Merge pull request #677 from bcgov/feature/genericCard
Browse files Browse the repository at this point in the history
Tenant UI main component card refactoring
  • Loading branch information
loneil committed Jun 30, 2023
2 parents 6f5cb57 + f32bb61 commit 8d6013b
Show file tree
Hide file tree
Showing 44 changed files with 2,051 additions and 2,017 deletions.
471 changes: 246 additions & 225 deletions services/tenant-ui/frontend/package-lock.json

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions services/tenant-ui/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@
},
"dependencies": {
"@intlify/unplugin-vue-i18n": "^0.11.0",
"@vuelidate/core": "^2.0.2",
"@vuelidate/validators": "^2.0.2",
"@vuelidate/core": "^2.0.3",
"@vuelidate/validators": "^2.0.3",
"axios": "^1.4.0",
"date-fns": "^2.29.3",
"dompurify": "^3.0.3",
"dompurify": "^3.0.4",
"json-editor-vue": "^0.10.6",
"marked": "^5.0.4",
"marked": "^5.1.0",
"oidc-client-ts": "^2.2.3",
"pinia": "^2.0.35",
"pinia": "^2.1.4",
"primeflex": "^3.3.1",
"primeicons": "^6.0.1",
"primevue": "^3.29.2",
"qrcode.vue": "^3.4.0",
"vanilla-jsoneditor": "^0.17.1",
"vanilla-jsoneditor": "^0.17.8",
"vue": "^3.3.1",
"vue-i18n": "^9.2.2",
"vue-json-pretty": "^2.2.4",
Expand All @@ -41,24 +41,24 @@
"@intlify/eslint-plugin-vue-i18n": "^2.0.0",
"@types/dompurify": "^3.0.2",
"@types/marked": "^5.0.0",
"@typescript-eslint/eslint-plugin": "^5.59.8",
"@typescript-eslint/parser": "^5.59.8",
"@typescript-eslint/eslint-plugin": "^5.60.1",
"@typescript-eslint/parser": "^5.60.1",
"@vitejs/plugin-vue": "^4.2.2",
"@vitest/coverage-c8": "^0.31.4",
"@vitest/coverage-c8": "^0.32.2",
"@vue/eslint-config-prettier": "^7.1.0",
"@vue/eslint-config-typescript": "^11.0.3",
"@vue/test-utils": "^2.3.2",
"eslint": "^8.39.0",
"@vue/test-utils": "^2.4.0",
"eslint": "^8.43.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.14.1",
"eslint-plugin-vue": "^9.15.1",
"flat": "^5.0.2",
"glob": "^10.2.3",
"glob": "^10.3.1",
"jsdom": "^22.1.0",
"prettier": "^2.8.8",
"sass": "^1.62.1",
"typescript": "^5.1.3",
"sass": "^1.63.6",
"typescript": "^5.1.6",
"vite": "^4.3.9",
"vitest": "^0.31.4",
"vue-tsc": "^1.6.1"
"vitest": "^0.32.2",
"vue-tsc": "^1.8.3"
}
}
256 changes: 256 additions & 0 deletions services/tenant-ui/frontend/src/components/connections/Connections.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
<template>
<MainCardContent
:title="$t('connect.connections.connections')"
:refresh-callback="loadTable"
>
<DataTable
v-model:expandedRows="expandedRows"
v-model:filters="filter"
:loading="loading"
:value="formattedConnections"
:paginator="true"
:rows="TABLE_OPT.ROWS_DEFAULT"
:rows-per-page-options="TABLE_OPT.ROWS_OPTIONS"
:global-filter-fields="['alias']"
selection-mode="single"
data-key="connection_id"
sort-field="created_at"
:sort-order="-1"
filter-display="menu"
>
<template #header>
<div class="flex justify-content-between">
<div class="flex justify-content-start">
<AcceptInvitation />
<DidExchange class="ml-4" />
</div>
<div class="flex justify-content-end">
<span class="p-input-icon-left">
<i class="pi pi-search" />
<InputText
v-model="filter.alias.value"
:placeholder="$t('connect.connections.search')"
/>
</span>
</div>
</div>
</template>
<template #empty>{{ $t('common.noRecordsFound') }}</template>
<template #loading>{{ $t('common.loading') }}</template>
<Column :expander="true" header-style="width: 3rem" />
<Column :sortable="false" :header="$t('common.actions')">
<template #body="{ data }">
<MessageContact
:connection-id="data.connection_id"
:connection-name="data.alias"
/>
<Button
title="Delete Contact"
icon="pi pi-trash"
class="p-button-rounded p-button-icon-only p-button-text"
:disabled="deleteDisabled(data.alias)"
@click="deleteContact($event, data.connection_id)"
/>
<EditContact :connection-id="data.connection_id" />
</template>
</Column>
<Column
:sortable="true"
field="alias"
:header="$t('common.alias')"
filter-field="alias"
:show-filter-match-modes="false"
>
<template #filter="{ filterModel, filterCallback }">
<InputText
v-model="filterModel.value"
type="text"
class="p-column-filter"
placeholder="Search By Alias"
@input="filterCallback()"
/>
</template>
</Column>
<Column
:sortable="true"
field="their_label"
filter-field="their_label"
:header="$t('connect.table.theirLabel')"
:show-filter-match-modes="false"
>
<template #filter="{ filterModel, filterCallback }">
<InputText
v-model="filterModel.value"
type="text"
class="p-column-filter"
placeholder="Search By Label"
@input="filterCallback()"
/>
</template>
</Column>
<Column
:sortable="true"
field="state"
:header="$t('common.status')"
filter-field="state"
:show-filter-match-modes="false"
>
<template #body="{ data }">
<StatusChip :status="data.state" />
</template>
<template #filter="{ filterModel, filterCallback }">
<InputText
v-model="filterModel.value"
type="text"
class="p-column-filter"
placeholder="Search By State"
@input="filterCallback()"
/>
</template>
</Column>
<Column
:sortable="true"
field="created"
:header="$t('connect.table.createdAt')"
filter-field="created"
:show-filter-match-modes="false"
>
<template #body="{ data }">
{{ data.created }}
</template>
<template #filter="{ filterModel, filterCallback }">
<InputText
v-model="filterModel.value"
type="text"
class="p-column-filter"
placeholder="Search By Date"
@input="filterCallback()"
/>
</template>
</Column>
<template #expansion="{ data }">
<RowExpandData :id="data.connection_id" :url="API_PATH.CONNECTIONS" />
</template>
</DataTable>
</MainCardContent>
</template>

<script setup lang="ts">
// Vue
import { onMounted, ref, Ref, computed } from 'vue';
import { FilterMatchMode } from 'primevue/api';
// PrimeVue
import Button from 'primevue/button';
import Column from 'primevue/column';
import DataTable from 'primevue/datatable';
import InputText from 'primevue/inputtext';
import { useConfirm } from 'primevue/useconfirm';
import { useToast } from 'vue-toastification';
// State
import { useContactsStore, useTenantStore } from '@/store';
import { storeToRefs } from 'pinia';
// Other components
import AcceptInvitation from './acceptInvitation/AcceptInvitation.vue';
import DidExchange from './didExchange/DidExchange.vue';
import EditContact from './editContact/EditContact.vue';
import MainCardContent from '../layout/mainCard/MainCardContent.vue';
import MessageContact from './messageContact/MessageContact.vue';
import RowExpandData from '../common/RowExpandData.vue';
import StatusChip from '../common/StatusChip.vue';
import { TABLE_OPT, API_PATH } from '@/helpers/constants';
import { formatDateLong } from '@/helpers';
const confirm = useConfirm();
const toast = useToast();
const contactsStore = useContactsStore();
const tenantStore = useTenantStore();
const { loading, filteredConnections } = storeToRefs(useContactsStore());
const { endorserInfo } = storeToRefs(useTenantStore());
const loadTable = async () => {
contactsStore.listContacts().catch((err) => {
console.error(err);
toast.error(`Failure: ${err}`);
});
};
onMounted(async () => {
// So we can check endorser connection
tenantStore.getEndorserInfo();
// Load your contact list
loadTable();
});
// Deleting a contact
const deleteContact = (event: any, id: string) => {
confirm.require({
target: event.currentTarget,
message: 'Are you sure you want to delete this connection?',
header: 'Confirmation',
icon: 'pi pi-exclamation-triangle',
accept: () => {
doDelete(id);
},
});
};
const doDelete = (id: string) => {
contactsStore
.deleteContact(id)
.then(() => {
toast.success(`Connection successfully deleted`);
})
.catch((err) => {
console.error(err);
toast.error(`Failure: ${err}`);
});
};
// Can't delete if it's endorser
const deleteDisabled = (contactAlias: string) => {
return (
endorserInfo.value != null &&
endorserInfo.value.endorser_name === contactAlias
);
};
// The formatted table row
const formattedConnections: Ref<any[]> = computed(() =>
filteredConnections.value.map((conn) => ({
connection_id: conn.connection_id,
alias: conn.alias,
their_label: conn.their_label,
state: conn.state,
created: formatDateLong(conn.created_at as string),
created_at: conn.created_at,
}))
);
// necessary for expanding rows, we don't do anything with this
const expandedRows = ref([]);
const filter = ref({
alias: {
value: null,
matchMode: FilterMatchMode.CONTAINS,
},
created: {
value: null,
matchMode: FilterMatchMode.CONTAINS,
},
their_label: {
value: null,
matchMode: FilterMatchMode.CONTAINS,
},
state: {
value: null,
matchMode: FilterMatchMode.CONTAINS,
},
});
</script>

<style scoped>
.create-contact {
float: right;
margin: 3rem 1rem 0 0;
}
</style>
Loading

0 comments on commit 8d6013b

Please sign in to comment.