Skip to content

Commit

Permalink
feat(vue): improve customizability of admin pages:
Browse files Browse the repository at this point in the history
- Data sources specified via query string on c-admin-table will now be passed down to links to c-admin-editor-page.
- Standard includes string values `admin-list` and admin-editor` have been added to c-admin-editor-page and c-admin-table. These are overridable via query string.
  • Loading branch information
ascott18 committed Jun 27, 2023
1 parent 2abdca6 commit 6b48ad0
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 34 deletions.
2 changes: 2 additions & 0 deletions docs/concepts/includes.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ There are a few values of `includes` that are either set by default in the auto-
| Value | Description |
|------|---|
| `'none'` | Setting `includes` to ``none`` suppresses the [Default Loading Behavior](/modeling/model-components/data-sources.md#default-loading-behavior) provided by the [Standard Data Source](/modeling/model-components/data-sources.md#standard-data-source) - The resulting data will be the requested object (or list of objects) and nothing more. |
| `'admin-list'` | Used when loading a list of objects in the [Vue admin list page](/stacks/vue/coalesce-vue-vuetify/components/c-admin-table-page.md). |
| `'admin-editor'` | Used when loading an object in the [Vue admin editor component](/stacks/vue/coalesce-vue-vuetify/components/c-admin-editor.md). |
| `'Editor'` | Used when loading an object in the generated Knockout CreateEdit views. |
| `'<ModelName>ListGen'` | Used when loading a list of objects in the generated Knockout Table and Cards views. For example, `PersonListGen` |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ export default defineComponent({
);
}
const viewModel = new ViewModel.typeLookup![this.type]();
viewModel.$includes = "admin-editor";
return {
viewModel: new ViewModel.typeLookup![this.type](),
viewModel,
};
},
Expand Down Expand Up @@ -83,14 +86,16 @@ export default defineComponent({
},
async created() {
const params = mapQueryToParams(
this.$route.query,
ListParameters,
this.metadata
);
this.viewModel.$dataSource = params.dataSource;
if (this.id) {
await this.viewModel.$load(this.id);
} else {
const params = mapQueryToParams(
this.$route.query,
ListParameters,
this.metadata
);
if (params.filter) {
for (const propName in this.metadata.props) {
const prop = this.metadata.props[propName];
Expand All @@ -109,7 +114,12 @@ export default defineComponent({
}
}
bindKeyToRouteOnCreate(this, this.viewModel);
bindKeyToRouteOnCreate(
this,
this.viewModel,
"id",
/* keep the querystring in case it has data source parameters */ true
);
}
this.viewModel.$startAutoSave(this, { wait: 500 });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export default defineComponent({
);
}
listVM = new ListViewModel.typeLookup![this.type]();
listVM.$includes = "admin-list";
}
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ export default defineComponent({
},
query: Object.fromEntries(
Object.entries(mapParamsToDto(this.list.$params) || {}).filter(
(entry) => entry[0].startsWith("filter.")
(entry) =>
entry[0].startsWith("filter.") ||
entry[0].startsWith("dataSource")
)
),
}).resolved.fullPath;
Expand Down
38 changes: 29 additions & 9 deletions src/coalesce-vue-vuetify2/src/components/admin/c-admin-table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ export default defineComponent({
type: this.metadata.name,
id: item.$primaryKey,
},
query: this.queryBind
? // If there's a data source for the list, pass it to the edit page
// in case that data source is the only thing allowing the item to be loaded.
mapParamsToDto({ dataSource: this.viewModel.$params.dataSource })
: {},
}).resolved.fullPath;
},
},
Expand All @@ -166,16 +171,22 @@ export default defineComponent({
"replace"
);
// Pull initial parameters from the querystring before we setup watchers.
this.viewModel.$params = mapQueryToParams(
this.$route.query,
ListParameters,
this.viewModel.$metadata
);
// Establish the baseline parameters that do not need to be represented in the query string.
// I.E. don't put the default values of parameters in the query string.
const baselineParams = mapParamsToDto(this.viewModel.$params);
// When the parameters change, put them into the query string.
this.$watch(
() => mapParamsToDto(this.viewModel.$params),
(mappedParams: any, old: any) => {
// For any parameters that match the baseline parameters,
// do not put those parameters in the query string.
for (const key in baselineParams) {
if (mappedParams[key] == baselineParams[key]) {
delete mappedParams[key];
}
}
this.$router
.replace({
query: {
Expand All @@ -202,16 +213,25 @@ export default defineComponent({
{ deep: true }
);
// When the query changes, grab the new value.
// When the query changes, grab the new parameter values.
this.$watch(
() => this.$route.query,
(v: any) => {
this.viewModel.$params = mapQueryToParams(
v,
{
...baselineParams,
// Overlay the query values on top of the baseline parameters.
...Object.fromEntries(
// Vue2 Only: Vue2's router will preserve `undefined` values in `query`.
// We need to filter those out to keep them from overwriting `baselineParams`.
Object.entries(v).filter((e) => e[1] !== undefined)
),
},
ListParameters,
this.viewModel.$metadata
);
}
},
{ immediate: true }
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ export default defineComponent({
);
}
const viewModel = new ViewModel.typeLookup![props.type]();
viewModel.$includes = "admin-editor";
return {
viewModel: new ViewModel.typeLookup![props.type](),
viewModel,
};
},
Expand Down Expand Up @@ -91,14 +94,16 @@ export default defineComponent({
},
async created() {
const params = mapQueryToParams(
useRoute().query,
ListParameters,
this.metadata
);
this.viewModel.$dataSource = params.dataSource;
if (this.id) {
await this.viewModel.$load(this.id);
} else {
const params = mapQueryToParams(
useRoute().query,
ListParameters,
this.metadata
);
if (params.filter) {
for (const propName in this.metadata.props) {
const prop = this.metadata.props[propName];
Expand All @@ -117,7 +122,12 @@ export default defineComponent({
}
}
bindKeyToRouteOnCreate(this, this.viewModel);
bindKeyToRouteOnCreate(
this,
this.viewModel,
"id",
/* keep the querystring in case it has data source parameters */ true
);
}
this.viewModel.$startAutoSave(this, { wait: 500 });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default defineComponent({
);
}
listVM = ref(new ListViewModel.typeLookup![props.type]() as any);
listVM.value.$includes = "admin-list";
}
return { listVM, ...useMetadataProps(props) };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ export default defineComponent({
},
query: Object.fromEntries(
Object.entries(mapParamsToDto(this.list.$params) || {}).filter(
(entry) => entry[0].startsWith("filter.")
(entry) =>
entry[0].startsWith("filter.") ||
entry[0].startsWith("dataSource")
)
),
}).fullPath;
Expand Down
34 changes: 25 additions & 9 deletions src/coalesce-vue-vuetify3/src/components/admin/c-admin-table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ export default defineComponent({
type: this.metadata.name,
id: item.$primaryKey,
},
query: this.queryBind
? // If there's a data source for the list, pass it to the edit page
// in case that data source is the only thing allowing the item to be loaded.
mapParamsToDto({ dataSource: this.viewModel.$params.dataSource })
: {},
}).fullPath;
},
},
Expand All @@ -168,16 +173,22 @@ export default defineComponent({
"replace"
);
// Pull initial parameters from the querystring before we setup watchers.
this.viewModel.$params = mapQueryToParams(
this.router.currentRoute.value.query,
ListParameters,
this.viewModel.$metadata
);
// Establish the baseline parameters that do not need to be represented in the query string.
// I.E. don't put the default values of parameters in the query string.
const baselineParams = mapParamsToDto(this.viewModel.$params);
// When the parameters change, put them into the query string.
this.$watch(
() => mapParamsToDto(this.viewModel.$params),
(mappedParams: any, old: any) => {
// For any parameters that match the baseline parameters,
// do not put those parameters in the query string.
for (const key in baselineParams) {
if (mappedParams[key] == baselineParams[key]) {
delete mappedParams[key];
}
}
this.router
.replace({
query: {
Expand All @@ -204,16 +215,21 @@ export default defineComponent({
{ deep: true }
);
// When the query changes, grab the new value.
// When the query changes, grab the new parameter values.
this.$watch(
() => this.router.currentRoute.value.query,
(v: any) => {
this.viewModel.$params = mapQueryToParams(
v,
{
...baselineParams,
// Overlay the query values on top of the baseline parameters.
...v,
},
ListParameters,
this.viewModel.$metadata
);
}
},
{ immediate: true }
);
}
Expand Down

0 comments on commit 6b48ad0

Please sign in to comment.