Merge branch 'development'
This commit is contained in:
commit
b19973ef87
17 changed files with 299 additions and 158 deletions
167
.github/workflows/release.yaml
vendored
167
.github/workflows/release.yaml
vendored
|
|
@ -1,89 +1,78 @@
|
|||
name: release
|
||||
run-name: release ${{ github.actor }}
|
||||
on:
|
||||
# push:
|
||||
# tags:
|
||||
# - 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
# tags-ignore:
|
||||
# - '2.*'
|
||||
# Allow run workflow manually from Action tab
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IMAGE_VER:
|
||||
description: "version for build image"
|
||||
type: string
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: edm/core
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/chamomind/docker/edm
|
||||
jobs:
|
||||
# act workflow_dispatch --reuse -W .github/workflows/release.yaml --input IMAGE_VER=v0.2.4-dev -s DOCKER_USER=robot\$edm+edm -s DOCKER_PASS=jJCfpfU7jfJrvb5BRbVr6Z9HbWNQWR69 -s SSH_KEY="$(< ~/.ssh/chamomind-ehr)"
|
||||
# act --reuse --workflows .github/workflows/release.yaml --job release --input IMAGE_VER=v0.2.4-dev -s DOCKER_USER=robot\$edm+edm -s DOCKER_PASS=jJCfpfU7jfJrvb5BRbVr6Z9HbWNQWR69 -s SSH_KEY="$(< ~/.ssh/chamomind-ehr)"
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code # checkout only cms is possible but I checkout all
|
||||
uses: actions/checkout@v3
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER='${GITHUB_REF/refs\/tags\//}'
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='beta'
|
||||
fi
|
||||
echo "{\"version\":\"$IMAGE_VER\", \"builddate\":\"$(date +"%Y-%m-%d_%T")\",\"ref_name\":\"$GITHUB_REF\" }" > ./Services/server/src/ver.json
|
||||
cat ./Services/server/src/ver.json
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
- name: Debug act
|
||||
if: ${{ env.ACT }}
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
cat ./Services/server/src/ver.json
|
||||
echo ${{secrets.DOCKER_USER}}
|
||||
echo ${{secrets.DOCKER_PASS}}
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login in to registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{env.REGISTRY}}
|
||||
username: ${{secrets.DOCKER_USER}}
|
||||
password: ${{secrets.DOCKER_PASS}}
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ./Services
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest
|
||||
# this stop solve mysterious build fail next stop ?!
|
||||
- name: Debug act
|
||||
if: ${{ env.ACT }}
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
cat ./Services/server/src/ver.json
|
||||
echo ${{secrets.DOCKER_USER}}
|
||||
echo ${{secrets.DOCKER_PASS}}
|
||||
|
||||
- name: Remote Deployment
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
# uses: appleboy/ssh-action@v0.1.8
|
||||
with:
|
||||
host: ${{env.DEPLOY_HOST}}
|
||||
username: chamomind
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
port: 10100
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
|
||||
|
||||
name: release
|
||||
|
||||
run-name: release ${{ github.actor }}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IMAGE_VER:
|
||||
description: image version
|
||||
type: string
|
||||
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: edm/core
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/chamomind/docker/edm
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER="${GITHUB_REF##*/}"
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='dev'
|
||||
fi
|
||||
echo "{\"version\":\"$IMAGE_VER\", \"date\":\"$(date +"%Y-%m-%d_%T")\",\"ref\":\"$GITHUB_REF\" }" > ./Services/server/src/version.json
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
cat ./Services/server/src/version.json
|
||||
- name: Debug act
|
||||
if: ${{ env.ACT }}
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
cat ./Services/server/src/version.json
|
||||
echo ${{ secrets.DOCKER_USER }}
|
||||
echo ${{ secrets.DOCKER_PASS }}
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login in to registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_PASS }}
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ./Services
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.gen_ver.outputs.image_ver }},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||
- name: Debug act
|
||||
if: ${{ env.ACT }}
|
||||
run: |
|
||||
cat ./Services/server/src/version.json
|
||||
echo ${{ secrets.DOCKER_USER }}
|
||||
echo ${{ secrets.DOCKER_PASS }}
|
||||
- name: Remote Deployment
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ env.DEPLOY_HOST }}
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
username: chamomind
|
||||
port: 10100
|
||||
script: |
|
||||
cd "${{ env.COMPOSE_PATH }}"
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const props = withDefaults(
|
|||
description?: string
|
||||
keyword?: string[]
|
||||
category?: string[]
|
||||
author?: string
|
||||
}>(),
|
||||
{
|
||||
open: false,
|
||||
|
|
@ -34,6 +35,7 @@ const emit = defineEmits([
|
|||
'update:description',
|
||||
'update:keyword',
|
||||
'update:category',
|
||||
'update:author',
|
||||
'filechange',
|
||||
'reset',
|
||||
'submit',
|
||||
|
|
@ -56,6 +58,7 @@ function reset() {
|
|||
emit('update:description', '')
|
||||
emit('update:keyword', '')
|
||||
emit('update:category', '')
|
||||
emit('update:author', '')
|
||||
emit('reset')
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +70,7 @@ function submit() {
|
|||
description: props.description ?? '',
|
||||
keyword: props.keyword,
|
||||
category: props.category,
|
||||
author: props.author,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +169,9 @@ const file = ref<File | undefined>()
|
|||
: ''
|
||||
"
|
||||
id="inputFile"
|
||||
:rules="[(v) => (v !== undefined || mode === 'edit' ) || ('โปรดอัปโหลดไฟล์')]"
|
||||
:rules="[
|
||||
(v) => v !== undefined || mode === 'edit' || 'โปรดอัปโหลดไฟล์',
|
||||
]"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="attach_file" />
|
||||
|
|
@ -181,7 +187,10 @@ const file = ref<File | undefined>()
|
|||
class="q-my-sm"
|
||||
placeholder="กรอกชื่อเรื่อง"
|
||||
:model-value="title"
|
||||
:rules="[(v) => (v != undefined && v.length > 3) || 'ชื่อต้องยาวกว่า 3 ตัวอักษร']"
|
||||
:rules="[
|
||||
(v) =>
|
||||
(v != undefined && v.length > 3) || 'ชื่อต้องยาวกว่า 3 ตัวอักษร',
|
||||
]"
|
||||
@update:model-value="(v) => $emit('update:title', v)"
|
||||
id="inputTitle"
|
||||
/>
|
||||
|
|
@ -217,7 +226,6 @@ const file = ref<File | undefined>()
|
|||
@new-value="createCategory"
|
||||
:options="filterDataCategory"
|
||||
@filter="filterCategory"
|
||||
style="width: 250px"
|
||||
@update:model-value="(v) => $emit('update:category', v)"
|
||||
data-testid="filterDataCategory"
|
||||
>
|
||||
|
|
@ -237,7 +245,6 @@ const file = ref<File | undefined>()
|
|||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
style="width: 250px"
|
||||
:model-value="props.keyword"
|
||||
@update:model-value="(v) => $emit('update:keyword', v)"
|
||||
@new-value="createKeyword"
|
||||
|
|
@ -247,6 +254,23 @@ const file = ref<File | undefined>()
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<section class="q-mb-md">
|
||||
<span class="text-weight-bold">เจ้าของผลงาน</span>
|
||||
<q-input
|
||||
outlined
|
||||
dense
|
||||
class="q-my-sm"
|
||||
placeholder="เจ้าของผลงาน"
|
||||
:model-value="author"
|
||||
:rules="[
|
||||
(v) =>
|
||||
(v != undefined && v.length > 3) || 'ชื่อต้องยาวกว่า 3 ตัวอักษร',
|
||||
]"
|
||||
@update:model-value="(v) => $emit('update:author', v)"
|
||||
id="inputAuthor"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section :style="{ display: 'flex', gap: '.5rem' }">
|
||||
<q-btn
|
||||
label="บันทึก"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ const fileFormData = ref<{
|
|||
description?: string
|
||||
keyword?: string[]
|
||||
category?: string[]
|
||||
author?: string
|
||||
}>({})
|
||||
const fileFormType = ref<'edit' | 'create'>('create')
|
||||
const fileFormError = ref<{ fileExist?: boolean; fileName2Long?: boolean }>({})
|
||||
|
|
@ -36,6 +37,7 @@ function triggerFileEdit(
|
|||
description: string
|
||||
keyword: string[]
|
||||
category: string[]
|
||||
author: string
|
||||
},
|
||||
pathname: string,
|
||||
file?: string,
|
||||
|
|
@ -48,6 +50,7 @@ function triggerFileEdit(
|
|||
description: value.description,
|
||||
keyword: value.keyword,
|
||||
category: value.category,
|
||||
author: value.author,
|
||||
}
|
||||
fileNameLabel.value = file
|
||||
}
|
||||
|
|
@ -68,7 +71,7 @@ function checkFileExist(name: string, except?: string) {
|
|||
}
|
||||
|
||||
function checkFileName2Long(name: string, except?: string) {
|
||||
return Boolean(name.length > 85)
|
||||
return name !== except && Boolean(name.length > 85)
|
||||
}
|
||||
|
||||
async function submitFileForm(
|
||||
|
|
@ -79,6 +82,7 @@ async function submitFileForm(
|
|||
description: string
|
||||
keyword: string[]
|
||||
category: string[]
|
||||
author: string
|
||||
},
|
||||
force = false,
|
||||
) {
|
||||
|
|
@ -101,6 +105,7 @@ async function submitFileForm(
|
|||
description: value.description,
|
||||
keyword: value.keyword,
|
||||
category: value.category,
|
||||
author: value.author,
|
||||
})
|
||||
} else {
|
||||
await updateFile(
|
||||
|
|
@ -110,6 +115,7 @@ async function submitFileForm(
|
|||
description: value.description,
|
||||
keyword: value.keyword,
|
||||
category: value.category,
|
||||
author: value.author,
|
||||
},
|
||||
value.file,
|
||||
)
|
||||
|
|
@ -132,11 +138,15 @@ async function submitFileForm(
|
|||
v-model:description="fileFormData.description"
|
||||
v-model:keyword="fileFormData.keyword"
|
||||
v-model:category="fileFormData.category"
|
||||
v-model:author="fileFormData.author"
|
||||
@reset="() => (fileFormError = {})"
|
||||
@filechange="
|
||||
(name: string) => {
|
||||
;(fileFormError.fileExist = checkFileExist(name, fileNameLabel)),
|
||||
(fileFormError.fileName2Long = checkFileName2Long(name, fileNameLabel))
|
||||
(fileFormError.fileName2Long = checkFileName2Long(
|
||||
name,
|
||||
fileNameLabel,
|
||||
))
|
||||
}
|
||||
"
|
||||
@submit="submitFileForm"
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ function triggerFileDelete(pathname: string) {
|
|||
description: value.description,
|
||||
keyword: value.keyword,
|
||||
category: value.category,
|
||||
author: value.author,
|
||||
},
|
||||
value.pathname,
|
||||
value.fileName,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ const { getFileInfo, getSize, getType } = useFileInfoStore()
|
|||
const storageStore = useStorage()
|
||||
const { deleteFile } = storageStore
|
||||
|
||||
const fileInfoStore = useFileInfoStore()
|
||||
const { getFormatDate } = fileInfoStore
|
||||
|
||||
const fileFormComponent = ref<InstanceType<typeof FileFormWrapper>>()
|
||||
|
||||
const keywordList = ref<string[]>([])
|
||||
|
|
@ -54,12 +57,20 @@ const columns: QTableProps['columns'] = [
|
|||
},
|
||||
{
|
||||
name: 'title',
|
||||
align: 'center',
|
||||
align: 'left',
|
||||
label: 'ชื่อเรื่อง',
|
||||
field: 'title',
|
||||
style: 'width: 200px',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'author',
|
||||
align: 'left',
|
||||
label: 'เจ้าของผลงาน',
|
||||
field: 'author',
|
||||
style: 'width: 200px',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'fileType',
|
||||
align: 'center',
|
||||
|
|
@ -223,6 +234,7 @@ onMounted(() => {
|
|||
description: value.description,
|
||||
keyword: value.keyword,
|
||||
category: value.category,
|
||||
author: value.author,
|
||||
},
|
||||
value.pathname,
|
||||
value.fileName,
|
||||
|
|
@ -262,17 +274,29 @@ onMounted(() => {
|
|||
<file-icon
|
||||
size="list"
|
||||
:fileMimeType="
|
||||
nameData.row.fileType ? nameData.row.fileType : 'unknow'
|
||||
nameData.row.fileType ? nameData.row.fileType : 'unknown'
|
||||
"
|
||||
:fileName="
|
||||
nameData.row.fileName ? nameData.row.fileName : 'unknown'
|
||||
"
|
||||
:fileName="nameData.row.fileName ? nameData.row.fileName : 'unknow'"
|
||||
/>
|
||||
{{ nameData.row.fileName }}
|
||||
</q-td>
|
||||
</template>
|
||||
<template v-slot:body-cell-title="data">
|
||||
<q-td style="width: 50%" @click="() => getFileInfo(data.row)">
|
||||
{{ data.row.metadata.subject ?? data.row.title }}
|
||||
</q-td>
|
||||
</template>
|
||||
<template v-slot:body-cell-author="author">
|
||||
<q-td style="width: 50%" @click="() => getFileInfo(author.row)">
|
||||
{{ author.row.metadata.author ?? author.row.author }}
|
||||
</q-td>
|
||||
</template>
|
||||
|
||||
<template v-slot:body-cell-fileType="typeData">
|
||||
<q-td>
|
||||
<div class="justify-center">
|
||||
<div>
|
||||
{{ getType(typeData.row.fileType, typeData.row.fileName) }}
|
||||
</div>
|
||||
</q-td>
|
||||
|
|
@ -282,12 +306,29 @@ onMounted(() => {
|
|||
<q-td class="justify-center">
|
||||
<div>
|
||||
<q-icon class="q-ma-sm" name="o_info" size="2em" color="primary" />
|
||||
<q-tooltip
|
||||
anchor="center left"
|
||||
self="center right"
|
||||
:offset="[5, 1]"
|
||||
>
|
||||
{{ getSize(actionData.row.fileSize) }}
|
||||
<q-tooltip anchor="center left" self="center right">
|
||||
<div class="flex" style="flex-direction: column; font-size: 120%">
|
||||
<span>ชื่อไฟล์: {{ actionData.row.fileName }}</span>
|
||||
<span>
|
||||
ชื่อเรื่อง:
|
||||
{{ actionData.row.metadata.subject ?? actionData.row.title }}
|
||||
</span>
|
||||
<span>
|
||||
เจ้าของผลงาน:
|
||||
{{ actionData.row.metadata.author ?? actionData.row.author }}
|
||||
</span>
|
||||
<span>ขนาด: {{ getSize(actionData.row.fileSize) }}</span>
|
||||
<span>
|
||||
ประเภทของไฟล์:
|
||||
{{
|
||||
getType(actionData.row.fileType, actionData.row.fileName)
|
||||
}}
|
||||
</span>
|
||||
<span>
|
||||
วันที่อัปโหลด:
|
||||
{{ getFormatDate(actionData.row.createdAt) }}
|
||||
</span>
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</div>
|
||||
<div v-if="props.action">
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ const props = defineProps<{
|
|||
|
||||
const deleteState = ref<boolean>(false)
|
||||
const open = ref<boolean>(false)
|
||||
|
||||
const deletePath = ref<string>('')
|
||||
const deleteTarget = ref<'deleteFolder' | 'deleteFile'>()
|
||||
const deleteMap = { deleteFolder, deleteFile }
|
||||
|
|
@ -90,14 +89,14 @@ const colFolder = [
|
|||
{
|
||||
name: 'createdBy',
|
||||
label: 'สร้างโดย',
|
||||
align: 'center',
|
||||
align: 'left',
|
||||
field: 'createdBy',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'createdAt',
|
||||
label: 'วันที่สร้าง',
|
||||
align: 'center',
|
||||
align: 'left',
|
||||
field: 'createdAt',
|
||||
sortable: true,
|
||||
},
|
||||
|
|
@ -120,14 +119,22 @@ const colFile = [
|
|||
{
|
||||
name: 'title',
|
||||
label: 'ชื่อเรื่อง',
|
||||
align: 'center',
|
||||
align: 'left',
|
||||
field: 'title',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'author',
|
||||
align: 'left',
|
||||
label: 'เจ้าของผลงาน',
|
||||
field: 'author',
|
||||
style: 'width: 200px',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'fileType',
|
||||
label: 'ประเภทของไฟล์',
|
||||
align: 'center',
|
||||
align: 'left',
|
||||
field: 'fileType',
|
||||
sortable: true,
|
||||
},
|
||||
|
|
@ -197,14 +204,14 @@ const onRowClick = ((_, row) => {
|
|||
</q-td>
|
||||
</template>
|
||||
<template v-slot:body-cell-createdBy="data">
|
||||
<q-td class="text-center">
|
||||
<q-td>
|
||||
<span class="sort-icon-offset-margin">
|
||||
{{ data.row.createdBy }}
|
||||
</span>
|
||||
</q-td>
|
||||
</template>
|
||||
<template v-slot:body-cell-createdAt="data">
|
||||
<q-td class="text-center">
|
||||
<q-td>
|
||||
<span class="sort-icon-offset-margin">
|
||||
{{ getFormatDate(data.row.createdAt) }}
|
||||
</span>
|
||||
|
|
@ -306,12 +313,21 @@ const onRowClick = ((_, row) => {
|
|||
</q-td>
|
||||
</template>
|
||||
<template v-slot:body-cell-title="data">
|
||||
<q-td class="text-center">
|
||||
<span class="sort-icon-offset-margin">{{ data.row.title }}</span>
|
||||
<q-td>
|
||||
<span class="sort-icon-offset-margin">{{
|
||||
data.row.metadata.subject ?? data.row.title
|
||||
}}</span>
|
||||
</q-td>
|
||||
</template>
|
||||
<template v-slot:body-cell-author="data">
|
||||
<q-td>
|
||||
<span class="sort-icon-offset-margin">
|
||||
{{ data.row.metadata.author ?? data.row.author }}
|
||||
</span>
|
||||
</q-td>
|
||||
</template>
|
||||
<template v-slot:body-cell-fileType="data">
|
||||
<q-td class="text-center">
|
||||
<q-td>
|
||||
<span class="sort-icon-offset-margin">
|
||||
{{ getType(data.row.fileType, data.row.fileName) }}
|
||||
</span>
|
||||
|
|
@ -326,12 +342,30 @@ const onRowClick = ((_, row) => {
|
|||
size="2em"
|
||||
color="primary"
|
||||
/>
|
||||
<q-tooltip
|
||||
anchor="center left"
|
||||
self="center right"
|
||||
:offset="[5, 1]"
|
||||
>
|
||||
{{ getSize(data.row.fileSize) }}
|
||||
<q-tooltip anchor="center left" self="center right">
|
||||
<div
|
||||
class="flex"
|
||||
style="flex-direction: column; font-size: 120%"
|
||||
>
|
||||
<span>ชื่อไฟล์: {{ data.row.fileName }}</span>
|
||||
<span>
|
||||
ชื่อเรื่อง:
|
||||
{{ data.row.metadata.subject ?? data.row.title }}
|
||||
</span>
|
||||
<span>
|
||||
เจ้าของผลงาน:
|
||||
{{ data.row.metadata.author ?? data.row.author }}
|
||||
</span>
|
||||
<span>ขนาด: {{ getSize(data.row.fileSize) }}</span>
|
||||
<span>
|
||||
ประเภทของไฟล์:
|
||||
{{ getType(data.row.fileType, data.row.fileName) }}
|
||||
</span>
|
||||
<span>
|
||||
วันที่อัปโหลด:
|
||||
{{ getFormatDate(data.row.createdAt) }}
|
||||
</span>
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</div>
|
||||
<div v-if="props.mode === 'admin'">
|
||||
|
|
@ -373,11 +407,21 @@ const onRowClick = ((_, row) => {
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.justify-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.sort-icon-offset-margin {
|
||||
margin-right: 18px;
|
||||
}
|
||||
.q-item-label {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.cursor {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,9 +108,9 @@ const folderFormComponent = ref<InstanceType<typeof FolderFormWrapper>>()
|
|||
<span v-if="isSearch">
|
||||
ผลการค้นหา
|
||||
<span class="text-grey text-body2 q-ml-md">{{
|
||||
mode === 'admin' &&
|
||||
currentInfo.path !== '/' &&
|
||||
currentInfo.path.split('/').join(' / ')
|
||||
mode === 'admin' && currentInfo.path !== '/'
|
||||
? currentInfo.path.split('/').join(' / ')
|
||||
: ''
|
||||
}}</span>
|
||||
</span>
|
||||
<q-breadcrumbs
|
||||
|
|
|
|||
|
|
@ -3,14 +3,8 @@ import { storeToRefs } from 'pinia'
|
|||
|
||||
import { useSearchDataStore } from '@/stores/searched-data'
|
||||
|
||||
const { isAdvSearchCall, advSearchDataRow, advSearchDataField } =
|
||||
const { isAdvSearchCall, advSearchDataRow, advSearchDataField, optionsField } =
|
||||
storeToRefs(useSearchDataStore())
|
||||
const optionsField = [
|
||||
{ label: 'ชื่อเรื่อง (title)', value: 'title' },
|
||||
{ label: 'คำสำคัญ (keyword)', value: 'keyword' },
|
||||
{ label: 'หมวดหมู่ (category)', value: 'category' },
|
||||
{ label: 'เนื้อหาในไฟล์ (content)', value: 'attachment.content' },
|
||||
]
|
||||
const optionsOp = [
|
||||
{ label: 'และ', value: 'AND' },
|
||||
{ label: 'หรือ', value: 'OR' },
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ async function downloadSubmit(path: string | undefined) {
|
|||
<span>ชื่อเรื่อง</span>
|
||||
</div>
|
||||
<div class="col-grow">
|
||||
<span class="text-grey">{{ fileInfo?.title }}</span>
|
||||
<span class="text-grey">{{ fileInfo?.metadata.subject ?? fileInfo?.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
|
|
@ -147,10 +147,10 @@ async function downloadSubmit(path: string | undefined) {
|
|||
<q-separator />
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-3">
|
||||
<span>ผู้เขียน</span>
|
||||
<span>เจ้าของผลงาน</span>
|
||||
</div>
|
||||
<div class="col-grow">
|
||||
<span class="text-grey">{{ fileInfo?.author }}</span>
|
||||
<span class="text-grey">{{ fileInfo?.metadata.author ?? fileInfo?.author }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
|
|
|
|||
|
|
@ -22,15 +22,10 @@ const {
|
|||
isAdvSearchCall,
|
||||
searchData,
|
||||
advSearchDataField,
|
||||
optionsField,
|
||||
advSearchDataRow,
|
||||
} = storeToRefs(useSearchDataStore())
|
||||
const { getFoundFile } = useSearchDataStore()
|
||||
const optionsField = [
|
||||
{ label: 'ชื่อเรื่อง (title)', value: 'title' },
|
||||
{ label: 'คำสำคัญ (keyword)', value: 'keyword' },
|
||||
{ label: 'หมวดหมู่ (category)', value: 'category' },
|
||||
{ label: 'เนื้อหาในไฟล์ (content)', value: 'attachment.content' },
|
||||
]
|
||||
const submitSearchData = ref<{
|
||||
AND: {
|
||||
field: string
|
||||
|
|
@ -55,7 +50,7 @@ async function submitSearch() {
|
|||
if (searchData.value.value.trim() !== '') {
|
||||
submitSearchData.value = { AND: [], OR: [] }
|
||||
if (props.mode === 'admin') {
|
||||
optionsField.forEach((option) => {
|
||||
optionsField.value.forEach((option) => {
|
||||
submitSearchData.value.OR.push({
|
||||
field: option.value,
|
||||
value: searchData.value.value,
|
||||
|
|
@ -67,6 +62,16 @@ async function submitSearch() {
|
|||
value: searchData.value.value,
|
||||
exact: true,
|
||||
})
|
||||
submitSearchData.value.OR.push({
|
||||
field: 'metadata.author',
|
||||
value: searchData.value.value,
|
||||
exact: true,
|
||||
})
|
||||
submitSearchData.value.OR.push({
|
||||
field: 'metadata.subject',
|
||||
value: searchData.value.value,
|
||||
exact: true,
|
||||
})
|
||||
submitSearchData.value.OR.push({
|
||||
field: 'fileType',
|
||||
value: mime.getType(searchData.value.value) || '',
|
||||
|
|
@ -79,6 +84,20 @@ async function submitSearch() {
|
|||
})
|
||||
}
|
||||
} else {
|
||||
if (searchData.value.field == 'title') {
|
||||
submitSearchData.value.OR.push({
|
||||
field: 'metadata.subject',
|
||||
value: searchData.value.value,
|
||||
exact: isExact.value,
|
||||
})
|
||||
}
|
||||
if (searchData.value.field == 'author') {
|
||||
submitSearchData.value.OR.push({
|
||||
field: 'metadata.author',
|
||||
value: searchData.value.value,
|
||||
exact: isExact.value,
|
||||
})
|
||||
}
|
||||
submitSearchData.value.OR.push({
|
||||
field: searchData.value.field,
|
||||
value: searchData.value.value,
|
||||
|
|
@ -92,6 +111,20 @@ async function submitSearch() {
|
|||
(d: { field: string; value: string; op: string; exact: boolean }) => {
|
||||
if (d.field && d.value.trim() !== '') {
|
||||
const op = d.op === 'AND' ? 'AND' : 'OR'
|
||||
if (d.field == 'title') {
|
||||
submitSearchData.value[op].push({
|
||||
field: 'metadata.subject',
|
||||
value: d.value,
|
||||
exact: d.exact,
|
||||
})
|
||||
}
|
||||
if (d.field == 'author') {
|
||||
submitSearchData.value[op].push({
|
||||
field: 'metadata.author',
|
||||
value: d.value,
|
||||
exact: d.exact,
|
||||
})
|
||||
}
|
||||
submitSearchData.value[op].push({
|
||||
field: d.field,
|
||||
value: d.value,
|
||||
|
|
@ -125,7 +158,6 @@ async function submitSearch() {
|
|||
`${import.meta.env.VITE_API_ENDPOINT}/search`,
|
||||
submitSearchData.value,
|
||||
)
|
||||
|
||||
getFoundFile(res.data)
|
||||
isSearch.value = true
|
||||
} catch (error) {
|
||||
|
|
@ -218,9 +250,7 @@ watch(
|
|||
<div class="col">
|
||||
<div class="row items-center justify-between q-gutter-y-md q-pt-sm">
|
||||
<div class="col-grow">
|
||||
<advanced-search
|
||||
:submitSearch="submitSearch"
|
||||
/>
|
||||
<advanced-search :submitSearch="submitSearch" />
|
||||
</div>
|
||||
<div v-if="isAdvSearchCall === false">
|
||||
<q-btn
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ export const useFileInfoStore = defineStore('info', () => {
|
|||
|
||||
const extension = mime.getExtension(mimeType)
|
||||
|
||||
if (extension) return '.' + extension
|
||||
if (extension) return extension
|
||||
if (fileName && fileName.includes('.')) {
|
||||
return fileName.substring(fileName.lastIndexOf('.'))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ export const useSearchDataStore = defineStore('searched', () => {
|
|||
exact: false,
|
||||
},
|
||||
])
|
||||
const optionsField = ref([
|
||||
{ label: 'ชื่อเรื่อง (title)', value: 'title' },
|
||||
{ label: 'คำสำคัญ (keyword)', value: 'keyword' },
|
||||
{ label: 'หมวดหมู่ (category)', value: 'category' },
|
||||
{ label: 'เนื้อหาในไฟล์ (content)', value: 'attachment.content' },
|
||||
{ label: 'เจ้าของผลงาน (author)', value: 'author' },
|
||||
])
|
||||
const advSearchDataField = ref<AdvancedSearchFields>({
|
||||
keyword: [],
|
||||
description: '',
|
||||
|
|
@ -52,6 +59,7 @@ export const useSearchDataStore = defineStore('searched', () => {
|
|||
isAdvSearchCall,
|
||||
searchData,
|
||||
advSearchDataRow,
|
||||
optionsField,
|
||||
advSearchDataField,
|
||||
getFoundFile,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export interface StorageFile {
|
|||
fileType: string
|
||||
title: string
|
||||
description: string
|
||||
author: string,
|
||||
author: string
|
||||
metadata: Record<string, unknown>
|
||||
category: string[]
|
||||
keyword: string[]
|
||||
|
|
@ -393,6 +393,7 @@ const useStorage = defineStore('storageStore', () => {
|
|||
description?: string
|
||||
category?: string[]
|
||||
keyword?: string[]
|
||||
author?: string
|
||||
}
|
||||
async function createFile(
|
||||
file: File,
|
||||
|
|
@ -441,9 +442,9 @@ const useStorage = defineStore('storageStore', () => {
|
|||
},
|
||||
to: file?.name
|
||||
? {
|
||||
file: file.name,
|
||||
path: arr,
|
||||
}
|
||||
file: file.name,
|
||||
path: arr,
|
||||
}
|
||||
: undefined,
|
||||
upload: !!file,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ export class StorageController extends Controller {
|
|||
*/
|
||||
@Post("folder/size")
|
||||
@Tags("Storage Folder")
|
||||
@Security("bearerAuth", ["management-role", "admin"])
|
||||
@Security("bearerAuth")
|
||||
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
|
||||
@Example({
|
||||
size: 10240,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Controller, Get, Route, Tags } from "tsoa";
|
||||
import version from "../ver.json";
|
||||
import version from "../version.json";
|
||||
|
||||
@Route("version")
|
||||
export class VersionController extends Controller {
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"version": "dev",
|
||||
"builddate": "2020-01-01_00:00:00"
|
||||
}
|
||||
|
||||
4
Services/server/src/version.json
Normal file
4
Services/server/src/version.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": "v0.0.0-dev",
|
||||
"date": "2023-01-01_00:00:00"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue