Skip to content

Commit

Permalink
feature:teampspace-setting:members
Browse files Browse the repository at this point in the history
  • Loading branch information
het-t committed Jul 22, 2024
1 parent bf05417 commit f5dd775
Show file tree
Hide file tree
Showing 16 changed files with 521 additions and 57 deletions.
13 changes: 13 additions & 0 deletions src/helpers/globals/setCurrentComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useGeneralStore } from "@/stores/general";

export const setCurrentComponent = ({component, props = {}, setAutoPositions = false, e}) => {
const generalStore = useGeneralStore();

if(setAutoPositions) {
const measures = e.target.getBoundingClientRect();
generalStore.dialog.top = measures.top;
generalStore.dialog.left = measures.left;
}

generalStore.setCurrentComponentInDefaultOverlay(component, props);
}
16 changes: 16 additions & 0 deletions src/services/api/updateTeamMembers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import makePostReq from "./makePostReq"

export const updateTeamMembers = function(args: {
spaceId: string,
teamId: string,
existingMembersOrGuestsToRemove?: Array<IMembership>,
newMembersOrGuestsToAdd?: Array<IMembership>
}) {
return makePostReq("/api/v1/updateTeamMembers", args);
}

interface IMembership {
entity_type: "user",
type: "member" | "owner",
user_id: string
}
6 changes: 5 additions & 1 deletion src/services/transactions/ui-usecases/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ export function set(args, path, pointer) {

targetNode[path[i]] = (
typeof args === 'object'
? Object.assign({}, args)
? (
args?.length >= 0
? [...args]
: Object.assign({}, args)
)
: args
);
}
2 changes: 0 additions & 2 deletions src/stores/recordValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ export const useRecordValuesStore = defineStore('recordValues', () => {

function addSpaceIfNotPresent(id: string): void {
if(checkSpacePresenceById(id)) return;

setSpace(id);

}

function setSpace(id: string) {
Expand Down
11 changes: 6 additions & 5 deletions src/stores/transactionsQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ export const useTransactionsQueue = defineStore('q', () => {
table,
record: recordValue,
spaceId
})
});
}
else {
recordValueStore.setRecordValue({
id: pointerId,
table,
record: recordValue
})
});
}
}

