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

Mission Log Improvements #380

Merged
merged 13 commits into from
Oct 15, 2024
17 changes: 15 additions & 2 deletions api/lib/api/mission-log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import TAKAPI from '../tak-api.js';
import { Type, Static } from '@sinclair/typebox';
import type { TAKItem } from './types.js';
import type { MissionOptions } from './mission.js';
import { GUIDMatch } from './mission.js';

export const MissionLog = Type.Object({
id: Type.String(),
Expand All @@ -12,14 +13,14 @@ export const MissionLog = Type.Object({
dtg: Type.Optional(Type.String()),
created: Type.String(),
contentHashes: Type.Array(Type.Unknown()),
keywords: Type.Array(Type.Unknown())
keywords: Type.Array(Type.String())
});

export const CreateMissionLog = Type.Object({
content: Type.String(),
creatorUid: Type.String(),
contentHashes: Type.Optional(Type.Array(Type.Unknown())),
keywords: Type.Optional(Type.Array(Type.Unknown()))
keywords: Type.Optional(Type.Array(Type.String()))
});

export const UpdateMissionLog = Type.Composite([ CreateMissionLog, Type.Object({
Expand All @@ -43,6 +44,10 @@ export default class {
}
}

#isGUID(id: string): boolean {
return GUIDMatch.test(id)
}

/**
* Delete a log entry on a Mission Sync
*
Expand Down Expand Up @@ -87,6 +92,10 @@ export default class {
): Promise<TAKItem<Static<typeof MissionLog>>> {
const url = new URL(`/Marti/api/missions/logs/entries`, this.api.url);

if (this.#isGUID(mission)) {
mission = (await this.api.Mission.get(mission, {}, opts)).name;
}

return await this.api.fetch(url, {
method: 'POST',
headers: this.#headers(opts),
Expand All @@ -110,6 +119,10 @@ export default class {
): Promise<TAKItem<Static<typeof MissionLog>>> {
const url = new URL(`/Marti/api/missions/logs/entries`, this.api.url);

if (this.#isGUID(mission)) {
mission = (await this.api.Mission.get(mission, {}, opts)).name;
}

return await this.api.fetch(url, {
method: 'PUT',
headers: this.#headers(opts),
Expand Down
1,378 changes: 1,151 additions & 227 deletions api/package-lock.json

Large diffs are not rendered by default.

161 changes: 89 additions & 72 deletions api/web/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion api/web/src/components/CloudTAK/Menu/Basemaps.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@

<script>
import { std, stdurl } from '/src/std.ts';
import Overlay from '/src/stores/overlays/base.ts';
import Overlay from '/src/stores/base/overlay.ts';
import BasemapEditModal from './Basemaps/EditModal.vue';
import MenuTemplate from '../util/MenuTemplate.vue';
import {
Expand Down
2 changes: 1 addition & 1 deletion api/web/src/components/CloudTAK/Menu/Files.vue
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ import {
import MenuTemplate from '../util/MenuTemplate.vue';
import timeDiff from '../../../timediff.ts';
import { useMapStore } from '/src/stores/map.ts';
import Overlay from '/src/stores/overlays/base.ts';
import Overlay from '/src/stores/base/overlay.ts';
const mapStore = useMapStore();

export default {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ import {
TablerLoading
} from '@tak-ps/vue-tabler';
import MenuTemplate from '../../util/MenuTemplate.vue';
import Overlay from '/src/stores/overlays/base.ts';
import Overlay from '/src/stores/base/overlay.ts';
import { useMapStore } from '/src/stores/map.ts';
const mapStore = useMapStore();
import { useCOTStore } from '/src/stores/cots.ts';
Expand Down
180 changes: 118 additions & 62 deletions api/web/src/components/CloudTAK/Menu/Mission/MissionLogs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,79 @@
:border='false'
:loading='loading.logs'
>
<div class='rows px-2'>
<div class='col-12 pb-2 px-2'>
<TablerInput
v-model='paging.filter'
icon='search'
placeholder='Filter'
/>
</div>

<TablerNone
v-if='!filteredLogs.length'
:create='false'
label='Logs'
/>
<div
v-else
class='rows px-2'
>
<div
v-for='(log, logidx) in logs'
v-for='(log, logidx) in filteredLogs'
:key='log.id'
class='col-12'
class='col-12 pb-2'
>
<div class='col-12 position-relative'>
<IconTrash
v-if='role.permissions.includes("MISSION_WRITE")'
:size='32'
stroke='1'
class='position-absolute cursor-pointer end-0 mx-2 my-2'
@click='deleteLog(logidx)'
/>
<pre
class='rounded mb-1'
v-text='log.content || "None"'
/>
</div>
<div class='d-flex'>
<label
class='subheader'
v-text='log.creatorUid'
/>
<label
class='subheader ms-auto'
v-text='log.created'
/>
</div>
<TablerLoading v-if='loading.ids.has(logidx)' desc='Deleting Log'/>
<template v-else>
<div class='d-flex'>
<label
class='subheader'
v-text='log.creatorUid'
/>
<label
class='subheader ms-auto'
v-text='log.created'
/>
</div>
<div class='col-12 position-relative'>
<IconTrash
v-if='role.permissions.includes("MISSION_WRITE")'
:size='32'
stroke='1'
class='position-absolute cursor-pointer end-0 mx-2 my-2'
@click='deleteLog(logidx)'
/>
<pre
class='rounded mb-1'
v-text='log.content || "None"'
/>
</div>

<div class='col-12'>
<span
v-for='keyword in log.keywords'
:key='keyword'
class='me-1 badge badge-outline bg-blue-lt'
v-text='keyword'
/>
</div>
</template>
</div>
</div>

<TablerLoading v-if='loading.create' desc='Creating Log' :compact='true'/>

<template v-if='role.permissions.includes("MISSION_WRITE")'>
<div class='mx-2'>
<TablerInput
v-model='createLog'
label='Create Log'
@keyup.enter='submitOnEnter ? submitLog() : undefined'
:rows='4'
/>

<TablerToggle label='Submit on Enter' v-model='submitOnEnter'/>

<div class='d-flex my-2'>
<div class='ms-auto'>
<button
Expand All @@ -61,16 +94,22 @@
</template>

<script setup lang='ts'>
import { ref, defineProps, onMounted } from 'vue'
import { std } from '../../../../../src/std.ts';
import { ref, computed, defineProps, onMounted } from 'vue'
import type { ComputedRef } from 'vue';
import type { MissionLog } from '../../../../types.ts';
import {
IconTrash,
} from '@tabler/icons-vue';
import {
TablerInput,
TablerToggle,
TablerLoading,
TablerNone
} from '@tak-ps/vue-tabler';
import MenuTemplate from '../../util/MenuTemplate.vue';
import Subscription from '../../../../stores/base/mission.ts';
import { useCOTStore } from '../../../../stores/cots.ts';
const cotStore = useCOTStore();

const props = defineProps({
mission: {
Expand All @@ -84,62 +123,79 @@ const props = defineProps({
}
})

const submitOnEnter = ref(true);
const sub = ref<Subscription | undefined>();
const paging = ref({ filter: '' });
const createLog = ref('');
const logs = ref<MissionLog[]>([]);
const loading = ref({
logs: false
const loading = ref<{
logs: boolean,
create: boolean,
ids: Set<number>
}> ({
logs: false,
create: false,
ids: new Set()
});

onMounted(async () => {
await fetchLogs()
});
sub.value = cotStore.subscriptions.get(props.mission.guid);

if (!sub.value) {
await fetchLogs()
} else {
logs.value = sub.value.logs;
}
});

function headers(): Record<string, string> {
if (props.token) {
return {
MissionAuthorization: props.token
}
const filteredLogs: ComputedRef<Array<MissionLog>> = computed(() => {
if (paging.value.filter.trim() === '') {
return logs.value;
} else {
return {};
const filter = paging.value.filter.toLowerCase();
return logs.value.filter((log) => {
return log.content.toLowerCase().includes(filter);
})
}
}
});

async function fetchLogs() {
loading.value.logs = true;
const list = await std(`/api/marti/missions/${props.mission.name}/log`, {
method: 'GET',
headers: headers()
}) as { items: Array<MissionLog> };

logs.value = list.items;

logs.value = (await Subscription.logList(props.mission.guid, props.token)).items;
loading.value.logs = false;
}

async function deleteLog(logidx: number): Promise<void> {
loading.value.logs = true;
await std(`/api/marti/missions/${props.mission.name}/log/${logs.value[logidx].id}`, {
method: 'DELETE',
headers: headers()
});

await fetchLogs();
if (sub.value) {
loading.value.ids.add(logidx);
await Subscription.logDelete(props.mission.guid, props.token, logs.value[logidx].id);
sub.value.logs.splice(logidx, 1);
loading.value.ids.delete(logidx);
} else {
loading.value.logs = true;
await Subscription.logDelete(props.mission.guid, props.token, logs.value[logidx].id);
await fetchLogs();
}
}

async function submitLog() {
loading.value.logs = true;
if (sub.value) {
loading.value.create = true;
const log = await Subscription.logCreate(props.mission.guid, props.token, {
content: createLog.value
});

sub.value.logs.push(log);

await std(`/api/marti/missions/${props.mission.name}/log`, {
method: 'POST',
headers: headers(),
body: {
loading.value.create = false;
} else {
loading.value.logs = true;
await Subscription.logCreate(props.mission.guid, props.token, {
content: createLog.value
}
});
});
await fetchLogs();
}

createLog.value = '';

await fetchLogs();
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export default {
],
data: function() {
return {
err: null,
loading: true,
changes: [],
}
Expand Down
2 changes: 1 addition & 1 deletion api/web/src/components/CloudTAK/Menu/OverlayExplorer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import {
import {
IconUser,
} from '@tabler/icons-vue'
import Overlay from '/src/stores/overlays/base.ts';
import Overlay from '/src/stores/base/overlay.ts';
import { useMapStore } from '/src/stores/map.ts';
const mapStore = useMapStore();

Expand Down
9 changes: 4 additions & 5 deletions api/web/src/derived-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,6 @@ export interface paths {
requestBody: {
content: {
"application/json": {
name: string;
description: string;
auto_transform?: boolean;
mission_diff?: boolean;
Expand Down Expand Up @@ -6330,7 +6329,7 @@ export interface paths {
dtg?: string;
created: string;
contentHashes: unknown[];
keywords: unknown[];
keywords: string[];
}[];
};
};
Expand Down Expand Up @@ -6424,7 +6423,7 @@ export interface paths {
dtg?: string;
created: string;
contentHashes: unknown[];
keywords: unknown[];
keywords: string[];
};
messages?: string[];
nodeId?: string;
Expand Down Expand Up @@ -6539,7 +6538,7 @@ export interface paths {
dtg?: string;
created: string;
contentHashes: unknown[];
keywords: unknown[];
keywords: string[];
}[];
contents: {
timestamp: string;
Expand Down Expand Up @@ -6635,7 +6634,7 @@ export interface paths {
dtg?: string;
created: string;
contentHashes: unknown[];
keywords: unknown[];
keywords: string[];
}[];
contents: {
timestamp: string;
Expand Down
File renamed without changes.
Loading
Loading