Skip to content

Commit

Permalink
Refactor project and organization forms to use local reactive data
Browse files Browse the repository at this point in the history
- Refactored ProjectForm.vue and OrganizationForm.vue to use local reactive data for form inputs, instead of directly manipulating store data.
- Updated corresponding store modules to accommodate changes in form components.
- Created a new type definition for Project in projectTypes.ts.
  • Loading branch information
kneoio committed Jul 1, 2024
1 parent dad2c30 commit cbed337
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 82 deletions.
30 changes: 22 additions & 8 deletions src/components/forms/OrganizationForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,31 @@
<n-grid :cols="1" x-gap="12" y-gap="12" class="m-3">
<n-gi>
<n-form-item label="Category">
<n-input v-model:value="store.getCurrent.orgCategory.localizedName"
<n-input v-model:value="localData.orgCategory.localizedName"
style="width: 50%; max-width: 600px;"/>
</n-form-item>
</n-gi>
<n-gi v-for="(_, key) in store.getCurrent.localizedName" :key="key">
<n-gi v-for="(_, key) in localData.localizedName" :key="key">
<n-form-item :label="`Name (${key})`">
<n-input v-model:value="store.getCurrent.localizedName[key]"
<n-input v-model:value="localData.localizedName[key]"
style="width: 50%; max-width: 600px;"/>
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="Business ID">
<n-input v-model:value="store.getCurrent.bizID"
<n-input v-model:value="localData.bizID"
style="width: 50%; max-width: 600px;"/>
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="Identifier">
<n-input v-model:value="store.getCurrent.identifier"
<n-input v-model:value="localData.identifier"
style="width: 50%; max-width: 600px;"/>
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="Rank">
<n-input-number v-model:value="store.getCurrent.rank"
<n-input-number v-model:value="localData.rank"
style="width: 10%"/>
</n-form-item>
</n-gi>
Expand All @@ -67,14 +67,15 @@
</template>

