Convert success list/view
Also adjusted webpack chunks, added tooling configuration
This commit is contained in:
parent
8cf54d73ca
commit
f132970535
@ -189,6 +189,7 @@ let withReconn (conn : IConnection) =
|
||||
| false -> ()))
|
||||
|
||||
open JobsJobsJobs.Domain.SharedTypes
|
||||
open RethinkDb.Driver.Ast
|
||||
|
||||
/// Profile data access functions
|
||||
[<RequireQualifiedAccess>]
|
||||
@ -432,7 +433,11 @@ module Success =
|
||||
|
||||
// Retrieve all success stories
|
||||
let all conn =
|
||||
// TODO: identify query and fields that will make StoryEntry meaningful
|
||||
withReconn(conn).ExecuteAsync(fun () ->
|
||||
r.Table(Table.Success)
|
||||
.EqJoin("citizenId", r.Table(Table.Citizen))
|
||||
.Without(r.HashMap("right", "id"))
|
||||
.Zip()
|
||||
.Merge(Javascript "function (s) { return { citizenName: s.realName || s.displayName || s.naUser } }")
|
||||
.Pluck("id", "citizenId", "citizenName", "recordedOn", "fromHere", "hasStory")
|
||||
.RunResultAsync<StoryEntry list> conn)
|
||||
|
392
src/JobsJobsJobs/App/package-lock.json
generated
392
src/JobsJobsJobs/App/package-lock.json
generated
@ -2021,6 +2021,122 @@
|
||||
"tslint": "^5.20.1",
|
||||
"webpack": "^4.0.0",
|
||||
"yorkie": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
||||
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"fork-ts-checker-webpack-plugin-v5": {
|
||||
"version": "npm:fork-ts-checker-webpack-plugin@5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz",
|
||||
"integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.8.3",
|
||||
"@types/json-schema": "^7.0.5",
|
||||
"chalk": "^4.1.0",
|
||||
"cosmiconfig": "^6.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"fs-extra": "^9.0.0",
|
||||
"memfs": "^3.1.2",
|
||||
"minimatch": "^3.0.4",
|
||||
"schema-utils": "2.7.0",
|
||||
"semver": "^7.3.2",
|
||||
"tapable": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
|
||||
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.4",
|
||||
"ajv": "^6.12.2",
|
||||
"ajv-keywords": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@vue/cli-plugin-vuex": {
|
||||
@ -2099,6 +2215,44 @@
|
||||
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
||||
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||
@ -2110,6 +2264,13 @@
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
@ -2119,6 +2280,18 @@
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
||||
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"ssri": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
|
||||
@ -2128,11 +2301,33 @@
|
||||
"minipass": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true
|
||||
},
|
||||
"vue-loader-v16": {
|
||||
"version": "npm:vue-loader@16.3.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.3.3.tgz",
|
||||
"integrity": "sha512-/1GzCuQ6MRORbC+leKTKoTGtpQt60bYe0gDGEextSteA2OM+v201FPha5jzmjQzVhRcwieZeUvezAtG5a/e5cw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
"hash-sum": "^2.0.0",
|
||||
"loader-utils": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -6506,122 +6701,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"fork-ts-checker-webpack-plugin-v5": {
|
||||
"version": "npm:fork-ts-checker-webpack-plugin@5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz",
|
||||
"integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.8.3",
|
||||
"@types/json-schema": "^7.0.5",
|
||||
"chalk": "^4.1.0",
|
||||
"cosmiconfig": "^6.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"fs-extra": "^9.0.0",
|
||||
"memfs": "^3.1.2",
|
||||
"minimatch": "^3.0.4",
|
||||
"schema-utils": "2.7.0",
|
||||
"semver": "^7.3.2",
|
||||
"tapable": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
||||
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
|
||||
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.4",
|
||||
"ajv": "^6.12.2",
|
||||
"ajv-keywords": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
@ -12883,87 +12962,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"vue-loader-v16": {
|
||||
"version": "npm:vue-loader@16.3.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.3.3.tgz",
|
||||
"integrity": "sha512-/1GzCuQ6MRORbC+leKTKoTGtpQt60bYe0gDGEextSteA2OM+v201FPha5jzmjQzVhRcwieZeUvezAtG5a/e5cw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
"hash-sum": "^2.0.0",
|
||||
"loader-utils": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
||||
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
||||
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vue-router": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.10.tgz",
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { MarkedOptions } from 'marked'
|
||||
import { Citizen, Continent, Count, LogOnSuccess, Profile, ProfileForView } from './types'
|
||||
import { Citizen, Continent, Count, LogOnSuccess, Profile, ProfileForView, StoryEntry, Success } from './types'
|
||||
|
||||
/**
|
||||
* Create a URL that will access the API
|
||||
@ -149,6 +149,29 @@ export default {
|
||||
*/
|
||||
delete: async (user : LogOnSuccess) : Promise<string | undefined> =>
|
||||
apiAction(await fetch(apiUrl('profile'), reqInit('DELETE', user)), 'deleting profile')
|
||||
},
|
||||
|
||||
/** API functions for success stories */
|
||||
success: {
|
||||
|
||||
/**
|
||||
* Retrieve all success stories
|
||||
*
|
||||
* @param user The currently logged-on user
|
||||
* @returns All success stories (if any exist), undefined (if none exist), or an error
|
||||
*/
|
||||
list: async (user : LogOnSuccess) : Promise<StoryEntry[] | string | undefined> =>
|
||||
apiResult<StoryEntry[]>(await fetch(apiUrl('success/list'), reqInit('GET', user)), 'retrieving success stories'),
|
||||
|
||||
/**
|
||||
* Retrieve a success story by its ID
|
||||
*
|
||||
* @param id The success story ID to be retrieved
|
||||
* @param user The currently logged-on user
|
||||
* @returns The success story, or an error
|
||||
*/
|
||||
retrieve: async (id : string, user : LogOnSuccess) : Promise<Success | string | undefined> =>
|
||||
apiResult<Success>(await fetch(apiUrl(`success/${id}`), reqInit('GET', user)), `retrieving success story ${id}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,3 +86,35 @@ export interface Count {
|
||||
/** The count being returned */
|
||||
count : number
|
||||
}
|
||||
|
||||
/** An entry in the list of success stories */
|
||||
export interface StoryEntry {
|
||||
/** The ID of this success story */
|
||||
id : string
|
||||
/** The ID of the citizen who recorded this story */
|
||||
citizenId : string
|
||||
/** The name of the citizen who recorded this story */
|
||||
citizenName : string
|
||||
/** When this story was recorded (date) */
|
||||
recordedOn : string
|
||||
/** Whether this story involves an opportunity that arose due to Jobs, Jobs, Jobs */
|
||||
fromHere : boolean
|
||||
/** Whether this report has a further story, or if it is simply a "found work" entry */
|
||||
hasStory : boolean
|
||||
}
|
||||
|
||||
/** A record of success finding employment */
|
||||
export interface Success {
|
||||
/** The ID of the success report */
|
||||
id : string
|
||||
/** The ID of the citizen who wrote this success report */
|
||||
citizenId : string
|
||||
/** When this success report was recorded (date) */
|
||||
recordedOn : string
|
||||
/** Whether the success was due, at least in part, to Jobs, Jobs, Jobs */
|
||||
fromHere : boolean
|
||||
/** The source of this success (listing or profile) */
|
||||
source : string
|
||||
/** The success story */
|
||||
story : string | undefined
|
||||
}
|
||||
|
34
src/JobsJobsJobs/App/src/components/FullDate.vue
Normal file
34
src/JobsJobsJobs/App/src/components/FullDate.vue
Normal file
@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<template v-if="true">{{formatted}}</template>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { format, parseJSON } from 'date-fns'
|
||||
import { utcToZonedTime } from 'date-fns-tz'
|
||||
|
||||
/**
|
||||
* Parse a date from its JSON representation to a UTC-aligned date
|
||||
*
|
||||
* @param date The date string in JSON from JSON
|
||||
* @returns A UTC JavaScript date
|
||||
*/
|
||||
export function parseToUtc (date : string) : Date {
|
||||
return utcToZonedTime(parseJSON(date), Intl.DateTimeFormat().resolvedOptions().timeZone)
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FullDate',
|
||||
props: {
|
||||
date: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
return {
|
||||
formatted: format(parseToUtc(props.date), 'PPP')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -4,8 +4,8 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { format, parseJSON } from 'date-fns'
|
||||
import { utcToZonedTime } from 'date-fns-tz'
|
||||
import { format } from 'date-fns'
|
||||
import { parseToUtc } from './FullDate.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FullDateTime',
|
||||
@ -17,10 +17,7 @@ export default defineComponent({
|
||||
},
|
||||
setup (props) {
|
||||
return {
|
||||
formatted: format(
|
||||
utcToZonedTime(
|
||||
parseJSON(props.date), Intl.DateTimeFormat().resolvedOptions().timeZone),
|
||||
'PPPppp')
|
||||
formatted: format(parseToUtc(props.date), 'PPPppp')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -12,7 +12,7 @@
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, ref } from 'vue'
|
||||
import marked from 'marked'
|
||||
import { markedOptions } from '../api'
|
||||
import { markedOptions } from '@/api'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'MarkdownEditor',
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import { useStore } from '../../store'
|
||||
import { useStore } from '@/store'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AppNav',
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import AudioClip from '../AudioClip.vue'
|
||||
import AudioClip from '@/components/AudioClip.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TitleBar',
|
||||
|
@ -9,11 +9,11 @@ const routes: Array<RouteRecordRaw> = [
|
||||
// Citizen URLs
|
||||
{
|
||||
path: '/citizen/authorized',
|
||||
component: () => import(/* webpackChunkName: "logon" */ '../views/citizen/Authorized.vue')
|
||||
component: () => import(/* webpackChunkName: "dashboard" */ '../views/citizen/Authorized.vue')
|
||||
},
|
||||
{
|
||||
path: '/citizen/dashboard',
|
||||
component: () => import(/* webpackChunkName: "logon" */ '../views/citizen/Dashboard.vue')
|
||||
component: () => import(/* webpackChunkName: "dashboard" */ '../views/citizen/Dashboard.vue')
|
||||
},
|
||||
{
|
||||
path: '/citizen/profile',
|
||||
@ -48,11 +48,15 @@ const routes: Array<RouteRecordRaw> = [
|
||||
// Success Story URLs
|
||||
{
|
||||
path: '/success-story/list',
|
||||
component: () => import(/* webpackChunkName: "succview" */ '../views/success-story/StoryList.vue')
|
||||
component: () => import(/* webpackChunkName: "success" */ '../views/success-story/StoryList.vue')
|
||||
},
|
||||
{
|
||||
path: '/success-story/add',
|
||||
component: () => import(/* webpackChunkName: "succedit" */ '../views/success-story/StoryAdd.vue')
|
||||
},
|
||||
{
|
||||
path: '/success-story/view/:id',
|
||||
component: () => import(/* webpackChunkName: "success" */ '../views/success-story/StoryView.vue')
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import AudioClip from '../components/AudioClip.vue'
|
||||
import AudioClip from '@/components/AudioClip.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Home',
|
||||
|
@ -8,7 +8,7 @@
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useStore } from '../../store'
|
||||
import { useStore } from '@/store'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Authorized',
|
||||
|
@ -23,8 +23,8 @@
|
||||
</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
You do not have an employment profile established; click below (or “Edit Profile” in the menu)
|
||||
to get started!
|
||||
You do not have an employment profile established; click below (or “Edit Profile” in the
|
||||
menu) to get started!
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
@ -74,11 +74,11 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, Ref, ref } from 'vue'
|
||||
import api, { LogOnSuccess, Profile } from '../../api'
|
||||
import { useStore } from '../../store'
|
||||
import FullDateTime from '../../components/FullDateTime.vue'
|
||||
import LoadData from '../../components/LoadData.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import api, { LogOnSuccess, Profile } from '@/api'
|
||||
import { useStore } from '@/store'
|
||||
import FullDateTime from '@/components/FullDateTime.vue'
|
||||
import LoadData from '@/components/LoadData.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Dashboard',
|
||||
|
@ -9,7 +9,7 @@
|
||||
<v-col cols="12" sm="10" md="8" lg="6">
|
||||
<label for="realName">Real Name</label>
|
||||
<input type="text" id="realName" v-model="realName" maxlength="255"
|
||||
placeholder="Leave blank to use your NAS display name">
|
||||
placeholder="Leave blank to use your NAS display name">
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
@ -34,7 +34,7 @@
|
||||
<v-col cols="12" sm="6" md="8">
|
||||
<label for="region" class="jjj-required">Region</label>
|
||||
<input type="text" id="region" v-model="profile.region" maxlength="255"
|
||||
placeholder="Country, state, geographic area, etc.">
|
||||
placeholder="Country, state, geographic area, etc.">
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
@ -111,10 +111,10 @@
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, Ref, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import api, { LogOnSuccess, Profile } from '../../api'
|
||||
import MarkdownEditor from '../../components/MarkdownEditor.vue'
|
||||
import LoadData from '../../components/LoadData.vue'
|
||||
import { useStore } from '../../store'
|
||||
import api, { LogOnSuccess, Profile } from '@/api'
|
||||
import MarkdownEditor from '@/components/MarkdownEditor.vue'
|
||||
import LoadData from '@/components/LoadData.vue'
|
||||
import { useStore } from '@/store'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'EditProfile',
|
||||
|
@ -8,7 +8,7 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useStore } from '../../store'
|
||||
import { useStore } from '@/store'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LogOff',
|
||||
|
@ -36,9 +36,9 @@
|
||||
import { computed, defineComponent, ref, Ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import marked from 'marked'
|
||||
import LoadData from '../../components/LoadData.vue'
|
||||
import { useStore } from '../../store'
|
||||
import api, { LogOnSuccess, markedOptions, ProfileForView } from '../../api'
|
||||
import api, { LogOnSuccess, markedOptions, ProfileForView } from '@/api'
|
||||
import { useStore } from '@/store'
|
||||
import LoadData from '@/components/LoadData.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ProfileEdit',
|
||||
|
@ -40,8 +40,8 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import api, { LogOnSuccess } from '../../api'
|
||||
import { useStore } from '../../store'
|
||||
import api, { LogOnSuccess } from '@/api'
|
||||
import { useStore } from '@/store'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DeletionOptions',
|
||||
|
@ -1,3 +1,79 @@
|
||||
<template>
|
||||
<p>TODO: convert this view</p>
|
||||
<article>
|
||||
<page-title title="Success Stories" />
|
||||
<h3>Success Stories</h3>
|
||||
<load-data :load="retrieveStories">
|
||||
<table v-if="stories?.length > 0" class="table table-sm table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Story</th>
|
||||
<th scope="col">From</th>
|
||||
<th scope="col">Found Here?</th>
|
||||
<th scope="col">Recorded On</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="story in stories" :key="story.id">
|
||||
<td>
|
||||
<router-link v-if="story.hasStory" :to="`/success-story/view/${story.id}`">View</router-link>
|
||||
<em v-else>None</em>
|
||||
<template v-if="story.citizenId === user.citizenId">
|
||||
~ <router-link :to="`/success-story/edit/${story.id}`">Edit</router-link>
|
||||
</template>
|
||||
</td>
|
||||
<td>{{story.citizenName}}</td>
|
||||
<td>
|
||||
<strong v-if="story.fromHere">Yes</strong>
|
||||
<template v-else>No</template>
|
||||
</td>
|
||||
<td><full-date :date="story.recordedOn" /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p v-else>There are no success stories recorded <em>(yet)</em></p>
|
||||
</load-data>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, Ref } from 'vue'
|
||||
import api, { LogOnSuccess, StoryEntry } from '@/api'
|
||||
import { useStore } from '@/store'
|
||||
import FullDate from '@/components/FullDate.vue'
|
||||
import LoadData from '@/components/LoadData.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'StoryList',
|
||||
components: {
|
||||
LoadData,
|
||||
FullDate
|
||||
},
|
||||
setup () {
|
||||
const store = useStore()
|
||||
|
||||
/** The currently logged-on user */
|
||||
const user = store.state.user as LogOnSuccess
|
||||
|
||||
/** The success stories to be displayed */
|
||||
const stories : Ref<StoryEntry[] | undefined> = ref(undefined)
|
||||
|
||||
/** Get all currently recorded stories */
|
||||
const retrieveStories = async (errors : string[]) => {
|
||||
const listResult = await api.success.list(user)
|
||||
if (typeof listResult === 'string') {
|
||||
errors.push(listResult)
|
||||
} else if (typeof listResult === 'undefined') {
|
||||
stories.value = []
|
||||
} else {
|
||||
stories.value = listResult
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
retrieveStories,
|
||||
stories,
|
||||
user
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
72
src/JobsJobsJobs/App/src/views/success-story/StoryView.vue
Normal file
72
src/JobsJobsJobs/App/src/views/success-story/StoryView.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<article>
|
||||
<page-title title="Success Story" />
|
||||
<load-data :load="retrieveStory">
|
||||
<h3>{{citizenName}}’s Success Story</h3>
|
||||
<h4><full-date-time :date="story.recordedOn" /></h4>
|
||||
<p v-if="story.fromHere"><em><strong>Found via Jobs, Jobs, Jobs</strong></em></p>
|
||||
<hr>
|
||||
<div v-if="story.story" v-html="successStory"></div>
|
||||
</load-data>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, Ref, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import marked from 'marked'
|
||||
import api, { LogOnSuccess, markedOptions, Success } from '@/api'
|
||||
import { useStore } from '@/store'
|
||||
import FullDateTime from '@/components/FullDateTime.vue'
|
||||
import LoadData from '@/components/LoadData.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'StoryView',
|
||||
components: {
|
||||
FullDateTime,
|
||||
LoadData
|
||||
},
|
||||
setup () {
|
||||
const store = useStore()
|
||||
const route = useRoute()
|
||||
|
||||
/** The currently logged-on user */
|
||||
const user = store.state.user as LogOnSuccess
|
||||
|
||||
/** The story to be displayed */
|
||||
const story : Ref<Success | undefined> = ref(undefined)
|
||||
|
||||
/** The citizen's name (real, display, or NAS, whichever is found first) */
|
||||
const citizenName = ref('')
|
||||
|
||||
/** Retrieve the success story */
|
||||
const retrieveStory = async (errors : string []) => {
|
||||
const storyResponse = await api.success.retrieve(route.params.id as string, user)
|
||||
if (typeof storyResponse === 'string') {
|
||||
errors.push(storyResponse)
|
||||
return
|
||||
}
|
||||
if (typeof storyResponse === 'undefined') {
|
||||
errors.push('Success story not found')
|
||||
return
|
||||
}
|
||||
story.value = storyResponse
|
||||
const citResponse = await api.citizen.retrieve(story.value.citizenId, user)
|
||||
if (typeof citResponse === 'string') {
|
||||
errors.push(citResponse)
|
||||
} else if (typeof citResponse === 'undefined') {
|
||||
errors.push('Citizen not found')
|
||||
} else {
|
||||
citizenName.value = citResponse.realName || citResponse.displayName || citResponse.naUser
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
story,
|
||||
retrieveStory,
|
||||
citizenName,
|
||||
successStory: computed(() => marked(story.value?.story || '', markedOptions))
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -189,7 +189,7 @@ type StoryEntry = {
|
||||
/// The name of the citizen who recorded this story
|
||||
citizenName : string
|
||||
/// When this story was recorded
|
||||
RecordedOn : Instant
|
||||
recordedOn : Instant
|
||||
/// Whether this story involves an opportunity that arose due to Jobs, Jobs, Jobs
|
||||
fromHere : bool
|
||||
/// Whether this report has a further story, or if it is simply a "found work" entry
|
||||
|
13
vetur.config.js
Normal file
13
vetur.config.js
Normal file
@ -0,0 +1,13 @@
|
||||
// vetur.config.js
|
||||
/** @type {import('vls').VeturConfig} */
|
||||
module.exports = {
|
||||
// override vscode settings
|
||||
// Notice: It only affects the settings used by Vetur.
|
||||
settings: {
|
||||
// "vetur.useWorkspaceDependencies": true,
|
||||
// "vetur.experimental.templateInterpolationService": true
|
||||
},
|
||||
projects: [
|
||||
'./src/JobsJobsJobs/App'
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user