@fishawack/lab-velocity 2.0.0-beta.24 → 2.0.0-beta.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,7 +23,12 @@
23
23
  <!-- Support a custom render function -->
24
24
  <template v-if="item.render" #default="scope">
25
25
  <component
26
- :is="item.render({ model: scope.row, ...this })"
26
+ :is="
27
+ item.render({
28
+ model: scope.row,
29
+ $emit,
30
+ })
31
+ "
27
32
  />
28
33
  </template>
29
34
  </el-table-column>
@@ -118,7 +123,7 @@ export default {
118
123
  default: true,
119
124
  },
120
125
  },
121
- emits: ["sort"],
126
+ emits: ["sort", "reload"],
122
127
 
123
128
  methods: {
124
129
  handleSort(data) {
@@ -80,6 +80,7 @@
80
80
  :display-show-action="displayShowAction"
81
81
  :display-edit-action="displayEditAction"
82
82
  @sort="handleSort"
83
+ @reload="reload"
83
84
  >
84
85
  <slot name="table-content"></slot>
85
86
  </VelTable>
@@ -128,10 +129,10 @@ export default {
128
129
  default: true,
129
130
  type: Boolean,
130
131
  },
131
- defaults: {
132
+ apiParams: {
132
133
  required: false,
133
- type: String,
134
- default: "",
134
+ type: Object,
135
+ default: () => ({}),
135
136
  },
136
137
  displayActions: {
137
138
  type: Boolean,
@@ -159,7 +160,7 @@ export default {
159
160
  return {
160
161
  search: null,
161
162
  sort: "-id",
162
- query: [],
163
+ query: {},
163
164
  table_data: [],
164
165
  table_meta: null,
165
166
  };
@@ -176,13 +177,21 @@ export default {
176
177
  },
177
178
 
178
179
  methods: {
180
+ reload() {
181
+ this.fetchData({ page: this.table_meta.current_page }).then(
182
+ (data) => {
183
+ this.table_data = data.data;
184
+ this.table_meta = data.meta;
185
+ },
186
+ );
187
+ },
179
188
  handleSearch(data) {
180
189
  if (data === null || data.length < 3) {
181
- this.query = [];
190
+ this.query = {};
182
191
  } else {
183
- this.query = [
184
- `filter[${this.$refs.search.$el.dataset.key}]=${data}`,
185
- ];
192
+ this.query = {
193
+ [`filter[${this.$refs.search.$el.dataset.key}]`]: data,
194
+ };
186
195
  }
187
196
  this.fetchData({}).then((data) => {
188
197
  this.table_data = data.data;
@@ -203,17 +212,15 @@ export default {
203
212
  },
204
213
 
205
214
  fetchData: function ({ page = "1" }) {
206
- const mergedQuery = [
207
- ...this.query,
208
- this.defaults,
209
- `sort=${this.sort}`,
210
- `page=${page}`,
211
- ];
212
-
213
- const query = mergedQuery.join("&");
214
-
215
215
  return axios
216
- .get(`${this.$props.jsonData.api}${query ? "?" + query : ""}`)
216
+ .get(`${this.$props.jsonData.api}`, {
217
+ params: {
218
+ sort: this.sort,
219
+ page: page,
220
+ ...this.query,
221
+ ...this.apiParams,
222
+ },
223
+ })
217
224
  .then((res) => res.data)
218
225
  .catch(console.log);
219
226
  },
@@ -179,7 +179,9 @@ export default {
179
179
 
180
180
  mounted() {
181
181
  axios
182
- .getAll(`/api/users?filter[company_id]=${this.$route.params.id}`)
182
+ .getAll(
183
+ `/api/users?filter[company_id]=${this.$route.params.companiesId}`,
184
+ )
183
185
  .then((res) => {
184
186
  this.users = res.data.data;
185
187
  });
@@ -9,13 +9,17 @@ import userResource from "../PUsers/resource.js";
9
9
  import { defaultResource, meta } from "../../../resource/index.js";
10
10
 
11
11
  import { ElNotification } from "element-plus";
12
- import { h } from "vue";
12
+ import { h, resolveComponent } from "vue";
13
13
  import axios from "axios";
14
14
 
15
15
  export default [
16
16
  "companies",
17
17
  {
18
- defaults: "include=primary_contact",
18
+ api: {
19
+ params: {
20
+ show: { include: "primary_contact" },
21
+ },
22
+ },
19
23
  permissions: {
20
24
  create: ({ $store }) => $store.getters.can("write companies"),
21
25
  edit: ({ $store }) => $store.getters.can("write companies"),
@@ -148,23 +152,47 @@ export default [
148
152
  form: { roles: model.roles.map((d) => d.id) },
149
153
  readonly: true,
150
154
  }),
151
- ({ model, $store }) => {
155
+ ({ model, $store, $router, ...rest }) => {
152
156
  const resource = meta(...userResource);
153
157
 
154
- return h(VelTableSorter, {
155
- key: "PIndex",
156
- "json-data": {
157
- ...resource,
158
- tableStructure: resource.table.structure,
159
- },
160
- defaults: `include=company&filter[company_id]=${model.id}`,
161
- idKey: resource.id,
162
- "fixed-height": false,
163
- "display-create-action":
164
- $store.getters.can("write users"),
165
- "display-edit-action":
166
- $store.getters.can("write users"),
167
- });
158
+ resource.api.params.index["filter[company_id]"] = model.id;
159
+
160
+ const props = {
161
+ model,
162
+ $store,
163
+ $router,
164
+ ...rest,
165
+ resource,
166
+ };
167
+
168
+ return h("div", [
169
+ h("div", { class: "flex justify-end items-end" }, [
170
+ resource.permissions.create(props) &&
171
+ h(
172
+ VelButton,
173
+ {
174
+ tag: "a",
175
+ type: "primary",
176
+ size: "large",
177
+ onClick: () => {
178
+ $router.push({
179
+ name: `${resource.slug}.create`,
180
+ });
181
+ },
182
+ },
183
+ () => [
184
+ h(resolveComponent("GIcon"), {
185
+ class: "fill-0 mr-0.5 icon--0.5",
186
+ name: "icon-plus",
187
+ embed: true,
188
+ artboard: true,
189
+ }),
190
+ `Create ${resource.singular}`,
191
+ ],
192
+ ),
193
+ ]),
194
+ h(VelTableSorter, resource.index.structure(props)),
195
+ ]);
168
196
  },
169
197
  ],
170
198
  },
@@ -24,7 +24,12 @@ function generatePassword(
24
24
  export default [
25
25
  "users",
26
26
  {
27
- defaults: "include=company",
27
+ api: {
28
+ params: {
29
+ index: { include: "company" },
30
+ show: { include: "company" },
31
+ },
32
+ },
28
33
  searchable: {
29
34
  value: "email",
30
35
  },
@@ -136,7 +141,7 @@ export default [
136
141
  model.company_id,
137
142
  },
138
143
  },
139
- text: model.company.name,
144
+ text: model.company?.name,
140
145
  }),
141
146
  },
142
147
  {
@@ -53,7 +53,7 @@ export default {
53
53
  } else {
54
54
  try {
55
55
  let res = await this.form.post(
56
- `${this.resource.api(this)}`,
56
+ `${this.resource.api.endpoint(this)}`,
57
57
  );
58
58
 
59
59
  this.$router.replace({
@@ -51,7 +51,10 @@ export default {
51
51
  async mounted() {
52
52
  window.axios
53
53
  .get(
54
- `${this.resource.api(this)}/${this.$route.params[this.resource.id]}?${this.resource.defaults}`,
54
+ `${this.resource.api.endpoint(this)}/${this.$route.params[this.resource.id]}`,
55
+ {
56
+ params: this.resource.api.params.show,
57
+ },
55
58
  )
56
59
  .then((res) => {
57
60
  this.model = res.data.data;
@@ -72,7 +75,7 @@ export default {
72
75
  } else {
73
76
  try {
74
77
  let res = await this.form.patch(
75
- `${this.resource.api(this)}/${this.model.id}`,
78
+ `${this.resource.api.endpoint(this)}/${this.model.id}`,
76
79
  );
77
80
 
78
81
  this.$router.replace({
@@ -11,7 +11,7 @@
11
11
  <div class="bg-0 p-3 box-shadow-1 border-r-4 mb-6">
12
12
  <VelPageHeader
13
13
  :icon="resource.icon"
14
- :title="`${model.name} ${model.last_name ?? ''}`"
14
+ :title="`${model.name ?? model.id} ${model.last_name ?? ''}`"
15
15
  >
16
16
  <template
17
17
  v-for="(render, index) in resource.show.actions"
@@ -89,7 +89,10 @@ export default {
89
89
 
90
90
  axios
91
91
  .get(
92
- `${this.resource.api(this)}/${this.$route.params[`${this.resource.slug}Id`]}?${this.resource.defaults}`,
92
+ `${this.resource.api.endpoint(this)}/${this.$route.params[`${this.resource.slug}Id`]}`,
93
+ {
94
+ params: this.resource.api.params.show,
95
+ },
93
96
  )
94
97
  .then((res) => {
95
98
  this.model = res.data.data;
@@ -4,7 +4,7 @@ import { merge, kebabCase, cloneDeepWith } from "lodash";
4
4
  import axios from "axios";
5
5
  import { h, resolveComponent } from "vue";
6
6
 
7
- import VTableSorter from "../../components/layout/TableSorter.vue";
7
+ import VelTableSorter from "../../components/layout/TableSorter.vue";
8
8
  import { ElDescriptions, ElDescriptionsItem, ElPopconfirm } from "element-plus";
9
9
  import VelButton from "../../components/basic/Button.vue";
10
10
 
@@ -23,7 +23,14 @@ export function meta(name = "default", properties = {}) {
23
23
  multiLabel: name,
24
24
  slug,
25
25
  id: properties.id || `${slug}Id`,
26
- api: () => `/api/${properties.slug || kebabCase(name)}`,
26
+ icon: `icon-${singular}`,
27
+ api: {
28
+ endpoint: () => `/api/${properties.slug || kebabCase(name)}`,
29
+ params: {
30
+ index: {},
31
+ show: {},
32
+ },
33
+ },
27
34
  permissions: {
28
35
  create: () => true,
29
36
  edit: () => true,
@@ -39,6 +46,82 @@ export function meta(name = "default", properties = {}) {
39
46
  structure: [],
40
47
  },
41
48
  table: {
49
+ actions: [
50
+ ({ $router, resource, model }) =>
51
+ h(
52
+ VelButton,
53
+ {
54
+ tag: "a",
55
+ size: "small",
56
+ type: "primary",
57
+ onClick: () => {
58
+ $router.push({
59
+ name: `${resource.slug}.show`,
60
+ params: {
61
+ [resource.id]: model.id,
62
+ },
63
+ });
64
+ },
65
+ },
66
+ () => "View",
67
+ ),
68
+ (props) => {
69
+ const { $router, resource, model } = props;
70
+
71
+ if (resource.permissions.edit(props)) {
72
+ return h(
73
+ VelButton,
74
+ {
75
+ tag: "a",
76
+ size: "small",
77
+ onClick: () => {
78
+ $router.push({
79
+ name: `${resource.slug}.edit`,
80
+ params: {
81
+ [resource.id]: model.id,
82
+ },
83
+ });
84
+ },
85
+ },
86
+ () => "Edit",
87
+ );
88
+ }
89
+ },
90
+ (props) => {
91
+ const { resource, model, $emit } = props;
92
+
93
+ if (resource.permissions.delete(props)) {
94
+ return h(
95
+ ElPopconfirm,
96
+ {
97
+ title: `Are you sure you want to delete this ${resource.singular}?`,
98
+ confirmButtonText: "Delete",
99
+ cancelButtonText: "Cancel",
100
+ confirmButtonType: "danger",
101
+ onConfirm: async () => {
102
+ await axios.delete(
103
+ `${resource.api.endpoint(props)}/${model.id}`,
104
+ );
105
+
106
+ $emit("reload");
107
+ },
108
+ },
109
+ {
110
+ reference: () =>
111
+ h(
112
+ VelButton,
113
+ {
114
+ tag: "a",
115
+ type: "danger",
116
+ size: "small",
117
+ },
118
+ () => `Delete`,
119
+ ),
120
+ },
121
+ );
122
+ }
123
+ },
124
+ ],
42
125
  structure: [
43
126
  {
44
127
  key: "id",
@@ -53,26 +136,88 @@ export function meta(name = "default", properties = {}) {
53
136
  ],
54
137
  },
55
138
  index: {
56
- actions: [],
139
+ structure: (props) => {
140
+ const { resource, $router, $route, $store, ...rest } =
141
+ props;
142
+
143
+ return {
144
+ key: "PIndex",
145
+ "json-data": {
146
+ ...resource,
147
+ tableStructure: resource.table.structure.concat(
148
+ resource.table.actions.length
149
+ ? [
150
+ {
151
+ key: "actions",
152
+ render: ({ model, $emit }) =>
153
+ h(
154
+ "div",
155
+ {
156
+ class: "flex gap-2",
157
+ },
158
+ resource.table.actions.map(
159
+ (d) =>
160
+ d({
161
+ resource,
162
+ $router,
163
+ $route,
164
+ $store,
165
+ ...rest,
166
+ model,
167
+ $emit,
168
+ }),
169
+ ),
170
+ ),
171
+ },
172
+ ]
173
+ : [],
174
+ ),
175
+ api: resource.api.endpoint(props),
176
+ },
177
+ apiParams: resource.api.params.index,
178
+ idKey: resource.id,
179
+ "fixed-height": false,
180
+ displayActions: false,
181
+ };
182
+ },
183
+ actions: [
184
+ (props) => {
185
+ const { resource, $router } = props;
186
+
187
+ if (resource.permissions.create(props)) {
188
+ return h(
189
+ VelButton,
190
+ {
191
+ tag: "a",
192
+ type: "primary",
193
+ size: "large",
194
+ onClick: () => {
195
+ $router.push({
196
+ name: `${resource.slug}.create`,
197
+ });
198
+ },
199
+ },
200
+ () => [
201
+ h(resolveComponent("GIcon"), {
202
+ class: "fill-0 mr-0.5 icon--0.5",
203
+ name: "icon-plus",
204
+ embed: true,
205
+ artboard: true,
206
+ }),
207
+ `Create ${resource.singular}`,
208
+ ],
209
+ );
210
+ }
211
+ },
212
+ ],
57
213
  layout: [
58
214
  (props) => {
59
215
  const { resource } = props;
60
216
 
61
- return h(VTableSorter, {
62
- key: "PIndex",
63
- "json-data": {
64
- ...resource,
65
- tableStructure: resource.table.structure,
66
- api: resource.api(props),
67
- },
68
- defaults: resource.defaults,
69
- idKey: resource.id,
70
- "fixed-height": false,
71
- "display-create-action":
72
- resource.permissions.create(props),
73
- "display-edit-action":
74
- resource.permissions.edit(props),
75
- });
217
+ return h(
218
+ VelTableSorter,
219
+ resource.index.structure(props),
220
+ );
76
221
  },
77
222
  ],
78
223
  },
@@ -121,7 +266,7 @@ export function meta(name = "default", properties = {}) {
121
266
  confirmButtonType: "danger",
122
267
  onConfirm: async () => {
123
268
  await axios.delete(
124
- `${resource.api(props)}/${model.id}`,
269
+ `${resource.api.endpoint(props)}/${model.id}`,
125
270
  );
126
271
 
127
272
  $router.push({
@@ -188,8 +333,6 @@ export function meta(name = "default", properties = {}) {
188
333
  },
189
334
  ],
190
335
  },
191
- defaults: "",
192
- icon: `icon-${singular}`,
193
336
  },
194
337
  properties,
195
338
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fishawack/lab-velocity",
3
- "version": "2.0.0-beta.24",
3
+ "version": "2.0.0-beta.25",
4
4
  "description": "Avalere Health branded style system",
5
5
  "scripts": {
6
6
  "setup": "npm ci || npm i && npm run content",