diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 535f15e..9504aba 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1043,7 +1043,8 @@ "chownr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "dev": true }, "chrome-trace-event": { "version": "1.0.0", @@ -2311,8 +2312,7 @@ "version": "2.1.1", "resolved": false, "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -2334,14 +2334,12 @@ "version": "1.0.0", "resolved": false, "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2351,22 +2349,19 @@ "version": "1.1.0", "resolved": false, "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "resolved": false, "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -2475,8 +2470,7 @@ "version": "2.0.3", "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -2488,7 +2482,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2503,7 +2496,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2512,14 +2504,12 @@ "version": "0.0.8", "resolved": false, "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true + "dev": true }, "mkdirp": { "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -2530,6 +2520,13 @@ "dev": true, "optional": true }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, "needle": { "version": "2.3.0", "bundled": true, @@ -2601,8 +2598,7 @@ "version": "1.0.1", "resolved": false, "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -2614,7 +2610,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -2701,8 +2696,7 @@ "version": "5.1.1", "resolved": false, "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -2738,7 +2732,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2758,7 +2751,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2813,8 +2805,7 @@ "version": "1.0.2", "resolved": false, "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", @@ -2825,18 +2816,6 @@ } } }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -3721,18 +3700,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, "lodash.tail": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", @@ -3996,7 +3963,6 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -4006,8 +3972,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true, - "optional": true + "dev": true } } }, @@ -4153,13 +4118,6 @@ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, - "optional": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -5344,7 +5302,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "safe-regex": { "version": "1.1.0", @@ -6106,14 +6065,64 @@ "dev": true }, "tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/tar/-/tar-5.0.5.tgz", + "integrity": "sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ==", + "requires": { + "chownr": "^1.1.3", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^0.5.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "chownr": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==" + }, + "fs-minipass": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.0.0.tgz", + "integrity": "sha512-40Qz+LFXmd9tzYVnnBmZvFfvAADfUA14TXPK1s7IfElJTIZ97rA8w4Kin7Wt5JBrC3ShnnFJO/5vPjPEeJIq9A==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", + "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "terser": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", + "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", "dev": true, "requires": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" + "commander": "^2.19.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.10" } }, "terser-webpack-plugin": { diff --git a/src/app/constants/LogDescription.tsx b/src/app/constants/LogDescription.tsx index abdee74..c4b3232 100644 --- a/src/app/constants/LogDescription.tsx +++ b/src/app/constants/LogDescription.tsx @@ -12,6 +12,7 @@ import * as m from 'mithril'; import { IDescription } from '../interfaces/Description'; import { ILog } from '../interfaces/Log'; import { formatDateField } from '../utility/DateUtil'; +import { ITag } from '../interfaces/Tag'; /** * The tab information used by the TabHeader and TabContent of the Log detail page. @@ -62,6 +63,16 @@ const LogDescription: IDescription[] = [ return log.user && log.user.name; } + }, + { + label: 'Tags', + value: (log: ILog): JSX.Element => ( +
+ {log.tags!.map((tag: ITag) => { + return {tag.tagText}, ; + })} +
+ ) } ]; diff --git a/src/app/constants/apiUrls.ts b/src/app/constants/apiUrls.ts index 9ff1eee..77cbe64 100644 --- a/src/app/constants/apiUrls.ts +++ b/src/app/constants/apiUrls.ts @@ -43,12 +43,13 @@ export const getLog = (id: string | number): string => `${BASE_URL}logs/${id}`; export const linkRunToLogUrl = (runNumber: number): string => `${BASE_URL}logs/${runNumber}/runs`; export const postLog = (): string => `${BASE_URL}logs`; export const postAttachment = (logId: string | number): string => `${BASE_URL}logs/${logId}/attachments`; +export const getTagsForLog = (logId: string | number): string => `${BASE_URL}logs/${logId}/tags`; // Tag export const getTags = (query?: string): string => `${BASE_URL}tags${query ? `?${query}` : ''}`; export const getTag = (id: string | number): string => `${BASE_URL}tags/${id}`; -export const getTagsForLog = (logId: string | number): string => `${BASE_URL}tags/${logId}/logs`; export const getTagsForRun = (runId: string | number): string => `${BASE_URL}tags/${runId}/runs`; export const postTag = (): string => `${BASE_URL}tags`; export const updateTag = (id: string | number): string => `${BASE_URL}tags/${id}`; export const deleteTage = (id: string | number): string => `${BASE_URL}tags/${id}`; +export const linkTagToLogUrl = (id: string | number): string => `${BASE_URL}tags/${id}/logs`; diff --git a/src/app/interfaces/Log.ts b/src/app/interfaces/Log.ts index df1933d..a7f2258 100644 --- a/src/app/interfaces/Log.ts +++ b/src/app/interfaces/Log.ts @@ -9,6 +9,7 @@ import { IAttachmentCreate, IAttachment } from './Attachment'; import { IUser } from './User'; import { IRun } from './Run'; +import { ITag } from './Tag'; /** * Interface with the fields for fetching one or more Log entries. @@ -24,6 +25,7 @@ export interface ILog { user: IUser; runs?: IRun[]; attachments?: IAttachment[]; + tags?: ITag[]; comments?: ILog[]; commentFkRootLogId?: number; commentFkParentLogId?: number; diff --git a/src/app/interfaces/Tag.ts b/src/app/interfaces/Tag.ts index ae15854..dd79840 100644 --- a/src/app/interfaces/Tag.ts +++ b/src/app/interfaces/Tag.ts @@ -10,7 +10,7 @@ * Interface with the fields for fetching one or more Attachment entries. */ export interface ITag { - id?: number; + tagId?: number; tagText: string; } @@ -18,6 +18,6 @@ export interface ITag { * Interface with the fields for creating a Attachment entry. */ export interface ITagCreate { - fileId?: number; + tagId?: number; tagText: string; } diff --git a/src/app/organisms/Log.tsx b/src/app/organisms/Log.tsx index c4fcab1..a3ea612 100644 --- a/src/app/organisms/Log.tsx +++ b/src/app/organisms/Log.tsx @@ -16,6 +16,7 @@ import SuccessMessage from '../atoms/SuccessMessage'; import { store } from '../redux/configureStore'; import { fetchAttachmentsByLog } from '../redux/ducks/attachment/operations'; import { fetchLog, fetchThread } from '../redux/ducks/log/operations'; +import { fetchTags } from '../redux/ducks/tag/operations'; import { selectCurrentLog, selectIsFetchingLog, selectIsPatchingLinkRunToLog, selectThread @@ -31,13 +32,13 @@ import { selectAttachments } from '../redux/ducks/attachment/selectors'; import { IAttachment } from '../interfaces/Attachment'; import { download } from '../utility/FileUtil'; import AttachmentComponent from '../molecules/Attachment'; -import { selectFetchingTags, selectTagsForLog, selectTags } from '../redux/ducks/tag/selectors'; +import { selectFetchingTags, selectTags } from '../redux/ducks/tag/selectors'; import { ITag, ITagCreate } from '../interfaces/Tag'; import Input from '../atoms/Input'; import FormGroup from '../molecules/FormGroup'; import Label from '../atoms/Label'; import Select from '../atoms/Select'; -import { createTag } from '../redux/ducks/tag/operations'; +import { createTag, linkTagToLog } from '../redux/ducks/tag/operations'; import Button, { ButtonType, ButtonClass } from '../atoms/Button'; import Comment from '../atoms/Comment'; import { ILog } from '../interfaces/Log'; @@ -55,6 +56,7 @@ export default class Log extends MithrilTsxComponent { super(); store.dispatch(fetchLog(vnode.attrs.logId)); store.dispatch(fetchAttachmentsByLog(vnode.attrs.logId)); + store.dispatch(fetchTags()); store.dispatch(setFilter(FilterName.Log, 'threadId', vnode.attrs.logId)); const queryString = selectQueryString(store.getState())(FilterName.Log); console.log('fetching thread...'); @@ -65,17 +67,23 @@ export default class Log extends MithrilTsxComponent { const log = await selectCurrentLog(store.getState()) as ILog | null; const tagId = event.target.tag.value; const newTag = event.target.tagText.value; - if (log && tagId) { - // add existing tag to Log - // store.dispatch() - event.target.reset(); // Clear the form. - } else if (log && newTag) { + console.log(event); + console.log(log); + console.log(event.target.tag.value); + console.log(newTag); + if (log && newTag) { // create new tag and add to Log const tagToCreate = { tagText: newTag }; store.dispatch(createTag(tagToCreate as ITagCreate)); event.target.reset(); // Clear the form. + } else if (log && tagId) { + // add existing tag to Log + // store.dispatch() + console.log('add tag'); + store.dispatch(linkTagToLog(tagId, log.logId)); + event.target.reset(); // Clear the form. } } @@ -86,8 +94,8 @@ export default class Log extends MithrilTsxComponent { const isFetchingLog = selectIsFetchingLog(state); const isPatchingLinkRunToLog = selectIsPatchingLinkRunToLog(state); const attachments = selectAttachments(store.getState()); - const tagsForLog = selectTagsForLog(store.getState()); const tags = selectTags(store.getState()); + console.log(tags); const thread = selectThread(store.getState()); return (
@@ -180,11 +188,13 @@ export default class Log extends MithrilTsxComponent {

Currently added tags: