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

Organization common view #2581

Merged
merged 31 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8f8ed14
Align org view
gaspergrom Aug 16, 2024
540f9e0
Fix lint
gaspergrom Aug 16, 2024
0cbd0f5
fix organization/list endpoint
skwowet Aug 16, 2024
fcb999d
Merge branch 'improvement/org-view' of github.com:CrowdDotDev/crowd.d…
skwowet Aug 16, 2024
9bc7090
add default filters
gaspergrom Aug 16, 2024
7d2bf43
turn aggs on for orgs list
skwowet Aug 16, 2024
a31b53a
Merge branch 'improvement/org-view' of github.com:CrowdDotDev/crowd.d…
gaspergrom Aug 16, 2024
07a1163
Merge branch 'improvement/org-view' of github.com:CrowdDotDev/crowd.d…
gaspergrom Aug 16, 2024
4059492
filter null values in segments
skwowet Aug 16, 2024
fd92508
Merge branch 'improvement/org-view' of github.com:CrowdDotDev/crowd.d…
skwowet Aug 16, 2024
154d94b
Fix list view
gaspergrom Aug 20, 2024
ea4c687
fix lint
gaspergrom Aug 20, 2024
b46863a
add loading state
gaspergrom Aug 20, 2024
b090042
Fix filter conditions
gaspergrom Aug 20, 2024
3d7be74
Add segments to deletion
gaspergrom Aug 20, 2024
f77f622
fix organization delete endpoint
skwowet Aug 21, 2024
0a29052
fix formatter
skwowet Aug 21, 2024
700213d
Fix loading for members and activities
gaspergrom Aug 21, 2024
934ca5f
Merge branch 'improvement/org-view' of github.com:CrowdDotDev/crowd.d…
gaspergrom Aug 21, 2024
feb26c6
fix member query and rm segmentId
skwowet Aug 21, 2024
4fdf8f9
Merge branch 'improvement/org-view' of github.com:CrowdDotDev/crowd.d…
skwowet Aug 21, 2024
a236863
Add filter to activity query
gaspergrom Aug 21, 2024
2b3e219
Add project group selection
gaspergrom Aug 22, 2024
d4beb70
Merge branch 'crowd-linux' into improvement/org-view
gaspergrom Aug 22, 2024
1ba796c
Merge branch 'crowd-linux' into improvement/org-view
gaspergrom Aug 22, 2024
81af162
Fix org activities
gaspergrom Aug 23, 2024
8bfae70
Fix issues
gaspergrom Aug 23, 2024
abaf308
Enable lfx member filter
gaspergrom Aug 23, 2024
63d74a9
Merge branch 'crowd-linux' into improvement/org-view
gaspergrom Aug 23, 2024
a92736a
fix the fitler
skwowet Aug 23, 2024
5858965
Org common fix orgs
gaspergrom Aug 26, 2024
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
67 changes: 31 additions & 36 deletions backend/src/database/repositories/organizationRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
upsertOrgAttributes,
IDbOrgAttribute,
markOrgAttributeDefault,
deleteOrgAttributesByOrganizationId,
} from '@crowd/data-access-layer/src/organizations'
import { FieldTranslatorFactory, OpensearchQueryParser } from '@crowd/opensearch'
import {
Expand All @@ -38,7 +39,10 @@ import lodash, { uniq } from 'lodash'
import Sequelize, { QueryTypes } from 'sequelize'
import validator from 'validator'
import { findManyLfxMemberships } from '@crowd/data-access-layer/src/lfx_memberships'
import { fetchManyOrgSegments } from '@crowd/data-access-layer/src/organizations/segments'
import {
cleanupForOganization,
fetchManyOrgSegments,
} from '@crowd/data-access-layer/src/organizations/segments'
import { OrganizationField, findOrgById } from '@crowd/data-access-layer/src/orgs'
import { findAttribute } from '@crowd/data-access-layer/src/organizations/attributesConfig'
import {
Expand Down Expand Up @@ -305,8 +309,8 @@ class OrganizationRepository {
static findLfxMembershipInFilters(filter: any): any {
if (!filter) return null

if (filter.not?.lfxMembership) {
return filter.not.lfxMembership
if (filter.lfxMembership) {
return filter.lfxMembership
}

if (Array.isArray(filter.and)) {
Expand Down Expand Up @@ -564,12 +568,7 @@ class OrganizationRepository {
)
}

static async destroy(
id,
options: IRepositoryOptions,
force = false,
destroyIfOnlyNoSegmentsLeft = true,
) {
static async destroy(id, options: IRepositoryOptions, force = false) {
const transaction = SequelizeRepository.getTransaction(options)

const currentTenant = SequelizeRepository.getCurrentTenant(options)
Expand All @@ -586,30 +585,21 @@ class OrganizationRepository {
throw new Error404()
}

if (destroyIfOnlyNoSegmentsLeft) {
await OrganizationRepository.excludeOrganizationsFromSegments([id], {
...options,
transaction,
})
const org = await this.findById(id, options)
await OrganizationRepository.excludeOrganizationsFromAllSegments([id], {
...options,
transaction,
})

if (org.segments.length === 0) {
await record.destroy({
transaction,
force,
})
}
} else {
await OrganizationRepository.excludeOrganizationsFromAllSegments([id], {
...options,
transaction,
})
const qx = SequelizeRepository.getQueryExecutor(options)

await record.destroy({
transaction,
force,
})
}
await cleanupForOganization(qx, id)

await deleteOrgAttributesByOrganizationId(qx, id)

await record.destroy({
transaction,
force,
})

await this._createAuditLog(AuditLogRepository.DELETE, record, record, options)
}
Expand Down Expand Up @@ -1239,6 +1229,7 @@ class OrganizationRepository {
attributes: true,
lfxMemberships: true,
identities: true,
segments: true,
},
},
options,
Expand All @@ -1257,6 +1248,7 @@ class OrganizationRepository {
attributes: true,
lfxMemberships: true,
identities: true,
segments: true,
},
},
options,
Expand Down Expand Up @@ -1702,7 +1694,7 @@ class OrganizationRepository {
segments: false,
attributes: false,
} as {
aggregates: boolean
aggregates?: boolean
identities?: boolean
lfxMemberships?: boolean
segments?: boolean
Expand All @@ -1723,14 +1715,14 @@ class OrganizationRepository {

if (lfxMembershipFilter) {
const filterKey = Object.keys(lfxMembershipFilter)[0]
if (filterKey === 'eq') {
if (filterKey === 'ne') {
lfxMembershipFilterWhereClause = `AND EXISTS (SELECT 1 FROM "lfxMemberships" lm WHERE lm."organizationId" = o.id AND lm."tenantId" = $(tenantId))`
} else if (filterKey === 'ne') {
} else if (filterKey === 'eq') {
lfxMembershipFilterWhereClause = `AND NOT EXISTS (SELECT 1 FROM "lfxMemberships" lm WHERE lm."organizationId" = o.id AND lm."tenantId" = $(tenantId))`
}

// remove lfxMembership filter from obj since filterParser doesn't support it
filter.and = filter.and.filter((f) => !f.and?.some((subF) => subF.not?.lfxMembership))
filter.and = filter.and.filter((f) => !f.and?.some((subF) => subF.lfxMembership))
}

if (segmentId) {
Expand Down Expand Up @@ -1854,7 +1846,10 @@ class OrganizationRepository {
const orgSegments = await fetchManyOrgSegments(qx, orgIds)

rows.forEach((org) => {
org.segments = orgSegments.find((i) => i.organizationId === org.id)?.segments || []
org.segments =
orgSegments
.find((i) => i.organizationId === org.id)
?.segments.filter((segment) => segment !== null) || []
})
}
if (include.attributes) {
Expand Down
4 changes: 0 additions & 4 deletions backend/src/services/memberService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1921,10 +1921,6 @@ export default class MemberService extends LoggerBase {

const segmentId = (data.segments || [])[0]

if (!segmentId) {
throw new Error400(this.options.language, 'member.segmentsRequired')
}

return MemberRepository.findAndCountAll(
{
...data,
Expand Down
6 changes: 3 additions & 3 deletions backend/src/services/organizationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ export default class OrganizationService extends LoggerBase {

await SequelizeRepository.commitTransaction(transaction)

const searchSyncService = new SearchSyncService(this.options)
const searchSyncService = new SearchSyncService(this.options, SyncMode.ASYNCHRONOUS)

for (const id of ids) {
await searchSyncService.triggerRemoveOrganization(this.options.currentTenant.id, id)
Expand Down Expand Up @@ -1067,8 +1067,8 @@ export default class OrganizationService extends LoggerBase {
limit,
offset,
segmentId: undefined,
fields: ['id', 'displayName', 'isTeamOrganization'],
include: { aggregates: false, identities: true, segments: true, lfxMemberships: true },
fields: ['id', 'logo', 'displayName', 'isTeamOrganization'],
include: { aggregates: true, identities: true, segments: true, lfxMemberships: true },
},
this.options,
)
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { useActivityStore } from '@/modules/activity/store/pinia';
import { useActivityTypeStore } from '@/modules/activity/store/type';
import { useAuthStore } from '@/modules/auth/store/auth.store';
import useSessionTracking from '@/shared/modules/monitoring/useSessionTracking';
import { useLfSegmentsStore } from '@/modules/lf/segments/store';

export default {
name: 'App',
Expand All @@ -37,10 +38,11 @@ export default {
setup() {
const authStore = useAuthStore();
const { detachListeners } = useSessionTracking();
const { listProjectGroups } = useLfSegmentsStore();
const { init } = authStore;
const { tenant, loaded } = storeToRefs(authStore);
return {
init, tenant, loaded, detachListeners,
init, tenant, loaded, detachListeners, listProjectGroups,
};
},

Expand All @@ -67,6 +69,7 @@ export default {
window.addEventListener('resize', this.handleResize);
this.handleResize();
this.init();
this.listProjectGroups();
},

unmounted() {
Expand Down
11 changes: 5 additions & 6 deletions frontend/src/modules/activity/activity-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,18 @@ export class ActivityService {
static async query(body, countOnly = false) {
const tenantId = AuthService.getTenantId();

const segments = [
...body?.segments ?? getSegmentsFromProjectGroup(getSelectedProjectGroup()),
getSelectedProjectGroup().id,
];

// const segments = [
// ...body?.segments ?? getSegmentsFromProjectGroup(getSelectedProjectGroup()),
// getSelectedProjectGroup().id,
// ];
// If tenant is less than a month old, use old query
// Else use new query
const response = await authAxios.post(
`/tenant/${tenantId}/activity/query`,
{
...body,
countOnly,
segments,
segments: body.segments,
},
{
headers: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const { filters } = storeToRefs(activityStore);

const segmentId = computed(() => {
if (!filters.value.projects) {
return selectedProjectGroup.value.id;
return selectedProjectGroup.value?.id;
}

return filters.value.projects.value[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,13 @@ const segments = computed(() => {
if (!props.entity.segments) {
return getSegmentsFromProjectGroup(selectedProjectGroup.value)?.map((s) => subprojects.value[s]) || [];
}

return props.entity.segments?.map((s) => {
if (typeof s === 'string') {
return subprojects.value[s];
}

return s;
}) || [];
}).filter((s) => !!s) || [];
});

const fetchActivities = async ({ reset } = { reset: false }) => {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/modules/lf/layout/components/lf-menu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ const classFor = (path, exact = false, disabled = false) => {
if (exact) {
return {
'pointer-events-none': disabled,
'is-active': route.path === path,
'is-active': route.path === path && !disabled,
};
}

Expand All @@ -291,7 +291,7 @@ const classFor = (path, exact = false, disabled = false) => {

return {
'pointer-events-none': disabled,
'is-active': active,
'is-active': active && !disabled,
};
};

Expand Down
11 changes: 6 additions & 5 deletions frontend/src/modules/lf/segments/pages/lf-admin-panel-page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
v-if="activeTab === 'project-groups'"
/>
</el-tab-pane>
<!-- <el-tab-pane v-if="isAdminUser" label="Organizations" name="organizations">-->
<!-- <app-organization-common-page-->
<!-- v-if="activeTab === 'organizations'"-->
<!-- />-->
<!-- </el-tab-pane>-->
<el-tab-pane v-if="isAdminUser" label="Organizations" name="organizations">
<app-organization-common-page
v-if="activeTab === 'organizations'"
/>
</el-tab-pane>
<el-tab-pane v-if="isAdminUser" label="Automations" name="automations">
<app-automation-list
v-if="activeTab === 'automations'"
Expand Down Expand Up @@ -52,6 +52,7 @@ import { storeToRefs } from 'pinia';
import AppLfAuditLogsPage from '@/modules/lf/segments/pages/lf-audit-logs-page.vue';
import LfDevmode from '@/modules/lf/segments/components/dev/devmode.vue';
import { LfRole } from '@/shared/modules/permissions/types/Roles';
import AppOrganizationCommonPage from '@/modules/organization/pages/organization-common-page.vue';
// import AppOrganizationCommonPage from '@/modules/organization/pages/organization-common-page.vue';

const route = useRoute();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
<template>
<div class="flex">
<lf-button-group>
<!-- Merge suggestions -->
<lf-button
v-if="mergeSuggestionsCount > 0 && hasPermission(LfPermission.mergeOrganizations)"
type="secondary"
@click="isMergeSuggestionsDialogOpen = true"
>
<div class="bg-primary-500 text-white text-medium leading-5 px-1.5 rounded font-semibold">
{{ mergeSuggestionsCount }}
</div>
{{ pluralize('Merge suggestion', mergeSuggestionsCount) }}
</lf-button>
<template v-if="hasSegments">
<!-- Merge suggestions -->
<lf-button
v-if="mergeSuggestionsCount > 0 && hasPermission(LfPermission.mergeOrganizations)"
type="secondary"
@click="isMergeSuggestionsDialogOpen = true"
>
<div class="bg-primary-500 text-white text-medium leading-5 px-1.5 rounded font-semibold">
{{ mergeSuggestionsCount }}
</div>
{{ pluralize('Merge suggestion', mergeSuggestionsCount) }}
</lf-button>

<!-- Merge -->
<lf-button v-else-if="hasPermission(LfPermission.mergeOrganizations)" type="secondary" @click="isMergeDialogOpen = props.organization">
<lf-icon name="exchange-2-line" />
Merge organization
</lf-button>
<!-- Merge -->
<lf-button v-else-if="hasPermission(LfPermission.mergeOrganizations)" type="secondary" @click="isMergeDialogOpen = props.organization">
<lf-icon name="exchange-2-line" />
Merge organization
</lf-button>
</template>

<!-- Actions -->
<lf-dropdown
Expand All @@ -29,7 +31,7 @@
<lf-button
type="secondary"
:icon-only="true"
:class="hasPermission(LfPermission.mergeOrganizations) ? '!rounded-l-none -ml-px' : ''"
:class="hasSegments && hasPermission(LfPermission.mergeOrganizations) ? '!rounded-l-none -ml-px' : ''"
>
<lf-icon name="more-fill" />
</lf-button>
Expand Down Expand Up @@ -62,7 +64,7 @@ import LfIcon from '@/ui-kit/icon/Icon.vue';
import LfButton from '@/ui-kit/button/Button.vue';
import LfButtonGroup from '@/ui-kit/button/ButtonGroup.vue';
import LfDropdown from '@/ui-kit/dropdown/Dropdown.vue';
import { onMounted, ref } from 'vue';
import { computed, onMounted, ref } from 'vue';
import { LfPermission } from '@/shared/modules/permissions/types/Permissions';
import usePermissions from '@/shared/modules/permissions/helpers/usePermissions';
import { Organization } from '@/modules/organization/types/Organization';
Expand All @@ -73,6 +75,8 @@ import AppOrganizationMergeDialog from '@/modules/organization/components/organi
import LfOrganizationDropdown from '@/modules/organization/components/shared/organization-dropdown.vue';
import pluralize from 'pluralize';
import { Contributor } from '@/modules/contributor/types/Contributor';
import { useLfSegmentsStore } from '@/modules/lf/segments/store';
import { storeToRefs } from 'pinia';

const props = defineProps<{
organization: Organization,
Expand All @@ -81,6 +85,7 @@ const props = defineProps<{
const emit = defineEmits<{(e: 'reload'): any}>();

const { hasPermission } = usePermissions();
const { selectedProjectGroup } = storeToRefs(useLfSegmentsStore());

const isMergeSuggestionsDialogOpen = ref<boolean>(false);
const isMergeDialogOpen = ref<Contributor | null>(null);
Expand All @@ -99,8 +104,12 @@ const fetchMergeSuggestions = () => {
});
};

const hasSegments = computed(() => selectedProjectGroup.value?.id);

onMounted(() => {
fetchMergeSuggestions();
if (hasSegments.value) {
fetchMergeSuggestions();
}
});
</script>

Expand Down
Loading
Loading