Skip to content
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
2 changes: 1 addition & 1 deletion frontend/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ declare module '@vue/runtime-core' {
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElButton: typeof import('element-plus/es')['ElButton']
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
ElCard: typeof import('element-plus/es')['ElCard']
ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
/>

<app-empty-state-cta
v-else-if="hasOrganizations && !count"
v-else-if="hasOrganizations && !totalOrganizations"
icon="ri-community-line"
title="No organizations found"
description="We couldn't find any results that match your search criteria, please try a different query."
Expand All @@ -27,9 +27,9 @@
<!-- Sorter -->
<div class="mb-2">
<app-pagination-sorter
:page-size="Number(pagination.pageSize)"
:total="count"
:current-page="pagination.currentPage"
:page-size="Number(pagination.perPage)"
:total="totalOrganizations"
:current-page="pagination.page"
:has-page-counter="false"
module="organization"
position="top"
Expand All @@ -56,7 +56,6 @@
>
<div
:style="{
width: tableWidth,
height: '10px',
}"
/>
Expand All @@ -77,12 +76,13 @@
<el-table
id="organizations-table"
ref="table"
:data="rows"
:data="organizations"
:default-sort="defaultSort"
row-key="id"
border
:row-class-name="rowClass"
@sort-change="doChangeSort"
@selection-change="selectedOrganizations = $event"
>
<!-- Checkbox -->
<el-table-column
Expand Down Expand Up @@ -511,9 +511,9 @@
class="mt-8 px-6"
>
<app-pagination
:total="count"
:page-size="Number(pagination.pageSize)"
:current-page="pagination.currentPage || 1"
:total="totalOrganizations"
:page-size="Number(pagination.perPage)"
:current-page="pagination.page || 1"
module="organization"
@change-current-page="
doChangePaginationCurrentPage
Expand All @@ -539,14 +539,11 @@ import {
onUnmounted,
} from 'vue';
import { useRouter } from 'vue-router';
import {
mapState,
mapGetters,
mapActions,
} from '@/shared/vuex/vuex.helpers';
import { formatDateToTimeAgo } from '@/utils/date';
import { formatNumberToCompact } from '@/utils/number';
import { withHttp, toSentenceCase } from '@/utils/string';
import { useOrganizationStore } from '@/modules/organization/store/pinia';
import { storeToRefs } from 'pinia';
import AppOrganizationIdentities from '../organization-identities.vue';
import AppOrganizationListToolbar from './organization-list-toolbar.vue';
import AppOrganizationName from '../organization-name.vue';
Expand All @@ -565,16 +562,10 @@ const props = defineProps({
},
});

const { count, list } = mapState('organization');
const {
activeView, rows, pagination, selectedRows,
} = mapGetters('organization');
const organizationStore = useOrganizationStore();
const {
doChangePaginationCurrentPage,
doChangePaginationPageSize,
doChangeSort,
doMountTable,
} = mapActions('organization');
organizations, selectedOrganizations, filters, totalOrganizations,
} = storeToRefs(organizationStore);

const table = ref(null);
const scrollbarRef = ref();
Expand All @@ -584,17 +575,20 @@ const isScrollbarVisible = ref(false);
const isTableHovered = ref(false);
const isCursorDown = ref(false);

const pagination = computed(() => filters.value.pagination);

const defaultSort = computed(() => ({
field: filters.value.order.prop,
order: filters.value.order.order,
}));

const showBottomPagination = computed(() => (
!!count.value
!!totalOrganizations.value
&& Math.ceil(
count.value / Number(pagination.value.pageSize),
totalOrganizations.value / Number(filters.value.pagination.perPage),
) > 1
));
const tableWidth = computed(() => list.value.table?.bodyWidth);
const defaultSort = computed(() => activeView.value.sorter);
const isLoading = computed(
() => list.value.loading || props.isPageLoading,
);
const isLoading = computed(() => props.isPageLoading);

