Skip to content

Commit

Permalink
Merge pull request #380 from dfpc-coe/log-improve
Browse files Browse the repository at this point in the history
Mission Log Improvements
  • Loading branch information
ingalls authored Oct 15, 2024
2 parents 16a4db1 + ce8c984 commit aef8a5d
Show file tree
Hide file tree
Showing 18 changed files with 1,495 additions and 403 deletions.
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

0 comments on commit aef8a5d

Please sign in to comment.