Expand Down Expand Up @@ -118,11 +118,12 @@ export const useTransactionsQueue = defineStore('q', () => {
if (syncRecordValues.length) {
const recordValuesResponse: SyncRecordResponse = await SyncrecordValuesApi.execute(syncRecordValues);
setRecordValuesFromRecordMap(recordValuesResponse.data.recordMap);

syncRecordIds.forEach(id => {
recordsStatuses.value[id] = { status: 1 }
});
}

syncRecordIds.forEach(id => {
recordsStatuses.value[id] = { status: 1 }
});
}
}
catch (error: any) {
Expand Down
175 changes: 175 additions & 0 deletions src/ui/components/DialogTeamspaceSettingMembers.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<template>
<div style="width: 100%; margin-bottom: 10px;">
<div style="font-weight: 500; font-size: 14px; margin-bottom: 10px;"
>Permissions</div>

<div style="border: 1px solid rgba(55, 53, 47, 0.09); border-radius: 4px;">
<base-button
style="min-height: 45px; width: 100%; padding: 4px 0;"
>
<div ref="typeBtn" style="display: flex; line-height: 120%; width: 100%; user-select: none; padding-top: 4px; padding-bottom: 4px;"
@click.stop="handleTeamspaceTypesDisplay"
>
<div style="margin-left: 10px; margin-right: 6px;">
<div>{{ props.accessType.type }}</div>

<div style="margin-top: 2px; font-size: 12px; color: rgb(120, 119, 116);"
>{{ props.accessType.description }}</div>
</div>
</div>
</base-button>

<div style="display: flex; align-items: center; width: 100%; justify-content: center; width: 100%; height: 1px;">
<div class="separator"
style="border-bottom: solid 1px rgba(55, 53, 47, 0.09); margin-left: 15px; margin-right: 15px; width: 100%;"
></div>
</div>

<div style="margin-left: 4px; margin-right: 7px; padding-top: 4px; padding-bottom: 4px;">
<div style="display: flex; align-items: center; justify-content: space-between; min-height: 36px;">
<div style="display: flex; gap: 10px; align-items: center; min-width: 200px; margin-left: 6px;">
<div>Teamspace owners</div>
</div>

<span>
<base-button style="padding: 0 8px; height: 28px;"
>Full access</base-button>
</span>
</div>

<div style="display: flex; align-items: center; justify-content: space-between; min-height: 36px;">
<div style="display: flex; gap: 10px; align-items: center; min-width: 200px; margin-left: 6px;">
<div>Teamspace members</div>
</div>

<span>
<base-button style="padding: 0 8px; height: 28px;"
>Full access</base-button>
</span>
</div>

<div style="display: flex; align-items: center; justify-content: space-between; min-height: 36px;">
<div style="display: flex; gap: 10px; align-items: center; min-width: 200px; margin-left: 6px;">
<div>Everyone else in Het Tarkhala's Xdoc</div>
</div>

<span>
<base-button style="padding: 0 8px; height: 28px;"
>Full access</base-button>
</span>
</div>
</div>
</div>

<div style="width: 100%; height: 20px;"></div>

<div style="font-weight: 500; font-size: 14px; margin-bottom: 10px;"
>Members</div>

<div style="display: flex; justify-content: space-between; align-items: center; position: sticky; top: 0; z-index: 10; background: white; padding-bottom: 10px;">
<div>
<base-button style="height: 32px; white-space: nowrap; border-radius: 4px; padding: 0 12px; color: white; font-weight: 500;"
@click.stop="handleClickNew"
:hover-style="{background: 'rgb(0, 119, 212)'}"
:default-style="{background: 'rgb(35, 131, 226)'}"
>Add members</base-button>

<base-button style="margin: 0 5px; font-size: 12px; height: 32px; padding: 0 6px 0 8px; white-space: nowrap; border-radius: 4px; line-height: 1.2; min-width: 0px; color: rgb(35, 131, 226);"
:hover-style="{background: 'rgba(35, 131, 226, 0.07)'}"
>Copy link</base-button>

<div style="flex-grow: 1;"></div>
</div>
</div>

<div style="display: block; overflow: hidden; margin-top: 6px; border-bottom: solid 1px rgba(55, 53, 47, 0.09);">
<div style="font-size: 12px; width: 100%; color: rgba(55, 53, 47, 0.65); text-overflow: ellipsis;">
<div style="display: flex; align-items: center; justify-content: space-between; height: 28px;">
<base-button :hover-style="{}">Name</base-button>
<base-button :hover-style="{}">Role</base-button>
</div>
</div>
</div>

<div style="flex-grow: 1; flex-shrink: 1; display: flex; flex-direction: column; width: 100%; margin-bottom: 12px;"
v-if="existance"
>
<div v-for="member in memberships" :key="member.id"
style="display: flex; flex-direction: row; justify-content: space-between; align-items: center;"
>
<space-settings-table-cell-user
:user-id="member.user_id"
/>

<base-button style="padding: 0 8px; height: 28px;"
@click.stop="setCurrentComponent({
component: 'dialog_teamspace_memberships',
props: { teamId: props.teamId, userId: member.user_id},
setAutoPositions: true, e: $event
})"
>
<span style="font-size: 12.5px; color: rgb(55, 53, 47); font-weight: 400;"
>{{ member.type === "owner"
? "Teamspace owner"
: "Teamspace member"
}}</span>
</base-button>
</div>

</div>

</div>
</template>

