Add developer toolkit UI component
The commit adds a new a UI component that's enabled in development mode. This component, initially, provides a button that wen clicked, logs all the script and category names to the console. It helps revising names used throughout the application. By having this component in a conditionally rendered component, it's excluded from the production builds.
This commit is contained in:
@@ -7,11 +7,12 @@
|
|||||||
<TheCodeButtons class="app__row app__code-buttons" />
|
<TheCodeButtons class="app__row app__code-buttons" />
|
||||||
<TheFooter />
|
<TheFooter />
|
||||||
</div>
|
</div>
|
||||||
|
<OptionalDevToolkit />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||||
import TheHeader from '@/presentation/components/TheHeader.vue';
|
import TheHeader from '@/presentation/components/TheHeader.vue';
|
||||||
import TheFooter from '@/presentation/components/TheFooter/TheFooter.vue';
|
import TheFooter from '@/presentation/components/TheFooter/TheFooter.vue';
|
||||||
import TheCodeButtons from '@/presentation/components/Code/CodeButtons/TheCodeButtons.vue';
|
import TheCodeButtons from '@/presentation/components/Code/CodeButtons/TheCodeButtons.vue';
|
||||||
@@ -22,6 +23,10 @@ import { provideDependencies } from '../bootstrapping/DependencyProvider';
|
|||||||
|
|
||||||
const singletonAppContext = await buildContext();
|
const singletonAppContext = await buildContext();
|
||||||
|
|
||||||
|
const OptionalDevToolkit = process.env.NODE_ENV !== 'production'
|
||||||
|
? defineAsyncComponent(() => import('@/presentation/components/DevToolkit/DevToolkit.vue'))
|
||||||
|
: null;
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
TheHeader,
|
TheHeader,
|
||||||
@@ -29,6 +34,7 @@ export default defineComponent({
|
|||||||
TheScriptArea,
|
TheScriptArea,
|
||||||
TheSearchBar,
|
TheSearchBar,
|
||||||
TheFooter,
|
TheFooter,
|
||||||
|
OptionalDevToolkit,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
provideDependencies(singletonAppContext); // In Vue 3.0 we can move it to main.ts
|
provideDependencies(singletonAppContext); // In Vue 3.0 we can move it to main.ts
|
||||||
@@ -59,5 +65,4 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
71
src/presentation/components/DevToolkit/DevToolkit.vue
Normal file
71
src/presentation/components/DevToolkit/DevToolkit.vue
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<template>
|
||||||
|
<div class="dev-toolkit">
|
||||||
|
<div class="title">
|
||||||
|
Tools
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<button
|
||||||
|
v-for="action in devActions"
|
||||||
|
@click="action.handler"
|
||||||
|
:key="action.name"
|
||||||
|
type="button">
|
||||||
|
{{ action.name }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { dumpNames } from './DumpNames';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
setup() {
|
||||||
|
const devActions: readonly DevAction[] = [
|
||||||
|
{
|
||||||
|
name: 'Log script/category names',
|
||||||
|
handler: async () => {
|
||||||
|
const names = await dumpNames();
|
||||||
|
console.log(names);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
devActions,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
interface DevAction {
|
||||||
|
readonly name: string;
|
||||||
|
readonly handler: () => void | Promise<void>;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@use "@/presentation/assets/styles/main" as *;
|
||||||
|
|
||||||
|
.dev-toolkit {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba($color-on-surface, 0.5);
|
||||||
|
color: $color-on-primary;
|
||||||
|
padding: 10px;
|
||||||
|
z-index: 10000;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
background-color: $color-primary;
|
||||||
|
color: $color-on-primary;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
35
src/presentation/components/DevToolkit/DumpNames.ts
Normal file
35
src/presentation/components/DevToolkit/DumpNames.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { IApplication } from '@/domain/IApplication';
|
||||||
|
import { ApplicationFactory } from '@/application/ApplicationFactory';
|
||||||
|
|
||||||
|
export async function dumpNames(): Promise<string> {
|
||||||
|
const application = await ApplicationFactory.Current.getApp();
|
||||||
|
const names = collectNames(application);
|
||||||
|
const output = names.join('\n');
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectNames(application: IApplication): string[] {
|
||||||
|
const { collections } = application;
|
||||||
|
|
||||||
|
const allNames = [
|
||||||
|
...collections.flatMap((collection) => collection.getAllCategories().map((c) => c.name)),
|
||||||
|
...collections.flatMap((collection) => collection.getAllScripts().map((c) => c.name)),
|
||||||
|
];
|
||||||
|
|
||||||
|
const uniqueNames = [...new Set(allNames)];
|
||||||
|
|
||||||
|
return shuffle(uniqueNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Shuffle an array of strings, returning a new array with elements in random order.
|
||||||
|
Uses the Fisher-Yates (or Durstenfeld) algorithm.
|
||||||
|
*/
|
||||||
|
function shuffle(array: readonly string[]): string[] {
|
||||||
|
const shuffledArray = [...array];
|
||||||
|
for (let i = array.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[shuffledArray[i], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i]];
|
||||||
|
}
|
||||||
|
return shuffledArray;
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
Reference in New Issue
Block a user