Skip to content

Commit

Permalink
feat: add button to delegate to user from space user page (#1051)
Browse files Browse the repository at this point in the history
* feat: add button to delete to user from space user page

* fix: show delegation setting name instead of network name

* fix: show delegate button when the space has setup delegation
  • Loading branch information
wa0x6e authored Dec 17, 2024
1 parent b63c672 commit 1d9ecfd
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 9 deletions.
80 changes: 71 additions & 9 deletions apps/ui/src/components/Modal/Delegate.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
<script setup lang="ts">
import { clone } from '@/helpers/utils';
import networks from '@snapshot-labs/snapshot.js/src/networks.json';
import { h, VNode } from 'vue';
import { clone, getUrl } from '@/helpers/utils';
import { getValidator } from '@/helpers/validation';
import { METADATA as STARKNET_NETWORK_METADATA } from '@/networks/starknet';
import { Space, SpaceMetadataDelegation } from '@/types';
const DEFAULT_FORM_STATE = {
delegatee: ''
delegatee: '',
selectedIndex: 0
};
const props = defineProps<{
open: boolean;
space: Space;
delegation: SpaceMetadataDelegation;
delegation?: SpaceMetadataDelegation;
initialState?: any;
}>();
Expand Down Expand Up @@ -39,18 +43,62 @@ const { delegate } = useActions();
const form: {
delegatee: string;
selectedIndex: number;
} = reactive(clone(DEFAULT_FORM_STATE));
const formValidated = ref(false);
const showPicker = ref(false);
const searchValue = ref('');
const sending = ref(false);
const formErrors = ref({} as Record<string, any>);
const selectedDelegation = computed<SpaceMetadataDelegation>(() => {
return props.delegation || props.space.delegations[form.selectedIndex];
});
const spaceDelegationsOptions = computed<
{ id: number; name: string; icon: VNode }[]
>(() => {
return props.space.delegations
.filter(d => d.chainId)
.map((d, i) => {
const network = getNetworkDetails(d.chainId as string);
return {
id: i,
name: d.name || '',
icon: h('img', {
src: getUrl(network.logo),
alt: network.name,
class: 'rounded-full'
})
};
});
});
function getNetworkDetails(chainId: number | string) {
if (typeof chainId === 'number') {
return networks[chainId];
}
const starknetNetwork = Object.entries(STARKNET_NETWORK_METADATA).find(
([, { chainId: starknetChainId }]) => starknetChainId === chainId
)?.[0];
if (!starknetNetwork) {
return { name: 'Unknown network', logo: '' };
}
return {
name: STARKNET_NETWORK_METADATA[starknetNetwork].name,
logo: STARKNET_NETWORK_METADATA[starknetNetwork].avatar
};
}
async function handleSubmit() {
if (
!props.delegation.apiType ||
!props.delegation.contractAddress ||
!props.delegation.chainId
!selectedDelegation.value.apiType ||
!selectedDelegation.value.contractAddress ||
!selectedDelegation.value.chainId
) {
return;
}
Expand All @@ -60,10 +108,10 @@ async function handleSubmit() {
try {
await delegate(
props.space,
props.delegation.apiType,
selectedDelegation.value.apiType,
form.delegatee,
props.delegation.contractAddress,
props.delegation.chainId
selectedDelegation.value.contractAddress,
selectedDelegation.value.chainId
);
emit('close');
} catch (e) {
Expand All @@ -78,8 +126,11 @@ watch(
() => {
if (props.initialState) {
form.delegatee = props.initialState.delegatee;
form.selectedIndex =
props.initialState.selectedIndex || DEFAULT_FORM_STATE.selectedIndex;
} else {
form.delegatee = DEFAULT_FORM_STATE.delegatee;
form.selectedIndex = DEFAULT_FORM_STATE.selectedIndex;
}
}
);
Expand Down Expand Up @@ -127,6 +178,17 @@ watchEffect(async () => {
/>
</template>
<div v-else class="s-box p-4">
<Combobox
v-if="!delegation && props.space.delegations.length > 1"
v-model="form.selectedIndex"
:definition="{
type: ['number'],
title: 'Delegation scheme',
examples: ['Select delegation scheme'],
enum: spaceDelegationsOptions.map(d => d.id),
options: spaceDelegationsOptions
}"
/>
<UiInputAddress
v-model="form.delegatee"
:definition="DELEGATEE_DEFINITION"
Expand Down
22 changes: 22 additions & 0 deletions apps/ui/src/views/SpaceUser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const userActivity = ref<UserActivity>({
const loaded = ref(false);
const votingPowers = ref([] as VotingPower[]);
const votingPowerStatus = ref<VotingPowerStatus>('loading');
const delegateModalOpen = ref(false);
const delegateModalState = ref<{ delegatee: string } | null>(null);
// const delegatesCount = ref(0);
const network = computed(() => getNetwork(props.space.network));
Expand Down Expand Up @@ -119,6 +122,11 @@ async function loadUserActivity() {
// .reduce((a, b) => a + b, 0);
// }
function handleDelegateClick() {
delegateModalState.value = { delegatee: userId.value };
delegateModalOpen.value = true;
}
async function getVotingPower() {
votingPowerStatus.value = 'loading';
try {
Expand Down Expand Up @@ -178,6 +186,12 @@ watch(
class="relative bg-skin-bg h-[16px] -top-3 rounded-t-[16px] md:hidden"
/>
<div class="absolute right-4 top-4 space-x-2 flex">
<UiButton
v-if="space.delegations.length"
@click="handleDelegateClick()"
>
Delegate
</UiButton>
<UiTooltip v-if="!isWhiteLabel" title="View profile">
<UiButton
:to="{ name: 'user', params: { user: user.id } }"
Expand Down Expand Up @@ -250,5 +264,13 @@ watch(
</div>
</UiScrollerHorizontal>
<router-view :user="user" :space="space" />
<teleport to="#modal">
<ModalDelegate
:open="delegateModalOpen"
:space="space"
:initial-state="delegateModalState"
@close="delegateModalOpen = false"
/>
</teleport>
</div>
</template>

0 comments on commit 1d9ecfd

Please sign in to comment.