Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
<template>
<div>
<VMenu location="left" offset="-40" width="240" contained>
<span>
<VMenu
v-model="isOpen"
location="left"
offset="-40"
width="240"
contained
>
<template #activator="{ props: menuProps }">
<VBtn
v-bind="menuProps"
aria-label="Options menu"
color="primary-lighten-3"
icon="mdi-dots-vertical"
size="small"
variant="text"
rounded
:size="activatorSize"
:rounded="rounded"
>
</VBtn>
</template>
Expand Down Expand Up @@ -45,13 +51,13 @@
:repository-id="activity.repositoryId"
@close="showCopyDialog = false"
/>
</div>
</span>
</template>

<script lang="ts" setup>
import { first, sortBy } from 'lodash-es';
import type { Activity } from '@tailor-cms/interfaces/activity';
import { InsertLocation } from '@tailor-cms/utils';
import type { StoreActivity } from '@/stores/activity';

import CopyDialog from '@/components/repository/Outline/CopyActivity/index.vue';
import CreateDialog from '@/components/repository/Outline/CreateDialog/index.vue';
Expand All @@ -62,11 +68,22 @@ const { AddAfter, AddBefore, AddInto } = InsertLocation;
const activityStore = useActivityStore();
const currentRepositoryStore = useCurrentRepository();

const props = defineProps<{ activity: StoreActivity }>();
export interface Props {
activity: StoreActivity;
activatorSize?: string;
rounded?: boolean | string;
}

const props = withDefaults(defineProps<Props>(), {
activatorSize: 'small',
rounded: 'circle',
});

const { $eventBus, $pluginRegistry } = useNuxtApp() as any;
const selectedActivity = useSelectedActivity(props.activity);

const isOpen = defineModel<boolean>({ default: false });

