diff --git a/.github/workflows/gitea-local.yaml b/.forgejo/workflows/deploy.yaml similarity index 77% rename from .github/workflows/gitea-local.yaml rename to .forgejo/workflows/deploy.yaml index 6b2afdbe..86b83f01 100644 --- a/.github/workflows/gitea-local.yaml +++ b/.forgejo/workflows/deploy.yaml @@ -1,8 +1,4 @@ -name: Gitea Action - -run-name: Build ${{ github.actor }} - -# Intended for local gitea instance only. +name: Deploy Local on: workflow_dispatch: @@ -37,22 +33,14 @@ jobs: platforms: linux/amd64 tags: ${{ env.CONTAINER_IMAGE_NAME }} push: true - - name: Remote Deploy Development + - name: Remote Deploy uses: appleboy/ssh-action@v1.2.1 with: - host: ${{ vars.SSH_DEVELOPMENT_HOST }} - port: ${{ vars.SSH_DEVELOPMENT_PORT }} - username: ${{ secrets.SSH_DEVELOPMENT_USER }} - password: ${{ secrets.SSH_DEVELOPMENT_PASSWORD }} - script: eval "${{ secrets.SSH_DEVELOPMENT_DEPLOY_CMD }}" & wait - - name: Remote Deploy Test - uses: appleboy/ssh-action@v1.2.1 - with: - host: ${{ vars.SSH_TEST_HOST }} - port: ${{ vars.SSH_TEST_PORT }} - username: ${{ secrets.SSH_TEST_USER }} - password: ${{ secrets.SSH_TEST_PASSWORD }} - script: eval "${{ secrets.SSH_TEST_DEPLOY_CMD }}" & wait + host: ${{ vars.SSH_DEPLOY_HOST }} + port: ${{ vars.SSH_DEPLOY_PORT }} + username: ${{ secrets.SSH_DEPLOY_USER }} + password: ${{ secrets.SSH_DEPLOY_PASSWORD }} + script: eval "${{ secrets.SSH_DEPLOY_CMD }}" - name: Notify Discord Success if: success() run: | diff --git a/.forgejo/workflows/spellcheck.yaml b/.forgejo/workflows/spellcheck.yaml new file mode 100644 index 00000000..b6a397f3 --- /dev/null +++ b/.forgejo/workflows/spellcheck.yaml @@ -0,0 +1,21 @@ +name: Spell Check + +permissions: + contents: read + +on: [push, pull_request] + +env: + CLICOLOR: 1 + +jobs: + spelling: + name: Spell Check with Typos + runs-on: ubuntu-latest + steps: + - name: Checkout Actions Repository + uses: actions/checkout@v4 + - name: Spell Check Repo + uses: crate-ci/typos@v1.29.9 + with: + files: ./src diff --git a/.github/workflows/local-build-dev.yaml b/.github/workflows/local-build-dev.yaml deleted file mode 100644 index 43d852cf..00000000 --- a/.github/workflows/local-build-dev.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: local-build-dev - -# Intended for local network use. -# Remote access is possible if the host has a public IP address. - -on: - workflow_dispatch: - -env: - REGISTRY: ${{ vars.DOCKER_REGISTRY }} - -jobs: - local-build-dev: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Setup Docker Buildx - uses: docker/setup-buildx-action@v2 - with: - config-inline: | - [registry."${{ env.REGISTRY }}"] - http = true - insecure = true - - name: Build and Push Docker Image - uses: docker/build-push-action@v3 - with: - context: . - platforms: linux/amd64 - push: true - tags: ${{ env.REGISTRY }}/jws/jws-frontend:dev - allow: security.insecure diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 00000000..5664db5d --- /dev/null +++ b/.typos.toml @@ -0,0 +1,2 @@ +[default] +extend-ignore-re = ["(?Rm)^.*(#|//)\\s*spellchecker:disable-line$"] diff --git a/src/components/shared/table/TableProductAndService.vue b/src/components/shared/table/TableProductAndService.vue index e209eade..e1801167 100644 --- a/src/components/shared/table/TableProductAndService.vue +++ b/src/components/shared/table/TableProductAndService.vue @@ -45,6 +45,8 @@ type ExclusiveProps = { type: 'service' | 'product'; grid?: boolean; disabledWorkerId?: string[]; + disabledProductFields?: (typeof columnsProduct)[number]['name'][]; + disabledServiceFields?: (typeof columnsService)[number]['name'][]; rows: Product[]; }; @@ -56,6 +58,13 @@ const columnsProduct = [ field: (_) => '#check', }, + { + name: 'order', + align: 'center', + label: 'general.order', + field: (e: Product & { _index: number }) => e._index + 1, + }, + { name: '#productName', align: 'left', @@ -76,7 +85,7 @@ const columnsProduct = [ label: 'productService.product.priceInformation', field: (v: Product) => v, }, -] satisfies QTableColumn[]; +] as const satisfies QTableColumn[]; const columnsService = [ { @@ -85,6 +94,12 @@ const columnsService = [ label: '', field: (_) => '#check', }, + { + name: 'order', + align: 'center', + label: 'general.order', + field: (e: Service & { _index: number }) => e._index + 1, + }, { name: '#serviceName', @@ -110,7 +125,7 @@ const columnsService = [ label: 'general.createdAt', field: (v: Service) => dateFormatJS({ date: v.createdAt }), }, -] satisfies QTableColumn[]; +] as const satisfies QTableColumn[]; const props = defineProps(); @@ -165,7 +180,18 @@ function selectedIndex(item: any) { :props="props" > @@ -209,7 +235,17 @@ function selectedIndex(item: any) { class="text-center" > diff --git a/src/i18n/eng.ts b/src/i18n/eng.ts index 63508253..c822240c 100644 --- a/src/i18n/eng.ts +++ b/src/i18n/eng.ts @@ -20,7 +20,7 @@ export default { confirm: 'Confirm', login: 'Login', logout: 'Logout', - manage: 'Manage', + manage: 'Manage {text}', theme: 'Theme', light: 'Light', dark: 'Dark', @@ -915,6 +915,10 @@ export default { salesRepresentative: 'Sales Representative', ref: 'Reference', + action: { + title: 'Action', + configure: 'Configure', + }, status: { work: { Pending: 'Await for order', diff --git a/src/i18n/tha.ts b/src/i18n/tha.ts index d60b0045..c3205cbc 100644 --- a/src/i18n/tha.ts +++ b/src/i18n/tha.ts @@ -20,7 +20,7 @@ export default { confirm: 'ยืนยัน', login: 'เข้าสู่ระบบ', logout: 'ออกจากระบบ', - manage: 'จัดการ', + manage: 'จัดการ{text}', theme: 'ธีม', light: 'สว่าง', dark: 'มืด', @@ -904,6 +904,10 @@ export default { noWorkflowTemplate: 'คุณไม่ได้เลือกแม่แบบขั้นตอนการทำงาน', salesRepresentative: 'พนักงานขาย', ref: 'อ้างอิง', + action: { + title: 'จัดการ', + configure: 'กำหนดค่า', + }, status: { work: { Pending: 'รอสั่งงาน', diff --git a/src/pages/08_request-list/FormResponsibleUser.vue b/src/pages/08_request-list/FormResponsibleUser.vue index 5e407f57..b2bf9bb8 100644 --- a/src/pages/08_request-list/FormResponsibleUser.vue +++ b/src/pages/08_request-list/FormResponsibleUser.vue @@ -12,7 +12,6 @@ const responsibleUserId = defineModel('responsibleUserId', { defineProps<{ readonly?: boolean; districtId?: string; - cost?: boolean; }>(); watch(responsibleUserLocal, (lhs, rhs) => { diff --git a/src/pages/08_request-list/RequestAction.vue b/src/pages/08_request-list/RequestAction.vue new file mode 100644 index 00000000..b9fbf082 --- /dev/null +++ b/src/pages/08_request-list/RequestAction.vue @@ -0,0 +1,229 @@ + + + + diff --git a/src/pages/08_request-list/RequestListView.vue b/src/pages/08_request-list/RequestListView.vue index 5010461c..2f5ee598 100644 --- a/src/pages/08_request-list/RequestListView.vue +++ b/src/pages/08_request-list/RequestListView.vue @@ -11,9 +11,10 @@ import PropertiesExpansion from './PropertiesExpansion.vue'; import FormGroupHead from './FormGroupHead.vue'; import AvatarGroup from 'src/components/shared/AvatarGroup.vue'; import { StateButton } from 'components/button'; -import { CancelButton } from 'components/button'; +import { CancelButton, MainButton } from 'components/button'; import DutyExpansion from './DutyExpansion.vue'; import MessengerExpansion from './MessengerExpansion.vue'; +import RequestAction from './RequestAction.vue'; // NOTE: Store import { @@ -68,9 +69,41 @@ const statusFile = ref({ const refDocumentExpansion = ref[]>([]); const data = ref(); const flow = ref(); +const productsList = computed(() => + workList.value + ?.filter((v) => + v.productService.work?.attributes.workflowStep?.[ + pageState.currentStep - 1 + ]?.productsId.includes(v.productService.productId), + ) + .map((v) => { + const _props = + v.productService.work?.attributes?.workflowStep[ + pageState.currentStep - 1 + ]?.attributes?.properties; + return Object.assign(v, { + _documentExpansion: _props.some( + (v: PropVariant) => v.fieldName === 'documentCheck', + ), + _formExpansion: _props.some( + (v: PropVariant) => v.fieldName === 'designForm', + ), + _dutyExpansion: _props.some((v: PropVariant) => v.fieldName === 'duty'), + _messengerExpansion: _props.some( + (v: PropVariant) => v.fieldName === 'messenger', + ), + }); + }) + .sort( + (lhs, rhs) => + lhs.productService.installmentNo - rhs.productService.installmentNo, + ), +); + const pageState = reactive({ hideMetaData: false, currentStep: 1, + requestActionDialog: false, }); // NOTE: Function @@ -342,6 +375,31 @@ function closeTab() { cancel: () => {}, }); } + +function openRequestAction() { + pageState.requestActionDialog = true; +} + +async function submitRequestAction(data: { + form: { responsibleUserLocal: boolean; responsibleUserId: string }; + selected: { _work: RequestWork }[]; +}) { + const requestWorksId = data.selected.map((s) => s._work.id); + + const res = await requestListStore.actionRequestWork( + route.params['requestListId'] as string, + pageState.currentStep, + requestWorksId.map((v) => ({ + responsibleUserId: data.form.responsibleUserId, + responsibleUserLocal: data.form.responsibleUserLocal, + requestWorkId: v!, + })), + ); + if (res) { + await getData(); + pageState.requestActionDialog = false; + } +}