document.onmouseup = () => {
// As soon as mouse is released, set scrollbar visibility
Expand All @@ -603,14 +597,29 @@ document.onmouseup = () => {
isCursorDown.value = false;
};

function doChangeSort(sorter) {
filters.value.order = {
prop: sorter.prop,
order: sorter.order,
};
}

function doChangePaginationCurrentPage(currentPage) {
filters.value.pagination.page = currentPage;
}

function doChangePaginationPageSize(pageSize) {
filters.value.pagination.perPage = pageSize;
}

const onCtaClick = () => {
router.push({
name: 'organizationCreate',
});
};

const rowClass = ({ row }) => {
const isSelected = selectedRows.value.find((r) => r.id === row.id)
const isSelected = selectedOrganizations.value.find((r) => r.id === row.id)
!== undefined;

return isSelected ? 'is-selected' : '';
Expand Down Expand Up @@ -661,7 +670,7 @@ const onTableMouseLeft = () => {

const emailsColumnWidth = computed(() => {
let maxTabWidth = 0;
rows.value.forEach((row) => {
organizations.value.forEach((row) => {
const tabWidth = row.emails
?.map((email) => (email ? email.length * 12 : 0))
.reduce((a, b) => a + b, 0);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<template>
<div
v-if="selectedRows.length > 0"
v-if="selectedOrganizations.length > 0"
class="app-list-table-bulk-actions"
>
<span class="block text-sm font-semibold mr-4">
{{
pluralize('organization', selectedRows.length, true)
pluralize('organization', selectedOrganizations.length, true)
}}
selected
</span>
Expand All @@ -22,6 +22,7 @@
</el-dropdown-item>

<el-dropdown-item
v-if="markAsTeamOrganizationOptions"
:command="{
action: 'markAsTeamOrganization',
value: markAsTeamOrganizationOptions.value,
Expand Down Expand Up @@ -67,16 +68,24 @@ import pluralize from 'pluralize';
import { computed } from 'vue';
import {
mapGetters,
mapActions,
} from '@/shared/vuex/vuex.helpers';
import ConfirmDialog from '@/shared/dialog/confirm-dialog';
import Message from '@/shared/message/message';
import { OrganizationService } from '../../organization-service';
import { useOrganizationStore } from '@/modules/organization/store/pinia';
import { storeToRefs } from 'pinia';
import Errors from '@/shared/error/errors';
import { Excel } from '@/shared/excel/excel';
import { OrganizationPermissions } from '../../organization-permissions';
import { OrganizationService } from '../../organization-service';

const { currentUser, currentTenant } = mapGetters('auth');
const { selectedRows, activeView } = mapGetters('organization');
const { doExport, doDestroyAll, doFetch } = mapActions('organization');

const organizationStore = useOrganizationStore();
const {
selectedOrganizations,
filters,
} = storeToRefs(organizationStore);
const { fetchOrganizations } = organizationStore;

const isPermissionReadOnly = computed(
() => new OrganizationPermissions(
Expand All @@ -99,10 +108,10 @@ const isDeleteLockedForSampleData = computed(
);

const markAsTeamOrganizationOptions = computed(() => {
const isTeamView = activeView.value.id === 'team';
const isTeamView = filters.value.settings.teamOrganization === 'filter';
const organizationsCopy = pluralize(
'organization',
selectedRows.value.length,
selectedOrganizations.value.length,
false,
);

Expand All @@ -121,31 +130,63 @@ const markAsTeamOrganizationOptions = computed(() => {
};
});

const handleDoDestroyAllWithConfirm = async () => {
const handleDoDestroyAllWithConfirm = () => ConfirmDialog({
type: 'danger',
title: 'Delete organizations',
message:
"Are you sure you want to proceed? You can't undo this action",
confirmButtonText: 'Confirm',
cancelButtonText: 'Cancel',
icon: 'ri-delete-bin-line',
})
.then(() => {
const ids = selectedOrganizations.value.map((m) => m.id);
return OrganizationService.destroyAll(ids);
})
.then(() => fetchOrganizations({ reload: true }));

const handleDoExport = async () => {
try {
await ConfirmDialog({
type: 'danger',
title: 'Delete organizations',
message:
"Are you sure you want to proceed? You can't undo this action",
confirmButtonText: 'Confirm',
cancelButtonText: 'Cancel',
icon: 'ri-delete-bin-line',
});
const filter = {
id: {
in: selectedOrganizations.value.map((o) => o.id),
},
};

await doDestroyAll(
selectedRows.value.map((item) => item.id),
const response = await OrganizationService.list(
filter,
`${filters.value.order.prop}_${filters.value.order.order === 'descending' ? 'DESC' : 'ASC'}`,
null,
null,
false,
);
} catch (error) {
console.error(error);
}
};

const handleDoExport = async () => {
try {
await doExport();
Excel.exportAsExcelFile(
response.rows.map((o) => ({
Id: o.id,
Name: o.name,
Description: o.description,
Headline: o.headline,
Website: o.website,
'# of members': o.memberCount,
'# of activities': o.activityCount,
Location: o.location,
Created: o.createdAt,
Updated: o.updatedAt,
})),
['Id', 'Name', 'Description',
'Headline', 'Headline', '# of members',
'# of activities', 'Location', 'Created', 'Updated',
],
`organizations_${new Date().getTime()}`,
);

Message.success('Organizations exported successfully');
} catch (error) {
console.error(error);
Errors.handle(error);
Message.error(
'There was an error exporting organizations',
);
}
};

Expand All @@ -156,20 +197,20 @@ const handleCommand = async (command) => {
await handleDoDestroyAllWithConfirm();
} else if (command.action === 'markAsTeamOrganization') {
Promise.all(
selectedRows.value.map((row) => OrganizationService.update(row.id, {
selectedOrganizations.value.map((row) => OrganizationService.update(row.id, {
isTeamOrganization: command.value,
})),
).then(() => {
Message.success(
`${pluralize(
'Organization',
selectedRows.length,
selectedOrganizations.value.length,
false,
)} updated successfully`,
);

doFetch({
keepPagination: true,
fetchOrganizations({
reload: true,
});
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ import {
} from '@/shared/vuex/vuex.helpers';
import ConfirmDialog from '@/shared/dialog/confirm-dialog';
import Message from '@/shared/message/message';
import { useOrganizationStore } from '@/modules/organization/store/pinia';
import { i18n } from '@/i18n';
import { OrganizationPermissions } from '../organization-permissions';
import { OrganizationService } from '../organization-service';

Expand All @@ -110,7 +112,10 @@ defineProps({
});

const { currentUser, currentTenant } = mapGetters('auth');
const { doDestroy, doFetch, doFind } = mapActions('organization');
const { doFind } = mapActions('organization');

const organizationStore = useOrganizationStore();
const { fetchOrganizations } = organizationStore;

const isReadOnly = computed(
() => new OrganizationPermissions(
Expand Down Expand Up @@ -144,7 +149,14 @@ const doDestroyWithConfirm = async (id) => {
icon: 'ri-delete-bin-line',
});

return doDestroy(id);
await OrganizationService.destroyAll([id]);

Message.success(
i18n('entities.organization.destroy.success'),
);
await fetchOrganizations({
reload: true,
});
} catch (error) {
console.error(error);
}
Expand All @@ -170,8 +182,8 @@ const handleCommand = (command) => {
if (
router.currentRoute.value.name === 'organization'
) {
doFetch({
keepPagination: false,
fetchOrganizations({
reload: true,
});
} else {
doFind(command.organization.id);
Expand Down
Loading