// Get processed name via plugin hooks
const activityName = computed(() => {
const data = props.activity?.data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import type { Activity } from '@tailor-cms/interfaces/activity';
import { activity as activityUtils } from '@tailor-cms/utils';
import type { Repository } from '@tailor-cms/interfaces/repository';
import { sortBy } from 'lodash-es';
import { TailorTreeview } from '@tailor-cms/core-components';
import TailorTreeview from './TailorTreeview/index.vue';

const { $schemaService, $pluginRegistry } = useNuxtApp() as any;

Expand All @@ -47,6 +47,7 @@ const getActivityName = (activity: Activity) => {

const attachActivityAttrs = (activity: Activity) => ({
id: activity.id,
uid: activity.uid,
title: getActivityName(activity),
isEditable: !!$schemaService.isEditable(activity.type),
isGroup: !!$schemaService.getLevel(activity.type)?.subLevels?.length,
Expand Down Expand Up @@ -146,10 +147,6 @@ const navigateToActivity = (activityId: number) => {
}

:deep(.v-list-item) {
.v-list-item__append {
visibility: hidden;
}

&:hover {
.v-list-item-title {
font-weight: 600 !important;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,47 @@
@edit="emit('edit', $event)"
/>
</template>
<ItemGroup
v-for="subItem in item.children"
:key="subItem.id"
:active-item-id="activeItemId"
:item="subItem"
@edit="emit('edit', $event)"
/>
<Draggable
:data-parent-id="item.id"
:list="item.children"
:move="repositoryStore.isValidDrop"
animation="150"
group="activities"
item-key="uid"
@update="(data: SortableEvent) => reorder(data, item.children)"
@change="(e: ChangeEvent) => repositoryStore.onOutlineItemDrop(e, item.id)"
>
<template #item="{ element }">
<ItemGroup
:active-item-id="activeItemId"
:item="element"
@edit="emit('edit', $event)"
/>
</template>
</Draggable>
</VListGroup>
<ListItem v-else v-bind="bindings" @edit="emit('edit', $event)" />
</template>

<script lang="ts" setup>
import { computed } from 'vue';
import Draggable from 'vuedraggable';

import type { ChangeEvent, SortableEvent } from '@/types/draggable';
import ItemGroup from './ItemGroup.vue';
import ListItem from './ListItem.vue';
import { useCurrentRepository } from '@/stores/current-repository';

const props = defineProps<{
item: any;
activeItemId: number;
}>();

const emit = defineEmits(['edit']);

const repositoryStore = useCurrentRepository();
const reorder = useOutlineReorder();

const bindings = computed(() => {
const { id, isEditable, title } = props.item;
return {
Expand All @@ -39,8 +58,6 @@ const bindings = computed(() => {
isActive: props.activeItemId === id,
};
});

const emit = defineEmits(['edit']);
</script>

<style lang="scss" scoped>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<template>
<VExpandTransition>
<VListItem
ref="listItem"
v-bind="omit(activatorProps, 'onClick')"
:class="{ 'list-item-active': isActive }"
:title="title"
class="list-item"
@click.prevent="onItemClick"
>
<template #prepend>
<VBtn
v-if="isGroup"
:color="prependColor"
:icon="prependIcon"
class="ml-n1 mr-2"
density="comfortable"
variant="text"
@click.stop="activatorProps?.onClick"
/>
</template>
<template #title>
<span :class="{ 'font-weight-bold': isActive }">{{ title }}</span>
</template>
<template #append>
<ActivityMenu
v-show="isHovered || isMenuOpen"
v-model="isMenuOpen"
:activity="activity"
activator-size="x-small"
class="activity-menu ml-2"
@click.stop
/>
</template>
</VListItem>
</VExpandTransition>
</template>

<script lang="ts" setup>
import { computed, useTemplateRef } from 'vue';
import { omit } from 'lodash-es';
import { useElementHover } from '@vueuse/core';
import type { Activity } from '@tailor-cms/interfaces/activity';

import ActivityMenu from '~/components/common/ActivityOptions/ActivityMenu.vue';

const props = defineProps<{
id: number;
title: string;
isGroup?: boolean;
isEmpty?: boolean;
isEditable?: boolean;
isOpen?: boolean;
isActive?: boolean;
activatorProps?: Record<string, any>;
}>();

const emit = defineEmits(['edit']);

const activityStore = useActivityStore();

const listItem = useTemplateRef<HTMLButtonElement>('listItem');
const isHovered = useElementHover(listItem);
const isMenuOpen = ref(false);

const activity = activityStore.findById(props.id) as Activity;

const prependIcon = computed(() => {
if (!props.isGroup) return '';
const icon = props.isOpen ? 'mdi-folder-open' : 'mdi-folder';
return props.isEmpty ? `${icon}-outline` : icon;
});

const prependColor = computed(() => {
return props.isOpen ? 'primary-lighten-3' : 'primary-lighten-2';
});

const onItemClick = (e: any) => {
if (!props.isEditable) return props.activatorProps?.onClick(e);
emit('edit', props.id);
};
</script>

<style lang="scss" scoped>
.list-item {
cursor: grab;

&:active {
cursor: grabbing;
}
}

.activity-menu {
:deep(.v-list-item-title),
:deep(.v-list-item-title:hover) {
color: rgb(var(--v-theme-primary-darken-3)) !important;
font-weight: 400 !important;
}
}

.v-list-item:hover .activity-menu :deep(.v-list-item__content) .v-list-item-title {
font-weight: 400 !important;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,24 @@
</VBtn>
</div>
<VList v-model:opened="expanded" slim>
<ItemGroup
v-for="item in processedItems"
:key="item.id"
:active-item-id="activeItemId"
:item="item"
@edit="emit('edit', $event)"
/>
<Draggable
:list="processedItems"
:disabled="!!search"
:move="repositoryStore.isValidDrop"
animation="150"
group="activities"
item-key="uid"
@update="(data: SortableEvent) => reorder(data, processedItems)"
@change="(e: ChangeEvent) => repositoryStore.onOutlineItemDrop(e)"
>
<template #item="{ element }">
<ItemGroup
:active-item-id="activeItemId"
:item="element"
@edit="emit('edit', $event)"
/>
</template>
</Draggable>
</VList>
<VAlert
v-if="search && !hasItems"
Expand All @@ -36,8 +47,14 @@
<script setup lang="ts">
import { cloneDeep, uniq } from 'lodash-es';
import { computed, ref, watch } from 'vue';
import Draggable from 'vuedraggable';

import type { ChangeEvent, SortableEvent } from '@/types/draggable';
import ItemGroup from './ItemGroup.vue';
import { useCurrentRepository } from '@/stores/current-repository';

const repositoryStore = useCurrentRepository();
const reorder = useOutlineReorder();

const props = defineProps<{
items: any[];
Expand Down Expand Up @@ -122,3 +139,9 @@ watch(
{ deep: true },
);
</script>

<style lang="scss" scoped>
:deep(.sortable-ghost) {
opacity: 0.6;
}
</style>
18 changes: 11 additions & 7 deletions apps/frontend/app/components/repository/Outline/OutlineItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
</template>
<span>{{ isExpanded ? 'Collapse' : 'Expand' }}</span>
</VTooltip>
<OptionsMenu :activity="activity" class="options-menu" />
<OptionsMenu :activity="activity" class="options-menu" rounded />
</div>
</template>
<template v-else>
Expand All @@ -81,21 +81,23 @@
</VSheet>
</template>
</VHover>
<div v-if="!isSoftDeleted && isExpanded && hasChildren">
<div v-if="!isSoftDeleted && isExpanded && hasSubtypes">
<Draggable
v-bind="{ handle: '.activity' }"
:data-parent-id="activity.id"
:list="children"
:move="currentRepositoryStore.isValidDrop"
animation="150"
group="activities"
item-key="uid"
@update="(data) => reorder(data, children)"
@change="(e) => currentRepositoryStore.handleOutlineItemDrag(e, activity.id)"
@update="(data: SortableEvent) => reorder(data, children)"
@change="(e: ChangeEvent) => onOutlineItemDrop(e, activity.id)"
>
<template #item="{ element, index: i }">
<OutlineItem
:activities="activities"
:activity="element"
:index="i + 1"
class="sub-activity"
/>
</template>
</Draggable>
Expand All @@ -107,18 +109,20 @@
import { activity as activityUtils } from '@tailor-cms/utils';
import Draggable from 'vuedraggable';
import { size } from 'lodash-es';
import { useDisplay } from 'vuetify';

import type { ChangeEvent, SortableEvent } from '@/types/draggable';
import ActivityName from '@/components/common/ActivityName.vue';
import OptionsMenu from '@/components/common/ActivityOptions/ActivityMenu.vue';
import OutlineItem from '@/components/repository/Outline/OutlineItem.vue';
import OutlineItemToolbar from '@/components/common/ActivityOptions/ActivityToolbar.vue';
import type { StoreActivity } from '@/stores/activity';
import { useDisplay } from 'vuetify';

const { smAndUp } = useDisplay();
const currentRepositoryStore = useCurrentRepository();

const { taxonomy } = storeToRefs(currentRepositoryStore);
const { onOutlineItemDrop } = currentRepositoryStore;

interface Props {
activity: StoreActivity;
Expand Down Expand Up @@ -230,7 +234,7 @@ $background-color: rgb(var(--v-theme-primary-darken-2));
}
}

.sub-activity {
.activity-wrapper .activity-wrapper {
margin-left: 1.25rem;
}
</style>
Loading
Loading