<script lang="ts">
import {defineComponent, ref, onMounted, computed} from 'vue';
import {defineComponent, ref, onMounted, computed, reactive} from 'vue';
import {useRoute, useRouter} from 'vue-router';
import {
NPageHeader, NButton, NButtonGroup, NForm, NFormItem, NInput, NInputNumber, NIcon, NTabs, NTabPane, NGrid,
NGi, NH2, NDatePicker, NSpace
} from 'naive-ui';
import {ArrowBigLeft} from '@vicons/tabler';
import {useOrganizationStore} from "../../stores/of/organizationStore";
import {Organization} from "../../types/officeFrameTypes";
export default defineComponent({
name: 'OrganizationForm',
Expand All @@ -88,9 +89,20 @@ export default defineComponent({
const store = useOrganizationStore();
const activeTab = ref('properties');
const localizedNames = computed(() => store.getCurrent.localizedName || {});
const localData = reactive<Organization>({
id: '',
identifier: '',
bizID: '',
localizedName: {},
orgCategory: {
localizedName: ''
},
status: '',
rank: 0,
});
const handleSaveProject = async () => {
await store.save();
await store.save(localData);
router.push('/references/organizations');
};
Expand All @@ -105,10 +117,12 @@ export default defineComponent({
onMounted(async () => {
const id = route.params.id as string;
await store.fetch(id);
Object.assign(localData, store.getCurrent);
});
return {
store,
localData,
localizedNames,
handleSaveProject,
handleArchive,
Expand Down
32 changes: 23 additions & 9 deletions src/components/forms/ProjectForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</n-timeline>
</n-gi>
<n-gi>
<n-h2>Project: {{ projectStore.projectFields }}</n-h2>
<n-h2>Project: {{ localData.name }}</n-h2>
</n-gi>
<n-gi>
<n-tabs v-model:value="activeTab">
Expand All @@ -34,27 +34,27 @@
<n-grid x-gap="12" y-gap="12">
<n-gi span="24">
<n-form-item label="Name" class="short-field">
<n-input v-model:value="projectStore.projectFields.name" style="width: 100%; max-width: 600px;"/>
<n-input v-model:value="localData.name" style="width: 100%; max-width: 600px;"/>
</n-form-item>
</n-gi>
<n-gi span="24">
<n-form-item label="Status" class="short-field">
<n-select v-model:value="projectStore.projectFields.status" :options="statusOptions"
<n-select v-model:value="localData.status" :options="statusOptions"
style="width: 100%; max-width: 300px;"/>
</n-form-item>
</n-gi>
<n-gi span="24">
<n-form-item label="Finish Date" class="short-field">
<n-date-picker
v-model:formatted-value="projectStore.projectFields.finishDate"
v-model:formatted-value="localData.finishDate"
value-format="yyyy-MM-dd"
clearable
style="width: 100%; max-width: 300px;"/>
</n-form-item>
</n-gi>
<n-gi span="24">
<n-form-item label="Manager" class="short-field">
<!-- <n-select v-model:value="projectStore.projectFields.manager.id" :options="officeFrameStore.employeeOptions"
<!-- <n-select v-model:value="localData.manager.name" :options="officeFrameStore.employeeOptions"
style="width: 100%; max-width: 600px;"/>-->
</n-form-item>
</n-gi>
Expand All @@ -75,7 +75,7 @@
</n-tab-pane>
<n-tab-pane name="rls" tab="RLS">
<n-dynamic-input
v-model:value="projectStore.projectFields.rls"
v-model:value="localData.rls"

Check failure on line 78 in src/components/forms/ProjectForm.vue

View workflow job for this annotation

GitHub Actions / deploy

Property 'rls' does not exist on type '{ id: string; author: string | undefined; lastModifier: string | undefined; name: string; status: string; finishDate: string | undefined; manager: string; coder: string; tester: string | undefined; selected?: boolean | undefined; }'.
:on-remove="handleRemoveReader"
>
<template #default="{ value }">
Expand All @@ -100,7 +100,7 @@
</template>

<script lang="ts">
import { defineComponent, ref, onMounted } from 'vue';
import {defineComponent, ref, onMounted, reactive} from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useProjectStore } from '../../stores/projectStore';
import {
Expand All @@ -124,9 +124,10 @@ import {
} from 'naive-ui';
import { ArrowBigLeft } from '@vicons/tabler';
import {useEmployeeStore} from "../../stores/of/employeeStore";
import {Project} from "../../types/projectTypes";
export default defineComponent({
name: 'KneoProjectForm',
name: 'ProjectForm',
components: {
NButtonGroup,
NForm,
Expand All @@ -153,6 +154,17 @@ export default defineComponent({
const projectStore = useProjectStore();
const employeeStore = useEmployeeStore();
const activeTab = ref('properties');
const localData = reactive<Project>({
author: undefined, lastModifier: undefined,
id: '',
status: '',
name: '',
finishDate: undefined,
manager: '',
coder: '',
tester: '',
rls:[]

Check failure on line 166 in src/components/forms/ProjectForm.vue

View workflow job for this annotation

GitHub Actions / deploy

Object literal may only specify known properties, and 'rls' does not exist in type 'Project'.
});
const statusOptions = [
{ label: 'Draft', value: 'DRAFT' },
Expand All @@ -177,17 +189,19 @@ export default defineComponent({
};
const handleRemoveReader = (index: number) => {

Check failure on line 191 in src/components/forms/ProjectForm.vue

View workflow job for this annotation

GitHub Actions / deploy

'index' is declared but its value is never read.
projectStore.projectFields.rls.splice(index, 1);
};
onMounted(async () => {
const projectId = route.params.id as string;
await projectStore.fetchProject(projectId);
Object.assign(localData, projectStore.getCurrent);
});
return {
projectStore,
localData,
employeeStore,
statusOptions,
accessLevelOptions,
Expand Down
52 changes: 22 additions & 30 deletions src/stores/of/organizationStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,53 +76,45 @@ export const useOrganizationStore = defineStore('organizationStore', () => {
loadingBar.start();
const response = await apiClient.get(`/orgs/${id}`);

if (response && response.data) {
console.log('API Response:', response.data);

if (response.data.payload) {
apiFormResponse.value = response.data.payload;
console.log('apiFormResponse.value set to:', apiFormResponse.value);
} else {
throw new Error('Missing payload in API response');
}
if (response && response.data && response.data.payload) {
apiFormResponse.value = response.data.payload;
} else {
throw new Error('Invalid API response structure');
}
} catch (error: any) {
loadingBar.error();

if (error instanceof Error) {
console.error('Fetch error:', error.message);
msgPopup.error(`Failed to fetch: ${error.message}`);
} else {
console.error('Unknown fetch error:', error);
msgPopup.error('Failed to fetch: Unknown error');
}

console.error('Fetch error:', error);
msgPopup.error(`Failed to fetch: ${error.message || 'Unknown error'}`);
throw error;
} finally {
loadingBar.finish();
}
};

const save = async () => {
const updateCurrent = (data: Organization, actions: any = {}) => {
apiFormResponse.value = {
docData: data,
actions: actions
};
};

const save = async (data: Organization) => {
try {
loadingBar.start();
if (apiFormResponse.value) {
const id = null;
const response = await apiClient.put(`/orgs/${id}`, apiFormResponse.value);
if (response && response.data.payload) {
apiFormResponse.value = response.data.payload.docData;
msgPopup.success('Project saved successfully');
} else {
throw new Error('Invalid API response structure');
}
const response = await apiClient.post('/orgs', data);

if (response && response.data && response.data.payload) {
const { docData, actions } = response.data.payload;
updateCurrent(docData, actions);
msgPopup.success('Organization saved successfully');
return docData;
} else {
throw new Error('No project data to save');
throw new Error('Invalid API response structure');
}
} catch (error: any) {
loadingBar.error();
msgPopup.error('Failed to save project: ' + (error.message || 'Unknown error'));
msgPopup.error('Failed to save organization: ' + (error.message || 'Unknown error'));
throw error;
} finally {
loadingBar.finish();
}
Expand Down
38 changes: 22 additions & 16 deletions src/stores/projectStore.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import {defineStore} from 'pinia';
import {ref, computed} from 'vue';
import apiClient from '../api/apiClient';
import {ApiFormResponse, ApiViewPageResponse, Project} from "../types";
import { useLoadingBar, useMessage } from 'naive-ui';
import {ApiFormResponse, ApiViewPageResponse} from "../types";
import {useLoadingBar, useMessage} from 'naive-ui';
import {Project} from "../types/projectTypes";

export const useProjectStore = defineStore('projectsStore', () => {
const apiViewResponse = ref<ApiViewPageResponse<Project> | null>(null);
Expand All @@ -11,23 +12,28 @@ export const useProjectStore = defineStore('projectsStore', () => {
const msgPopup = useMessage();
const loadingBar = useLoadingBar();

const getCurrentProject = computed(() => apiFormResponse.value?.payload.docData || {
id: '',
name: '',
status: '',
finishDate: '',
manager: '',
coder: '',
tester: '',
rls: [],
primaryLang: ''
const getCurrent = computed(() => {
const defaultData = {
regDate: '',
lastModifiedDate: '',
id: '',
name: '',
status: '',
finishDate: '',
manager: '',
coder: '',
tester: '',
rls: [],
primaryLang: ''
};
return apiFormResponse.value?.docData || defaultData;
});

const getEntries = computed(() => {
return apiViewResponse.value?.viewData.entries || [];
});

const fetchProjects = async (page = 1, pageSize = 10 ) => {
const fetchProjects = async (page = 1, pageSize = 10) => {
try {
loadingBar.start();
const response = await apiClient.get(`/projects?page=${page}&size=${pageSize}`);
Expand Down Expand Up @@ -94,6 +100,6 @@ export const useProjectStore = defineStore('projectsStore', () => {
fetchProjects,
fetchProject,
saveProject,
projectFields: getCurrentProject
getCurrent
};
});
13 changes: 0 additions & 13 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,6 @@ export interface ViewData<T = any> {
entries: T[];
}

export interface Project {
id: string;
author: string | undefined;
lastModifier: string | undefined;
name: string;
status: string;
finishDate: string | undefined;
manager: string;
coder: string;
tester: string | undefined;
selected?: boolean;
}

export interface KneoGeneric {
id: string;
author: string | undefined;
Expand Down
16 changes: 10 additions & 6 deletions src/types/officeFrameTypes.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@

export interface Organization {
docData: {
id: string;
author: string;
regDate: string;
lastModifier: string;
lastModifiedDate: string;
id?: string; // Optional for new organizations
identifier: string;
bizID: string;
localizedName: Record<string, string>;
orgCategory: {
localizedName: string;
};
status: string;
rank: number;
// Other properties...
}

export interface Employer {
Expand Down
12 changes: 12 additions & 0 deletions src/types/projectTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export interface Project {
id: string;
author: string | undefined;
lastModifier: string | undefined;
name: string;
status: string;
finishDate: string | undefined;
manager: string;
coder: string;
tester: string | undefined;
selected?: boolean;
}

0 comments on commit cbed337

Please sign in to comment.