pass blueprint configuration to client
This commit is contained in:
@@ -16,15 +16,7 @@ Axios.defaults.paramsSerializer = (params) =>
|
||||
};
|
||||
|
||||
Axios.interceptors.response.use(
|
||||
response =>
|
||||
{
|
||||
//if (response.headers['x-variant'] == 'api-response')
|
||||
//{
|
||||
// return response.data;
|
||||
//}
|
||||
|
||||
return response;
|
||||
},
|
||||
response => response,
|
||||
error =>
|
||||
{
|
||||
if (error.response && error.response.headers['x-variant'] == 'api-response')
|
||||
@@ -45,18 +37,31 @@ Axios.interceptors.response.use(
|
||||
|
||||
Axios.interceptors.request.use(config =>
|
||||
{
|
||||
if (location.search)
|
||||
if (!config.params)
|
||||
{
|
||||
var query = Qs.parse(location.search.substring(1));
|
||||
if (query.scope)
|
||||
{
|
||||
if (!config.params)
|
||||
{
|
||||
config.params = {};
|
||||
}
|
||||
config.params['scope'] = query.scope;
|
||||
}
|
||||
config.params = {};
|
||||
}
|
||||
|
||||
let locationQuery = Qs.parse(location.search.substring(1));
|
||||
let appKey = 'hofbauer';
|
||||
|
||||
// set app key to system when required
|
||||
if (config.params['zero.system'] === true || locationQuery['zero.shared'] === "true")
|
||||
{
|
||||
delete config.params['zero.system'];
|
||||
appKey = 'system';
|
||||
}
|
||||
|
||||
// rewrite URLs to replace {app} placeholder
|
||||
if (config.url != null && config.url.indexOf('{app}') > -1)
|
||||
{
|
||||
config.url = config.url.replace('{app}', appKey);
|
||||
}
|
||||
if (config.baseURL != null && config.baseURL.indexOf('{app}') > -1)
|
||||
{
|
||||
config.baseURL = config.baseURL.replace('{app}', appKey);
|
||||
}
|
||||
|
||||
return config;
|
||||
}, error => Promise.reject(error));
|
||||
|
||||
|
||||
@@ -35,36 +35,6 @@
|
||||
</ui-dropdown>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.ui-decision
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 16px 16px;
|
||||
font-size: var(--font-size);
|
||||
}
|
||||
|
||||
.ui-decision-button
|
||||
{
|
||||
padding: 16px 16px;
|
||||
}
|
||||
|
||||
.ui-dropdown.theme-dark .ui-decision
|
||||
{
|
||||
.ui-toggle-switch:not(.is-active)
|
||||
{
|
||||
background: var(--color-bg);
|
||||
}
|
||||
|
||||
input:focus + .ui-toggle-switch
|
||||
{
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import { useUiStore } from '../ui/store';
|
||||
@@ -99,24 +69,21 @@
|
||||
flavors: [],
|
||||
loading: false,
|
||||
asBlueprint: false,
|
||||
selectedflavor: null
|
||||
allowBlueprint: false,
|
||||
selectedflavor: null,
|
||||
store: null
|
||||
}),
|
||||
|
||||
computed: {
|
||||
hasDropdown()
|
||||
{
|
||||
return this.flavors.length > 0 || this.blueprintsEnabled;
|
||||
},
|
||||
blueprintsEnabled()
|
||||
{
|
||||
return true;
|
||||
//let blueprint = this.zero.config.blueprints.find(x => x.alias == this.blueprintAlias);
|
||||
//return this.blueprintAlias && blueprint && blueprint.enabled;
|
||||
return this.flavors.length > 0 || this.allowBlueprint;
|
||||
}
|
||||
},
|
||||
|
||||
async created()
|
||||
{
|
||||
this.store = useUiStore();
|
||||
this.buildFlavors();
|
||||
},
|
||||
|
||||
@@ -129,9 +96,11 @@
|
||||
|
||||
if (this.alias)
|
||||
{
|
||||
flavorConfig = useUiStore().flavors[this.alias];
|
||||
flavorConfig = this.store.flavors[this.alias];
|
||||
}
|
||||
|
||||
this.allowBlueprint = this.store.blueprints.indexOf(this.alias) > -1;
|
||||
|
||||
flavorConfig = flavorConfig || {
|
||||
canUseWithoutFlavors: true,
|
||||
flavors: []
|
||||
@@ -167,11 +136,11 @@
|
||||
routeObj.query = routeObj.query || {};
|
||||
if (flavor)
|
||||
{
|
||||
routeObj.query.flavor = flavor;
|
||||
routeObj.query['zero.flavor'] = flavor;
|
||||
}
|
||||
if (shared)
|
||||
{
|
||||
routeObj.query.shared = true;
|
||||
routeObj.query['zero.shared'] = true;
|
||||
}
|
||||
this.$router.push(routeObj);
|
||||
}
|
||||
@@ -186,6 +155,34 @@
|
||||
|
||||
<style>
|
||||
|
||||
.ui-decision
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 16px 16px;
|
||||
font-size: var(--font-size);
|
||||
}
|
||||
|
||||
.ui-decision-button
|
||||
{
|
||||
padding: 16px 16px;
|
||||
}
|
||||
|
||||
.ui-dropdown.theme-dark .ui-decision
|
||||
{
|
||||
.ui-toggle-switch:not(.is-active)
|
||||
{
|
||||
background: var(--color-bg);
|
||||
}
|
||||
|
||||
input:focus + .ui-toggle-switch
|
||||
{
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-add-button
|
||||
{
|
||||
display: flex;
|
||||
|
||||
@@ -129,7 +129,6 @@
|
||||
async handle(response, isCreate)
|
||||
{
|
||||
this.setState('loading');
|
||||
console.info('handle out', response);
|
||||
this.clearErrors();
|
||||
|
||||
if (!response.success)
|
||||
|
||||
@@ -5,35 +5,6 @@ import { ApiRequestConfig } from './request.types';
|
||||
|
||||
export * from './request.types';
|
||||
|
||||
function getConfig(config?: ApiRequestConfig): ApiRequestConfig
|
||||
{
|
||||
config = config || {};
|
||||
|
||||
if (config.scope)
|
||||
{
|
||||
config.params = config.params || {};
|
||||
config.params.scope = config.scope;
|
||||
}
|
||||
|
||||
if (!config.raw)
|
||||
{
|
||||
config.baseURL = paths.api;
|
||||
|
||||
const appKey = config.system ? 'system' : 'hofbauer'; // TODO
|
||||
|
||||
if (config.url != null && config.url.indexOf('{app}') > -1)
|
||||
{
|
||||
config.url = config.url.replace('{app}', appKey);
|
||||
}
|
||||
if (config.baseURL != null && config.baseURL.indexOf('{app}') > -1)
|
||||
{
|
||||
config.baseURL = config.baseURL.replace('{app}', appKey);
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
export function get(url: string, config?: ApiRequestConfig)
|
||||
{
|
||||
return send({ method: 'get', url, ...config });
|
||||
@@ -62,7 +33,15 @@ export function patch(url: string, data: any, config?: ApiRequestConfig)
|
||||
|
||||
export async function send(config: ApiRequestConfig)
|
||||
{
|
||||
config = getConfig(config);
|
||||
if (!config.raw)
|
||||
{
|
||||
config.baseURL = paths.api;
|
||||
}
|
||||
if (config.system)
|
||||
{
|
||||
config.params['zero.system'] = true;
|
||||
}
|
||||
|
||||
const result = await axios(config);
|
||||
return result.data;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ $font-text-name: 'Lato';
|
||||
|
||||
@include font-face($font-text-name, '/Assets/Fonts/Lato/LatoLatin-Black', 900);
|
||||
|
||||
@font-face {
|
||||
/*@font-face {
|
||||
font-family: 'Inter';
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
@@ -40,7 +40,7 @@ $font-text-name: 'Lato';
|
||||
font-style: italic;
|
||||
font-named-instance: 'Italic';
|
||||
src: url("/Assets/Fonts/Inter/Inter-italic.var.woff2?v=3.17") format("woff2");
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
%font
|
||||
|
||||
@@ -11,5 +11,7 @@ export default {
|
||||
|
||||
getTranslations: (config?: ApiRequestConfig): Promise<ApiResponse<Record<string, string>>> => get('backoffice/ui/translations', { ...config }),
|
||||
|
||||
getFlavors: (config?: ApiRequestConfig): Promise<ApiResponse<Record<string, UiFlavorProvider>>> => get('backoffice/ui/flavors', { ...config })
|
||||
getFlavors: (config?: ApiRequestConfig): Promise<ApiResponse<Record<string, UiFlavorProvider>>> => get('backoffice/ui/flavors', { ...config }),
|
||||
|
||||
getBlueprints: (config?: ApiRequestConfig): Promise<ApiResponse<string[]>> => get('backoffice/ui/blueprints', { ...config }),
|
||||
};
|
||||
@@ -8,7 +8,8 @@ export const useUiStore = defineStore('zero.ui', {
|
||||
sections: [],
|
||||
settingGroups: [],
|
||||
iconSets: [],
|
||||
flavors: []
|
||||
flavors: [],
|
||||
blueprints: []
|
||||
} as UiStoreState),
|
||||
|
||||
actions: {
|
||||
@@ -18,13 +19,15 @@ export const useUiStore = defineStore('zero.ui', {
|
||||
api.getSections(),
|
||||
api.getSettingGroups(),
|
||||
api.getIconSets(),
|
||||
api.getFlavors()
|
||||
api.getFlavors(),
|
||||
api.getBlueprints()
|
||||
]);
|
||||
|
||||
this.sections = values[0].data as UiSection[];
|
||||
this.settingGroups = values[1].data as UiSettingsGroup[];
|
||||
this.iconSets = values[2].data as UiIconSet[];
|
||||
this.flavors = values[3].data as Record<string, UiFlavorProvider>;
|
||||
this.blueprints = values[4].data as string[];
|
||||
}
|
||||
}
|
||||
});
|
||||
Vendored
+1
@@ -7,6 +7,7 @@ declare module 'zero/ui'
|
||||
settingGroups: UiSettingsGroup[];
|
||||
iconSets: UiIconSet[];
|
||||
flavors: Record<string, UiFlavorProvider>;
|
||||
blueprints: string[];
|
||||
}
|
||||
|
||||
export interface UiSection
|
||||
|
||||
@@ -56,4 +56,19 @@ public class UIController : ZeroBackofficeController
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("blueprints")]
|
||||
public ActionResult<IEnumerable<string>> GetBlueprints()
|
||||
{
|
||||
HashSet<string> result = new();
|
||||
|
||||
foreach (Blueprint blueprint in Options.For<BlueprintOptions>())
|
||||
{
|
||||
string key = blueprint.ContentType.GetCustomAttribute<RavenCollectionAttribute>(true)?.Name ?? blueprint.Alias;
|
||||
result.Add(Safenames.Alias(key));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace zero.Architecture;
|
||||
|
||||
@@ -161,6 +162,7 @@ public abstract class Blueprint
|
||||
/// <summary>
|
||||
/// Type of the associated entity
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public Type ContentType { get; private set; }
|
||||
|
||||
public string Alias { get; private set; }
|
||||
|
||||
@@ -6,16 +6,16 @@ public class BlueprintOptions : List<Blueprint>
|
||||
|
||||
public void Add<T>() where T : Blueprint, new()
|
||||
{
|
||||
Add(new T());
|
||||
base.Add(new T());
|
||||
}
|
||||
|
||||
public void Add<T>(Blueprint<T> implementation) where T : ZeroEntity, new()
|
||||
{
|
||||
Add(implementation);
|
||||
base.Add(implementation);
|
||||
}
|
||||
|
||||
public void Add<T>(Action<Blueprint<T>> createExpression = null) where T : ZeroEntity, new()
|
||||
{
|
||||
Add(new DefaultBlueprint<T>(createExpression));
|
||||
base.Add(new DefaultBlueprint<T>(createExpression));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,12 @@ public class BlueprintService : IBlueprintService
|
||||
blueprint = Blueprints.FirstOrDefault(x => x.ContentType.IsAssignableFrom(type));
|
||||
return blueprint != null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<Type, Blueprint> GetAllBlueprints()
|
||||
{
|
||||
return Blueprints.ToDictionary(x => x.ContentType, x => x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,4 +68,9 @@ public interface IBlueprintService
|
||||
bool TryGetBlueprint<T>(out Blueprint blueprint);
|
||||
|
||||
bool TryGetBlueprint(Type type, out Blueprint blueprint);
|
||||
|
||||
/// <summary>
|
||||
/// Get all registered blueprint configurations
|
||||
/// </summary>
|
||||
Dictionary<Type, Blueprint> GetAllBlueprints();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using zero;
|
||||
using zero.Api;
|
||||
using zero.Applications;
|
||||
using zero.Architecture;
|
||||
using zero.Backoffice;
|
||||
using zero.Backoffice.DevServer;
|
||||
using zero.Demo;
|
||||
@@ -32,6 +33,11 @@ builder.Services.Configure<FlavorOptions>(opts =>
|
||||
//opts.Add<Country, AmericanCountry>("usa_country", "USA", "A country in the United States", "fth-flag");
|
||||
});
|
||||
|
||||
builder.Services.Configure<BlueprintOptions>(opts =>
|
||||
{
|
||||
opts.Add<Country>();
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
|
||||
Reference in New Issue
Block a user