feat: add clickable links

This commit is contained in:
DCsunset 2021-04-15 12:35:26 +08:00
parent a6c8277e3d
commit 302988b68c
3 changed files with 1078 additions and 25 deletions

View file

@ -110,6 +110,10 @@
</v-row> </v-row>
</template> </template>
<template v-slot:item.description="{ item }">
<span v-html="linkify(item.description)" />
</template>
<template v-if="status === 'waiting'" v-slot:item.wait="{ item }"> <template v-if="status === 'waiting'" v-slot:item.wait="{ item }">
{{ displayDate(item.wait) }} {{ displayDate(item.wait) }}
</template> </template>
@ -182,6 +186,8 @@ import _ from 'lodash';
import TaskDialog from '../components/TaskDialog.vue'; import TaskDialog from '../components/TaskDialog.vue';
import ConfirmationDialog from '../components/ConfirmationDialog.vue'; import ConfirmationDialog from '../components/ConfirmationDialog.vue';
import moment from 'moment'; import moment from 'moment';
import urlRegex from 'url-regex-safe';
import normalizeUrl from 'normalize-url';
function displayDate(str?: string) { function displayDate(str?: string) {
if (!str) if (!str)
@ -215,6 +221,25 @@ function expiredDate(str?: string) {
return date.isBefore(moment()); return date.isBefore(moment());
} }
function linkify(text: string) {
const regex = urlRegex();
let match;
let lastIndex = 0;
let result = '';
while ((match = regex.exec(text)) !== null) {
console.log(match[0], match.index);
const str = text.substring(lastIndex, match.index);
const url = `<a target="_blank" href=${normalizeUrl(match[0])}>${match[0]}</a>`;
result = `${result}${str}${url}`;
lastIndex = match.index + match[0].length;
}
result += text.substring(lastIndex);
console.log(result);
return result;
}
interface Props { interface Props {
[key: string]: unknown, [key: string]: unknown,
tasks: Task[] tasks: Task[]
@ -340,6 +365,7 @@ export default defineComponent({
}; };
return { return {
linkify,
refresh, refresh,
headers, headers,
classifiedTasks, classifiedTasks,

File diff suppressed because it is too large Load diff

View file

@ -19,9 +19,11 @@
"@vue/composition-api": "^1.0.0-beta.18", "@vue/composition-api": "^1.0.0-beta.18",
"lodash": "^4.17.20", "lodash": "^4.17.20",
"moment": "^2.29.1", "moment": "^2.29.1",
"normalize-url": "^6.0.0",
"nuxt": "^2.14.7", "nuxt": "^2.14.7",
"nuxt-typed-vuex": "^0.1.22", "nuxt-typed-vuex": "^0.1.22",
"typeface-open-sans": "1.1.13" "typeface-open-sans": "1.1.13",
"url-regex-safe": "^2.0.2"
}, },
"devDependencies": { "devDependencies": {
"@nuxt/types": "^2.14.7", "@nuxt/types": "^2.14.7",
@ -31,6 +33,7 @@
"@nuxtjs/eslint-module": "^3.0.0", "@nuxtjs/eslint-module": "^3.0.0",
"@nuxtjs/vuetify": "^1.11.2", "@nuxtjs/vuetify": "^1.11.2",
"@types/lodash": "^4.14.163", "@types/lodash": "^4.14.163",
"@types/url-regex-safe": "^1.0.0",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"eslint": "^7.12.1", "eslint": "^7.12.1",
"eslint-plugin-nuxt": "^1.0.0", "eslint-plugin-nuxt": "^1.0.0",