<script setup>
import { ref, defineProps, toRef } from 'vue';
import SpaceSettingsTableCellUser from './SpaceSettingsTableCellUser.vue';
import BaseButton from './BaseButton.vue';
import { useRecordValuesStore } from '@/stores/recordValues';
import { useDataExistanceCheck } from '../composables/useDataExistanceCheck';
import { syncRecordValueFromApi } from '@/helpers/globals/SyncRecordValueFromApi';
import { setCurrentComponent } from "@/helpers/globals/setCurrentComponent";
const props = defineProps({
accessType: {
type: Object,
required: true
},
teamId: {
type: String,
required: true
}
});
const typeBtn = ref("");
function handleClickNew() {
console.log(props.teamId);
}
function handleTeamspaceTypesDisplay() {
const { top, width, left, height } = typeBtn.value.getBoundingClientRect();
setCurrentComponent("dialog_teamspace_types", {
top,
left,
height,
width
});
}
const recordValuesStore = useRecordValuesStore();
const { memberships } = recordValuesStore.getRecordValue({
id: props.teamId,
table: "team",
spaceId: "f2cf1fd1-8789-4ddd-9190-49f41966c446"
});
const { existance } = useDataExistanceCheck(toRef(() => memberships.map(({user_id}) => user_id)));
memberships.map(({ user_id: id }) => syncRecordValueFromApi(
"xdoc_user",
id,
"f2cf1fd1-8789-4ddd-9190-49f41966c446"
));
</script>
126 changes: 126 additions & 0 deletions src/ui/components/DialogTeamspaceSettingMemberships.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<template>
<dialog-view>
<div role="menu" tabindex="0">
<div style="padding-top: 6px; padding-bottom: 6px; display: flex; flex-direction: column;">
<base-menu-item style="padding: 6px 0;"
@click.stop="handleSelectMembership('owner')"
>
<div style="display: flex; align-items: center; line-height: 120%; width: 100%; user-select: none; min-height: 28px; font-size: 14px;">
<div style="display: flex; flex-direction: column; gap: 6px;">
<div style="margin-left: 12px; margin-right: 12px; min-width: 0px; flex: 1 1 auto;">
<div style="display: flex;"
>Teamspace owner</div>

<div style="color: rgba(55, 53, 47, 0.6); font-size: 12px; margin-top: 3px;"
>Can edit teamspace setting and full access to teamspace pages</div>
</div>
</div>
</div>
</base-menu-item>

<base-menu-item style="padding: 6px 0;"
@click.stop="handleSelectMembership('member')"
>
<div style="display: flex; align-items: center; line-height: 120%; width: 100%; user-select: none; min-height: 28px; font-size: 14px;">
<div style="display: flex; flex-direction: column; gap: 6px;">
<div style="margin-left: 12px; margin-right: 12px; min-width: 0px; flex: 1 1 auto;">
<div style="display: flex;"
>Teamspace member</div>

<div style="color: rgba(55, 53, 47, 0.6); font-size: 12px; margin-top: 3px;"
>Cannot edit teamspace setting and can access teamspace pages</div>
</div>
</div>
</div>
</base-menu-item>

<base-menu-item style="color: rgb(235, 87, 87) !important;"
@click.stop="handleSelectMembership('remove')"
>
<div style="display: flex; align-items: center; line-height: 120%; width: 100%; user-select: none; min-height: 28px; font-size: 14px;">
<div style="display: flex; flex-direction: column; gap: 6px;">
<div style="margin-left: 12px; margin-right: 12px; min-width: 0px; flex: 1 1 auto;"
>Remove</div>
</div>
</div>
</base-menu-item>
</div>
</div>
</dialog-view>
</template>

<script setup>
import DialogView from './DialogView.vue';
import BaseMenuItem from './BaseMenuItem.vue';
import { useGeneralStore } from '@/stores/general';
import { defineProps } from 'vue';
import { useTransactionsQueue } from '@/stores/transactionsQueue';
import { makeOperation } from '@/services/transactions/factories/makeOperation';
import { makeTransaction } from '@/services/transactions/factories/makeTransaction';
import { useRecordValuesStore } from '@/stores/recordValues';
import { updateTeamMembers } from '@/services/api/updateTeamMembers';
const props = defineProps({
teamId: {
type: String,
required: true
},
userId: {
type: String,
required: true
}
});
async function handleSelectMembership(memberType) {
const transactionsStore = useTransactionsQueue();
const spaceId = "f2cf1fd1-8789-4ddd-9190-49f41966c446";
const teamPointer = {
id: props.teamId,
spaceId,
table: "team"
};
const team = useRecordValuesStore().getRecordValue(teamPointer);
if(memberType == "remove") {
const res = await updateTeamMembers({
spaceId,
teamId: props.teamId,
existingMembersOrGuestsToRemove: [
team.memberships.find(({ user_id }) => user_id === props.userId)
]
});
console.log(res.data)
}
else {
const membership = team.memberships.find(({user_id}) => user_id === props.userId);
membership.type = memberType;
transactionsStore.enqueue(
makeTransaction({
spaceId,
debug: {
userAction: "DialogTeamspaceSettingMemberships"
},
operations: [
makeOperation(
"set",
team.memberships,
["memberships"],
{
id: props.teamId,
table: "team",
spaceId
}
)
]
})
);
}
useGeneralStore().hideCurrentComponent();
}
</script>
Loading

0 comments on commit f5dd775

Please sign in to comment.