Skip to content

Commit

Permalink
fix(mapper): task comment events for mapper frontend (#1871)
Browse files Browse the repository at this point in the history
* fix(activitiesPanel): optional chaining add

* fix(events): commentTask func add for commenting tasks

* fix(editor): ts types add, import path fix

* fix(activities): replace dynamic data with static

* fix(comment): replace dynamic data with static

* fix(+page): comment eventCard and uncomment more component

* fix(more): props fix, filter taskEvents & comments into seperate variable

* fix(more/editor): style fix

* fix(activities): zoomToTask functionality add

* fix(types): TaskEventType type add

* fix: ts types add

* fix(comment): add comment editor if task selected only

* fix(main): taskLayer opacity decrease, geojson property key change to state

* fix(editor): uplift state of editor if setEditorRef present

* fix(comment): clear editor content functionality add

* fix(more): if no events i.e.activities or comments then show a message
  • Loading branch information
NSUWAL123 authored Nov 12, 2024
1 parent ea4a033 commit bf7dda2
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const ActivitiesPanel = ({ defaultTheme, state, params, map }: activitiesPanelTy

setAllActivities(projectTaskActivityList.length);
let finalTaskEvents: projectTaskActivity[] = taskHistories.filter((task) => {
return task.username.replace(/\s+/g, '').toString().includes(searchText.toString());
return task?.username?.replace(/\s+/g, '')?.toString().includes(searchText.toString());
});
if (searchText != '') {
setTaskHistories(finalTaskEvents);
Expand Down
2 changes: 1 addition & 1 deletion src/mapper/src/lib/components/dialog-task-actions.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
type Props = {
isTaskActionModalOpen: boolean;
toggleTaskActionModal: (value: boolean) => {};
toggleTaskActionModal: (value: boolean) => void;
selectedTab: string;
projectId: number;
};
Expand Down
26 changes: 17 additions & 9 deletions src/mapper/src/lib/components/editor/editor.svelte
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
<script>
import '$styles/button.css';
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import '$styles/button.css';
import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';
import Toolbar from './toolbar.svelte';
import './editor.css';
import Toolbar from '$lib/components/editor/toolbar.svelte';
import '$lib/components/editor/editor.css';
type Props = {
editable: boolean;
content: string;
setEditorHtmlContent?: (content: string) => any;
setEditorRef?: (editor: any) => void;
};
let element = $state();
let editor = $state();
let { editable, content, setEditorHtmlContent } = $props();
let element: Element | undefined = $state();
let editor: Editor | undefined = $state();
let { editable, content, setEditorHtmlContent, setEditorRef }: Props = $props();
onMount(() => {
editor = new Editor({
Expand All @@ -23,11 +30,12 @@
setEditorHtmlContent && setEditorHtmlContent(editor.getHTML());
},
});
setEditorRef && setEditorRef(editor);
});
onDestroy(() => {
if (editor) {
editor.destroy();
editor?.destroy();
}
});
</script>
Expand All @@ -38,7 +46,7 @@
<Toolbar {editor} />
{/if}

<div class={`${editable ? 'h-[80px]' : 'h-full'}`}>
<div class={`${editable ? 'h-[80px] overflow-y-scroll pt-[3px]' : 'h-full'}`}>
<div bind:this={element}></div>
</div>
</div>
Expand Down
16 changes: 12 additions & 4 deletions src/mapper/src/lib/components/map/main.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@
interface Props {
projectOutlineCoords: Position[][];
entitiesUrl: string;
toggleTaskActionModal: (value: boolean) => {};
toggleTaskActionModal: (value: boolean) => void;
projectId: number;
setMapRef: (map: maplibregl.Map | undefined) => void;
}
let { projectOutlineCoords, entitiesUrl, toggleTaskActionModal, projectId }: Props = $props();
let { projectOutlineCoords, entitiesUrl, toggleTaskActionModal, projectId, setMapRef }: Props = $props();
const taskStore = getTaskStore();
const projectSetupStepStore = getProjectSetupStepStore();
Expand All @@ -58,6 +59,13 @@
projectSetupStep = +projectSetupStepStore.projectSetupStep;
});
// set the map ref to parent component
$effect(() => {
if (map) {
setMapRef(map);
}
});
// Fit the map bounds to the project area
$effect(() => {
if (map && projectOutlineCoords) {
Expand Down Expand Up @@ -160,7 +168,7 @@
'#40ac8c',
'#c5fbf5', // default color if no match is found
],
'fill-opacity': hoverStateFilter(0.1, 0),
'fill-opacity': hoverStateFilter(0.3, 0),
}}
beforeLayerType="symbol"
manageHoverState
Expand Down Expand Up @@ -193,7 +201,7 @@
'case',
['==', ['get', 'state'], 'LOCKED_FOR_MAPPING'],
'LOCKED_FOR_MAPPING',
['==', ['get', 'status'], 'LOCKED_FOR_VALIDATION'],
['==', ['get', 'state'], 'LOCKED_FOR_VALIDATION'],
'LOCKED_FOR_VALIDATION',
'',
],
Expand Down
52 changes: 43 additions & 9 deletions src/mapper/src/lib/components/more/activities.svelte
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
<script>
<script lang="ts">
import ActivitiesSkeleton from '$lib/components/more/skeleton/activities.svelte';
import type { TaskEventType } from '$lib/types';
import { getTaskStore } from '$store/tasks.svelte.ts';
interface Props {
taskEvents: TaskEventType[];
zoomToTask: (taskId: number) => void;
}
let { taskEvents, zoomToTask }: Props = $props();
const taskStore = getTaskStore();
</script>

