Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
331f5a7dd5 | |||
1973348040 | |||
1d06e9e71b | |||
aecc379d0a | |||
1b4ffeae2b | |||
241486fc4f | |||
399407b15a | |||
316d917f6e | |||
c09941ebe9 |
53
.drone.yml
Normal file
53
.drone.yml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: kubernetes
|
||||||
|
name: default
|
||||||
|
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
pod-security.kubernetes.io/audit: privileged
|
||||||
|
|
||||||
|
services:
|
||||||
|
- name: docker daemon
|
||||||
|
image: docker:dind
|
||||||
|
privileged: true
|
||||||
|
environment:
|
||||||
|
DOCKER_TLS_CERTDIR: ""
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- tag
|
||||||
|
- promote
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: node.js build
|
||||||
|
image: node:18
|
||||||
|
commands:
|
||||||
|
- "npm add --global pnpm"
|
||||||
|
- pnpm i
|
||||||
|
- pnpm run build
|
||||||
|
|
||||||
|
- name: container build
|
||||||
|
image: docker:latest
|
||||||
|
privileged: true
|
||||||
|
commands:
|
||||||
|
- "while ! docker stats --no-stream; do sleep 1; done"
|
||||||
|
- "docker build -t $DOCKER_REGISTRY/glmdev/mathy ."
|
||||||
|
- "docker push $DOCKER_REGISTRY/glmdev/mathy"
|
||||||
|
environment:
|
||||||
|
DOCKER_HOST: tcp://localhost:2375
|
||||||
|
DOCKER_REGISTRY:
|
||||||
|
from_secret: DOCKER_REGISTRY
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- tag
|
||||||
|
- promote
|
||||||
|
|
||||||
|
- name: k8s rollout
|
||||||
|
image: bitnami/kubectl
|
||||||
|
commands:
|
||||||
|
- cd deploy && kubectl apply -f .
|
||||||
|
- kubectl rollout -n mathy restart deployment/mathy
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- tag
|
||||||
|
- promote
|
56
deploy.yaml
56
deploy.yaml
@ -1,56 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: mathy
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
name: mathy
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
name: mathy
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: mathy
|
|
||||||
image: glmdev/mathy:latest
|
|
||||||
imagePullPolicy: Always
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: mathy-service
|
|
||||||
spec:
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
port: 80
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: 80
|
|
||||||
selector:
|
|
||||||
name: mathy
|
|
||||||
---
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: mathy-ingress
|
|
||||||
annotations:
|
|
||||||
kubernetes.io/ingress.class: "nginx"
|
|
||||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
|
||||||
spec:
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- mathy.glmdev.tech
|
|
||||||
secretName: mathy-tls
|
|
||||||
rules:
|
|
||||||
- host: "mathy.glmdev.tech"
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- pathType: Prefix
|
|
||||||
path: "/"
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: mathy-service
|
|
||||||
port:
|
|
||||||
number: 80
|
|
5
deploy/0-namespace.yaml
Normal file
5
deploy/0-namespace.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: mathy
|
12
deploy/1-certificate.yaml
Normal file
12
deploy/1-certificate.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: mathy-tls
|
||||||
|
namespace: mathy
|
||||||
|
spec:
|
||||||
|
secretName: mathy-tls
|
||||||
|
dnsNames:
|
||||||
|
- 'crystalmath.garrettmills.dev'
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt-ca
|
||||||
|
kind: ClusterIssuer
|
127
deploy/2-deploy.yaml
Normal file
127
deploy/2-deploy.yaml
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mathy
|
||||||
|
namespace: mathy
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
name: mathy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
name: mathy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: mathy
|
||||||
|
image: glmdev/mathy:latest
|
||||||
|
imagePullPolicy: Always
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mathy-api
|
||||||
|
namespace: mathy
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
name: mathy-api
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
name: mathy-api
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: mathy
|
||||||
|
image: glmdev/mathy-api:latest
|
||||||
|
imagePullPolicy: Always
|
||||||
|
env:
|
||||||
|
- name: REDIS_HOST
|
||||||
|
value: localhost
|
||||||
|
- name: DATABASE_HOST
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: psql-conn
|
||||||
|
key: host
|
||||||
|
optional: false
|
||||||
|
- name: DATABASE_USERNAME
|
||||||
|
value: mathy
|
||||||
|
- name: DATABASE_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: psql-conn
|
||||||
|
key: password
|
||||||
|
optional: false
|
||||||
|
- name: DATABASE_NAME
|
||||||
|
value: mathy
|
||||||
|
ports:
|
||||||
|
- containerPort: 8000
|
||||||
|
|
||||||
|
- name: redis
|
||||||
|
image: redis:latest
|
||||||
|
imagePullPolicy: Always
|
||||||
|
ports:
|
||||||
|
- containerPort: 6379
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mathy-api-service
|
||||||
|
namespace: mathy
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: 8000
|
||||||
|
selector:
|
||||||
|
name: mathy-api
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mathy-service
|
||||||
|
namespace: mathy
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: 80
|
||||||
|
selector:
|
||||||
|
name: mathy
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: mathy-ingress
|
||||||
|
namespace: mathy
|
||||||
|
annotations:
|
||||||
|
kubernetes.io/ingress.class: "nginx"
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
|
spec:
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- crystalmath.garrettmills.dev
|
||||||
|
secretName: mathy-tls
|
||||||
|
rules:
|
||||||
|
- host: "crystalmath.garrettmills.dev"
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- pathType: Prefix
|
||||||
|
path: "/api"
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: mathy-api-service
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
- pathType: Prefix
|
||||||
|
path: "/"
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: mathy-service
|
||||||
|
port:
|
||||||
|
number: 80
|
@ -9,10 +9,10 @@
|
|||||||
"lint": "eslint . --ext .ts",
|
"lint": "eslint . --ext .ts",
|
||||||
"lint:fix": "eslint --fix . --ext .ts",
|
"lint:fix": "eslint --fix . --ext .ts",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"cd:build": "pnpm run build && docker image build . -t glmdev/mathy",
|
"cd:build": "pnpm run build && docker image build . -t ${DOCKER_REGISTRY}/glmdev/mathy",
|
||||||
"cd:push": "docker push glmdev/mathy",
|
"cd:push": "docker push ${DOCKER_REGISTRY}/glmdev/mathy",
|
||||||
"cd:deploy": "kubectl apply -f deploy.yaml",
|
"cd:deploy": "kubectl apply -f deploy/1-certificate.yaml -f deploy/2-deploy.yaml",
|
||||||
"cd:rollout": "kubectl rollout restart deployment/mathy",
|
"cd:rollout": "kubectl rollout -n mathy restart deployment/mathy",
|
||||||
"cd": "pnpm run cd:build && pnpm run cd:push && pnpm run cd:rollout"
|
"cd": "pnpm run cd:build && pnpm run cd:push && pnpm run cd:rollout"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -3,10 +3,11 @@ import * as math from 'mathjs'
|
|||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { LineChart } from 'vue-chart-3'
|
import { LineChart } from 'vue-chart-3'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { Chart, ChartData, ChartOptions, registerables } from 'chart.js'
|
import { Chart, ChartData, registerables } from 'chart.js'
|
||||||
import { MathStatement } from '../support/parse'
|
import { MathStatement } from '../support/parse'
|
||||||
import { ChartBox } from '../support/types'
|
import { ChartBox } from '../support/types'
|
||||||
import { stepX, stepY } from '../support/const'
|
import { stepX, stepY } from '../support/const'
|
||||||
|
import {MathPage} from '../support/page'
|
||||||
|
|
||||||
Chart.register(...registerables)
|
Chart.register(...registerables)
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ const emit = defineEmits<{
|
|||||||
}>()
|
}>()
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
page: MathPage,
|
||||||
fn: MathStatement,
|
fn: MathStatement,
|
||||||
value: ChartBox,
|
value: ChartBox,
|
||||||
}>()
|
}>()
|
||||||
@ -69,27 +71,33 @@ const getChartData = (): ChartData<'line'> => {
|
|||||||
throw new TypeError('Cannot chart node that is not a function.')
|
throw new TypeError('Cannot chart node that is not a function.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const evaluationResult = props.page.evaluate()
|
||||||
const node = props.fn.parse() as math.FunctionAssignmentNode
|
const node = props.fn.parse() as math.FunctionAssignmentNode
|
||||||
const fn = node.compile().evaluate() // FIXME need dependencies in scope
|
const fn = node.compile().evaluate(evaluationResult.scope)
|
||||||
|
|
||||||
console.log('getChartData', {
|
|
||||||
labels: range.map(x => `${x}`),
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: node.name,
|
|
||||||
data: range.map(n => fn(n)),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
return {
|
return {
|
||||||
labels: range.map(x => `${x}`),
|
labels: range.map(x => `${x}`),
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: node.name,
|
label: node.name,
|
||||||
backgroundColor: '#553564',
|
backgroundColor: '#553564',
|
||||||
|
borderColor: '#ccc',
|
||||||
data: range.map(x => fn(x)),
|
data: range.map(x => fn(x)),
|
||||||
pointRadius: 5
|
pointRadius: 5
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
} catch (_) {
|
||||||
|
return {
|
||||||
|
labels: [],
|
||||||
|
datasets: [{
|
||||||
|
label: '',
|
||||||
|
backgroundColor: '#553564',
|
||||||
|
borderColor: '#ccc',
|
||||||
|
data: [],
|
||||||
|
pointRadius: 5
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const chartData = ref(getChartData())
|
const chartData = ref(getChartData())
|
||||||
|
@ -103,6 +103,7 @@ const openEditFunctionModal = () => {
|
|||||||
editFunctionModalOpen.value = true
|
editFunctionModalOpen.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const chartBoxKey = ref(uuidv4())
|
||||||
const updateStatements = () => {
|
const updateStatements = () => {
|
||||||
statements.value = math.value.getStatements();
|
statements.value = math.value.getStatements();
|
||||||
try {
|
try {
|
||||||
@ -153,18 +154,21 @@ const saveNewVariable = (stmt: MathStatement) => {
|
|||||||
math.value.addStatement(stmt)
|
math.value.addStatement(stmt)
|
||||||
newVariableModalOpen.value = false
|
newVariableModalOpen.value = false
|
||||||
updateStatements()
|
updateStatements()
|
||||||
|
chartBoxKey.value = uuidv4()
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveNewExpression = (stmt: MathStatement) => {
|
const saveNewExpression = (stmt: MathStatement) => {
|
||||||
math.value.addStatement(stmt)
|
math.value.addStatement(stmt)
|
||||||
newExpressionModalOpen.value = false
|
newExpressionModalOpen.value = false
|
||||||
updateStatements()
|
updateStatements()
|
||||||
|
chartBoxKey.value = uuidv4()
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveNewFunction = (stmt: MathStatement) => {
|
const saveNewFunction = (stmt: MathStatement) => {
|
||||||
math.value.addStatement(stmt)
|
math.value.addStatement(stmt)
|
||||||
newFunctionModalOpen.value = false
|
newFunctionModalOpen.value = false
|
||||||
updateStatements()
|
updateStatements()
|
||||||
|
chartBoxKey.value = uuidv4()
|
||||||
}
|
}
|
||||||
|
|
||||||
const editStatement = (stmt: MathStatement) => {
|
const editStatement = (stmt: MathStatement) => {
|
||||||
@ -182,6 +186,7 @@ const editStatement = (stmt: MathStatement) => {
|
|||||||
const removeStatement = (stmt: MathStatement) => {
|
const removeStatement = (stmt: MathStatement) => {
|
||||||
math.value.removeStatement(stmt.id)
|
math.value.removeStatement(stmt.id)
|
||||||
updateStatements()
|
updateStatements()
|
||||||
|
chartBoxKey.value = uuidv4()
|
||||||
}
|
}
|
||||||
|
|
||||||
const finishEditStatement = () => {
|
const finishEditStatement = () => {
|
||||||
@ -189,6 +194,7 @@ const finishEditStatement = () => {
|
|||||||
editVarDeclModalOpen.value = false
|
editVarDeclModalOpen.value = false
|
||||||
editFunctionModalOpen.value = false
|
editFunctionModalOpen.value = false
|
||||||
updateStatements()
|
updateStatements()
|
||||||
|
chartBoxKey.value = uuidv4()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -202,7 +208,6 @@ const makeNewRichTextBox = () => {
|
|||||||
richEditModal.value = true;
|
richEditModal.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const chartBoxKey = ref(uuidv4())
|
|
||||||
const chartBoxes = ref<ChartBox[]>([])
|
const chartBoxes = ref<ChartBox[]>([])
|
||||||
|
|
||||||
const newChartModalOpen = ref(false)
|
const newChartModalOpen = ref(false)
|
||||||
@ -213,6 +218,7 @@ const openNewChartModal = () => {
|
|||||||
const saveNewChartBox = (chartBox: ChartBox) => {
|
const saveNewChartBox = (chartBox: ChartBox) => {
|
||||||
chartBoxes.value.push(chartBox)
|
chartBoxes.value.push(chartBox)
|
||||||
newChartModalOpen.value = false
|
newChartModalOpen.value = false
|
||||||
|
chartBoxKey.value = uuidv4()
|
||||||
}
|
}
|
||||||
|
|
||||||
const editingChartBox = ref<ChartBox | undefined>()
|
const editingChartBox = ref<ChartBox | undefined>()
|
||||||
@ -271,7 +277,7 @@ const removeRichTextBox = (id: number) => {
|
|||||||
const makeNewImageBox = () => {
|
const makeNewImageBox = () => {
|
||||||
images.value.push(new ImageContainer(''));
|
images.value.push(new ImageContainer(''));
|
||||||
imageID.value = images.value.length - 1;
|
imageID.value = images.value.length - 1;
|
||||||
imageURL.value = images.value[richEditID.value].url;
|
imageURL.value = images.value[imageID.value].url;
|
||||||
imageModal.value = true;
|
imageModal.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -362,9 +368,12 @@ const saveEditorPage = async (close = false) => {
|
|||||||
return alert('Failed to save page: ' + result.message)
|
return alert('Failed to save page: ' + result.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const justCreated = !editorPageId.value
|
||||||
editorPageId.value = result.data.pageId
|
editorPageId.value = result.data.pageId
|
||||||
if ( close ) {
|
if ( close ) {
|
||||||
await router.push('/Listings')
|
await router.push('/Listings')
|
||||||
|
} else if ( justCreated ) {
|
||||||
|
await router.push(`/Editor/${editorPageId.value}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,6 +524,7 @@ onMounted(() => {
|
|||||||
<q-page-container id="editor" style='padding: 0'>
|
<q-page-container id="editor" style='padding: 0'>
|
||||||
<span v-for="(chartBox, index) in chartBoxes" style="display: flex">
|
<span v-for="(chartBox, index) in chartBoxes" style="display: flex">
|
||||||
<RangeChart
|
<RangeChart
|
||||||
|
:page="math"
|
||||||
:fn="math.getFunctionByNameOrFail(chartBox.fnName)"
|
:fn="math.getFunctionByNameOrFail(chartBox.fnName)"
|
||||||
:key="chartBoxKey"
|
:key="chartBoxKey"
|
||||||
:value="chartBox"
|
:value="chartBox"
|
||||||
|
@ -197,6 +197,7 @@ export class MathPage {
|
|||||||
return {
|
return {
|
||||||
variables: nonFunctionalScope,
|
variables: nonFunctionalScope,
|
||||||
statements: evaluations,
|
statements: evaluations,
|
||||||
|
scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@ export type EvaluatedValue = TypeTag<'@app.EvaluatedValue'> & string
|
|||||||
export interface EvaluationResult {
|
export interface EvaluationResult {
|
||||||
variables: Record<VariableName, any>
|
variables: Record<VariableName, any>
|
||||||
statements: Record<StatementID, any>
|
statements: Record<StatementID, any>
|
||||||
|
scope: Record<VariableName, any>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user