<div class="overflow-y-scroll overflow-x-hidden flex flex-col gap-2 pb-2">
{#if false}
{#each Array.from({ length: 5 }) as _, index}
<ActivitiesSkeleton />
{/each}
{:else if taskEvents?.length === 0}
<div class="flex justify-center mt-10">
<p class="text-[#484848] text-base">
{taskStore?.selectedTaskId ? `No activities yet on task ${taskStore?.selectedTaskId}` : 'No activities yet'}
</p>
</div>
{:else}
{#each Array.from({ length: 5 }) as _, index}
{#each taskEvents as event}
<div class="flex flex-col gap-2 py-3 bg-[#F6F5F5] rounded-md mr-1">
<div class="flex gap-4 px-3">
<hot-icon
Expand All @@ -17,26 +34,43 @@
class="!text-[1.7rem] text-red-600 cursor-pointer duration-200 rounded-full p-[2px] bg-white"
></hot-icon>
<div class="flex flex-col gap-1 flex-1">
<p class="font-semibold">Localadmin</p>
<p class="font-semibold capitalize">{event?.username}</p>
<div class="flex items-center justify-between">
<p class="text-[#484848] text-sm">#2</p>
<p class="text-[#484848] text-sm">#{event?.task_id}</p>
<div class="flex items-center gap-2">
<hot-icon name="clock-history" class="!text-[1rem] text-red-600 cursor-pointer duration-200"></hot-icon>
<p class="text-[#484848] text-sm">2024-10-21 11:42</p>
<p class="text-[#484848] text-sm">
<span>
{event?.created_at?.split(' ')[0]}
</span>
<span>
{event?.created_at?.split(' ')[1]?.split('.')[0]}
</span>
</p>
</div>
</div>
</div>
</div>
<div class="px-3 flex items-center fmtm-justify-between gap-2">
<p class="font-normal text-[#484848] flex-1">
<span class="">svcfmtm</span> updated status to <span>MAPPED</span>
<span class="capitalize">{event?.username}</span> updated status to <span>{event?.state}</span>
</p>
<hot-icon name="map" class="!text-[1rem] text-[#484848] hover:text-red-600 cursor-pointer duration-200"
<hot-icon
onkeydown={(e: KeyboardEvent) => {
if (e.key === 'Enter') {
zoomToTask(event?.task_id);
}
}}
role="button"
tabindex="0"
onclick={() => {
zoomToTask(event?.task_id);
}}
name="map"
class="!text-[1rem] text-[#484848] hover:text-red-600 cursor-pointer duration-200"
></hot-icon>
</div>
</div>
{/each}
{/if}
</div>

<style></style>
101 changes: 75 additions & 26 deletions src/mapper/src/lib/components/more/comment.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
<script>
<script lang="ts">
import Editor from '$lib/components/editor/editor.svelte';
import CommentSkeleton from '$lib/components/more/skeleton/comment.svelte';
import { commentTask } from '$lib/db/events';
import type { TaskEventType } from '$lib/types';
import { getTaskStore } from '$store/tasks.svelte.ts';
interface Props {
comments: TaskEventType[];
projectId: any;
}
let { comments, projectId }: Props = $props();
let currentComment: string = $state('');
let editorRef: any = $state(undefined);
const taskStore = getTaskStore();
</script>

<div class="h-[calc(100%-2.25rem)] sm:h-[calc(100%-2.6rem)]">
<div class="h-[calc(100%-11.875rem)] overflow-y-scroll overflow-x-hidden flex flex-col gap-2">
<div
class={`overflow-y-scroll overflow-x-hidden flex flex-col gap-2 ${taskStore.selectedTaskId ? 'h-[calc(100%-11.875rem)]' : 'h-[100%]'}`}
>
{#if false}
{#each Array.from({ length: 5 }) as _, index}
<CommentSkeleton />
{/each}
{:else if comments?.length === 0}
<div class="flex justify-center mt-10">
<p class="text-[#484848] text-base">
{taskStore?.selectedTaskId ? `No comments yet on task ${taskStore?.selectedTaskId}` : 'No comments yet'}
</p>
</div>
{:else}
{#each Array.from({ length: 5 }) as _, index}
{#each comments as comment}
<div class="flex flex-col gap-2 py-3 bg-[#F6F5F5] rounded-md">
<div class="flex gap-4 px-3">
<hot-icon
Expand All @@ -19,40 +42,66 @@
class="!text-[1.7rem] text-red-600 cursor-pointer duration-200 rounded-full p-[2px] bg-white"
></hot-icon>
<div class="flex flex-col gap-1 flex-1">
<p class="font-semibold">Localadmin</p>
<p class="font-semibold capitalize">{comment?.username}</p>
<div class="flex items-center justify-between">
<p class="text-[#484848] text-sm">#2</p>
<p class="text-[#484848] text-sm">#{comment?.task_id}</p>
<div class="flex items-center gap-2">
<hot-icon name="clock-history" class="!text-[1rem] text-red-600 cursor-pointer duration-200"
></hot-icon>
<p class="text-[#484848] text-sm">2024-10-21 11:42</p>
<p class="text-[#484848] text-sm">
<span>
{comment?.created_at?.split(' ')[0]}
</span>
<span>
{comment?.created_at?.split(' ')[1]?.split('.')[0]}
</span>
</p>
</div>
</div>
</div>
</div>
<Editor editable={false} content={'<p>This is a comment</p>'} />
<Editor editable={false} content={comment?.comment as string} />
</div>
{/each}
{/if}
</div>

<div class="mt-2">
<Editor
editable={true}
content=""
setEditorHtmlContent={(editorText) => {
// to-do: store state to post comment
}}
/>
<div class="w-full flex justify-end my-2 gap-2">
<sl-button variant="default" size="small" class="secondary col-span-2 sm:col-span-1"
><span class="font-barlow-medium text-sm">CLEAR</span></sl-button
>
<sl-button variant="default" size="small" class="primary col-span-2 sm:col-span-1"
><span class="font-barlow-medium text-sm">COMMENT</span></sl-button
>
{#if taskStore.selectedTaskId}
<div class="mt-2">
<Editor
editable={true}
content=""
setEditorHtmlContent={(editorText: string) => {
currentComment = editorText;
}}
setEditorRef={(editor) => {
editorRef = editor;
}}
/>
<div class="w-full flex justify-end my-2 gap-2">
<sl-button
onclick={() => {
editorRef?.commands.clearContent(true);
}}
onkeydown={() => {}}
role="button"
tabindex="0"
variant="default"
size="small"
class="secondary col-span-2 sm:col-span-1"><span class="font-barlow-medium text-sm">CLEAR</span></sl-button
>
<sl-button
variant="default"
size="small"
class="primary col-span-2 sm:col-span-1"
onclick={() => {
commentTask(projectId, taskStore.selectedTaskId, currentComment);
editorRef?.commands.clearContent(true);
}}
onkeydown={() => {}}
role="button"
tabindex="0"><span class="font-barlow-medium text-sm">COMMENT</span></sl-button
>
</div>
</div>
</div>
{/if}
</div>

<style></style>
Loading

0 comments on commit bf7dda2

Please sign in to comment.