mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
feat(site): implement site status management and update related components
This commit is contained in:
parent
402de5d987
commit
502b656bc5
12 changed files with 93 additions and 99 deletions
|
@ -28,11 +28,6 @@ func GetSite(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
enabled := true
|
|
||||||
if _, err := os.Stat(nginx.GetConfPath("sites-enabled", name)); os.IsNotExist(err) {
|
|
||||||
enabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
g := query.ChatGPTLog
|
g := query.ChatGPTLog
|
||||||
chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
|
chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -63,15 +58,15 @@ func GetSite(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, Site{
|
c.JSON(http.StatusOK, site.Site{
|
||||||
ModifiedAt: file.ModTime(),
|
ModifiedAt: file.ModTime(),
|
||||||
Site: siteModel,
|
Site: siteModel,
|
||||||
Enabled: enabled,
|
|
||||||
Name: name,
|
Name: name,
|
||||||
Config: string(origContent),
|
Config: string(origContent),
|
||||||
AutoCert: certModel.AutoCert == model.AutoCertEnabled,
|
AutoCert: certModel.AutoCert == model.AutoCertEnabled,
|
||||||
ChatGPTMessages: chatgpt.Content,
|
ChatGPTMessages: chatgpt.Content,
|
||||||
Filepath: path,
|
Filepath: path,
|
||||||
|
Status: site.GetSiteStatus(name),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -96,10 +91,9 @@ func GetSite(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, Site{
|
c.JSON(http.StatusOK, site.Site{
|
||||||
Site: siteModel,
|
Site: siteModel,
|
||||||
ModifiedAt: file.ModTime(),
|
ModifiedAt: file.ModTime(),
|
||||||
Enabled: enabled,
|
|
||||||
Name: name,
|
Name: name,
|
||||||
Config: nginxConfig.FmtCode(),
|
Config: nginxConfig.FmtCode(),
|
||||||
Tokenized: nginxConfig,
|
Tokenized: nginxConfig,
|
||||||
|
@ -107,6 +101,7 @@ func GetSite(c *gin.Context) {
|
||||||
CertInfo: certInfoMap,
|
CertInfo: certInfoMap,
|
||||||
ChatGPTMessages: chatgpt.Content,
|
ChatGPTMessages: chatgpt.Content,
|
||||||
Filepath: path,
|
Filepath: path,
|
||||||
|
Status: site.GetSiteStatus(name),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,16 @@ import type { ModelBase } from '@/api/curd'
|
||||||
import type { EnvGroup } from '@/api/env_group'
|
import type { EnvGroup } from '@/api/env_group'
|
||||||
import type { NgxConfig } from '@/api/ngx'
|
import type { NgxConfig } from '@/api/ngx'
|
||||||
import type { ChatComplicationMessage } from '@/api/openai'
|
import type { ChatComplicationMessage } from '@/api/openai'
|
||||||
import type { PrivateKeyType } from '@/constants'
|
import type { ConfigStatus, PrivateKeyType } from '@/constants'
|
||||||
import Curd from '@/api/curd'
|
import Curd from '@/api/curd'
|
||||||
import http from '@/lib/http'
|
import http from '@/lib/http'
|
||||||
|
|
||||||
|
export type SiteStatus = ConfigStatus.Enabled | ConfigStatus.Disabled | ConfigStatus.Maintenance
|
||||||
|
|
||||||
export interface Site extends ModelBase {
|
export interface Site extends ModelBase {
|
||||||
modified_at: string
|
modified_at: string
|
||||||
path: string
|
path: string
|
||||||
advanced: boolean
|
advanced: boolean
|
||||||
enabled: boolean
|
|
||||||
name: string
|
name: string
|
||||||
filepath: string
|
filepath: string
|
||||||
config: string
|
config: string
|
||||||
|
@ -23,7 +24,7 @@ export interface Site extends ModelBase {
|
||||||
env_group?: EnvGroup
|
env_group?: EnvGroup
|
||||||
sync_node_ids: number[]
|
sync_node_ids: number[]
|
||||||
urls?: string[]
|
urls?: string[]
|
||||||
status: string
|
status: SiteStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AutoCertRequest {
|
export interface AutoCertRequest {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Cert, CertificateInfo } from '@/api/cert'
|
import type { Cert, CertificateInfo } from '@/api/cert'
|
||||||
import type { NgxDirective } from '@/api/ngx'
|
import type { NgxDirective } from '@/api/ngx'
|
||||||
|
import type { SiteStatus } from '@/api/site'
|
||||||
|
import { ConfigStatus } from '@/constants'
|
||||||
import CertInfo from '@/views/site/cert/CertInfo.vue'
|
import CertInfo from '@/views/site/cert/CertInfo.vue'
|
||||||
import ChangeCert from '@/views/site/cert/components/ChangeCert/ChangeCert.vue'
|
import ChangeCert from '@/views/site/cert/components/ChangeCert/ChangeCert.vue'
|
||||||
import IssueCert from '@/views/site/cert/IssueCert.vue'
|
import IssueCert from '@/views/site/cert/IssueCert.vue'
|
||||||
|
@ -9,7 +11,7 @@ const props = defineProps<{
|
||||||
configName: string
|
configName: string
|
||||||
currentServerIndex: number
|
currentServerIndex: number
|
||||||
certInfo?: CertificateInfo[]
|
certInfo?: CertificateInfo[]
|
||||||
siteEnabled: boolean
|
siteStatus: SiteStatus
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const current_server_directives = defineModel<NgxDirective[]>('current_server_directives')
|
const current_server_directives = defineModel<NgxDirective[]>('current_server_directives')
|
||||||
|
@ -96,7 +98,7 @@ function handleCertChange(certs: Cert[]) {
|
||||||
<ChangeCert @change="handleCertChange" />
|
<ChangeCert @change="handleCertChange" />
|
||||||
|
|
||||||
<IssueCert
|
<IssueCert
|
||||||
v-if="siteEnabled"
|
v-if="siteStatus === ConfigStatus.Enabled || siteStatus === ConfigStatus.Maintenance"
|
||||||
v-model:enabled="enabled"
|
v-model:enabled="enabled"
|
||||||
:config-name="configName"
|
:config-name="configName"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,28 +1,17 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { SiteStatus } from '@/api/site'
|
||||||
import site from '@/api/site'
|
import site from '@/api/site'
|
||||||
import { ConfigStatus } from '@/constants'
|
import { ConfigStatus } from '@/constants'
|
||||||
import { message, Modal } from 'ant-design-vue'
|
import { message, Modal } from 'ant-design-vue'
|
||||||
|
|
||||||
/**
|
|
||||||
* Component props interface
|
|
||||||
*/
|
|
||||||
interface Props {
|
|
||||||
/**
|
|
||||||
* The name of the site configuration
|
|
||||||
*/
|
|
||||||
siteName: string
|
|
||||||
/**
|
|
||||||
* Whether the site is enabled
|
|
||||||
*/
|
|
||||||
enabled: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define props with TypeScript
|
// Define props with TypeScript
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<{
|
||||||
|
siteName: string
|
||||||
|
}>()
|
||||||
|
|
||||||
// Define event for status change notification
|
// Define event for status change notification
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
statusChanged: [{ status: string, enabled: boolean }]
|
statusChanged: [{ status: SiteStatus }]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// Use defineModel for v-model binding
|
// Use defineModel for v-model binding
|
||||||
|
@ -32,73 +21,59 @@ const status = defineModel<string>({
|
||||||
|
|
||||||
const [modal, ContextHolder] = Modal.useModal()
|
const [modal, ContextHolder] = Modal.useModal()
|
||||||
|
|
||||||
/**
|
// Enable the site
|
||||||
* Enable the site
|
|
||||||
*/
|
|
||||||
function enable() {
|
function enable() {
|
||||||
site.enable(props.siteName).then(() => {
|
site.enable(props.siteName).then(() => {
|
||||||
message.success($gettext('Enabled successfully'))
|
message.success($gettext('Enabled successfully'))
|
||||||
status.value = ConfigStatus.Enabled
|
status.value = ConfigStatus.Enabled
|
||||||
emit('statusChanged', {
|
emit('statusChanged', {
|
||||||
status: ConfigStatus.Enabled,
|
status: ConfigStatus.Enabled,
|
||||||
enabled: true,
|
|
||||||
})
|
})
|
||||||
}).catch(r => {
|
}).catch(r => {
|
||||||
message.error($gettext('Failed to enable %{msg}', { msg: r.message ?? '' }), 10)
|
message.error($gettext('Failed to enable %{msg}', { msg: r.message ?? '' }), 10)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Disable the site
|
||||||
* Disable the site
|
|
||||||
*/
|
|
||||||
function disable() {
|
function disable() {
|
||||||
site.disable(props.siteName).then(() => {
|
site.disable(props.siteName).then(() => {
|
||||||
message.success($gettext('Disabled successfully'))
|
message.success($gettext('Disabled successfully'))
|
||||||
status.value = ConfigStatus.Disabled
|
status.value = ConfigStatus.Disabled
|
||||||
emit('statusChanged', {
|
emit('statusChanged', {
|
||||||
status: ConfigStatus.Disabled,
|
status: ConfigStatus.Disabled,
|
||||||
enabled: false,
|
|
||||||
})
|
})
|
||||||
}).catch(r => {
|
}).catch(r => {
|
||||||
message.error($gettext('Failed to disable %{msg}', { msg: r.message ?? '' }))
|
message.error($gettext('Failed to disable %{msg}', { msg: r.message ?? '' }))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Enable maintenance mode for the site
|
||||||
* Enable maintenance mode for the site
|
|
||||||
*/
|
|
||||||
function enableMaintenance() {
|
function enableMaintenance() {
|
||||||
site.enableMaintenance(props.siteName).then(() => {
|
site.enableMaintenance(props.siteName).then(() => {
|
||||||
message.success($gettext('Maintenance mode enabled successfully'))
|
message.success($gettext('Maintenance mode enabled successfully'))
|
||||||
status.value = ConfigStatus.Maintenance
|
status.value = ConfigStatus.Maintenance
|
||||||
emit('statusChanged', {
|
emit('statusChanged', {
|
||||||
status: ConfigStatus.Maintenance,
|
status: ConfigStatus.Maintenance,
|
||||||
enabled: true,
|
|
||||||
})
|
})
|
||||||
}).catch(r => {
|
}).catch(r => {
|
||||||
message.error($gettext('Failed to enable maintenance mode %{msg}', { msg: r.message ?? '' }))
|
message.error($gettext('Failed to enable maintenance mode %{msg}', { msg: r.message ?? '' }))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Disable maintenance mode for the site
|
||||||
* Disable maintenance mode for the site
|
|
||||||
*/
|
|
||||||
function disableMaintenance() {
|
function disableMaintenance() {
|
||||||
site.enable(props.siteName).then(() => {
|
site.enable(props.siteName).then(() => {
|
||||||
message.success($gettext('Maintenance mode disabled successfully'))
|
message.success($gettext('Maintenance mode disabled successfully'))
|
||||||
status.value = ConfigStatus.Enabled
|
status.value = ConfigStatus.Enabled
|
||||||
emit('statusChanged', {
|
emit('statusChanged', {
|
||||||
status: ConfigStatus.Enabled,
|
status: ConfigStatus.Enabled,
|
||||||
enabled: true,
|
|
||||||
})
|
})
|
||||||
}).catch(r => {
|
}).catch(r => {
|
||||||
message.error($gettext('Failed to disable maintenance mode %{msg}', { msg: r.message ?? '' }))
|
message.error($gettext('Failed to disable maintenance mode %{msg}', { msg: r.message ?? '' }))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Handle status change from segmented control
|
||||||
* Handle status change from segmented control
|
|
||||||
*/
|
|
||||||
function onChangeStatus(value: string | number) {
|
function onChangeStatus(value: string | number) {
|
||||||
const statusValue = value as string
|
const statusValue = value as string
|
||||||
if (statusValue === status.value) {
|
if (statusValue === status.value) {
|
||||||
|
@ -148,7 +123,7 @@ function onChangeStatus(value: string | number) {
|
||||||
<div class="site-status-segmented">
|
<div class="site-status-segmented">
|
||||||
<ContextHolder />
|
<ContextHolder />
|
||||||
<ASegmented
|
<ASegmented
|
||||||
v-model:value="status"
|
:value="status"
|
||||||
:options="[
|
:options="[
|
||||||
{
|
{
|
||||||
value: ConfigStatus.Enabled,
|
value: ConfigStatus.Enabled,
|
|
@ -1,27 +1,27 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { CertificateInfo } from '@/api/cert'
|
import type { CertificateInfo } from '@/api/cert'
|
||||||
import type { NgxConfig, NgxDirective } from '@/api/ngx'
|
import type { NgxConfig, NgxDirective } from '@/api/ngx'
|
||||||
|
import type { SiteStatus } from '@/api/site'
|
||||||
import type { CheckedType } from '@/types'
|
import type { CheckedType } from '@/types'
|
||||||
import type { ComputedRef } from 'vue'
|
import type { ComputedRef } from 'vue'
|
||||||
import template from '@/api/template'
|
import template from '@/api/template'
|
||||||
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
||||||
|
import { ConfigStatus } from '@/constants'
|
||||||
import NginxStatusAlert from '@/views/site/ngx_conf/NginxStatusAlert.vue'
|
import NginxStatusAlert from '@/views/site/ngx_conf/NginxStatusAlert.vue'
|
||||||
import NgxServer from '@/views/site/ngx_conf/NgxServer.vue'
|
import NgxServer from '@/views/site/ngx_conf/NgxServer.vue'
|
||||||
import NgxUpstream from '@/views/site/ngx_conf/NgxUpstream.vue'
|
import NgxUpstream from '@/views/site/ngx_conf/NgxUpstream.vue'
|
||||||
import { Modal } from 'ant-design-vue'
|
import { Modal } from 'ant-design-vue'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
withDefaults(defineProps<{
|
||||||
autoCert?: boolean
|
status?: SiteStatus
|
||||||
enabled?: boolean
|
|
||||||
certInfo?: Record<number, CertificateInfo[]>
|
certInfo?: Record<number, CertificateInfo[]>
|
||||||
context?: 'http' | 'stream'
|
context?: 'http' | 'stream'
|
||||||
}>(), {
|
}>(), {
|
||||||
autoCert: false,
|
status: ConfigStatus.Enabled,
|
||||||
enabled: false,
|
|
||||||
context: 'http',
|
context: 'http',
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['callback', 'update:autoCert'])
|
const autoCert = defineModel<boolean>('autoCert')
|
||||||
|
|
||||||
const save_config = inject('save_config') as () => Promise<void>
|
const save_config = inject('save_config') as () => Promise<void>
|
||||||
|
|
||||||
|
@ -158,15 +158,6 @@ const support_ssl = computed(() => {
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
const autoCertRef = computed({
|
|
||||||
get() {
|
|
||||||
return props.autoCert
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
emit('update:autoCert', value)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
provide('directivesMap', directivesMap)
|
provide('directivesMap', directivesMap)
|
||||||
|
|
||||||
const activeKey = ref(['3'])
|
const activeKey = ref(['3'])
|
||||||
|
@ -211,9 +202,9 @@ const activeKey = ref(['3'])
|
||||||
header="Server"
|
header="Server"
|
||||||
>
|
>
|
||||||
<NgxServer
|
<NgxServer
|
||||||
v-model:auto-cert="autoCertRef"
|
v-model:auto-cert="autoCert"
|
||||||
:enabled
|
:status
|
||||||
:cert-info="certInfo"
|
:cert-info
|
||||||
:context
|
:context
|
||||||
/>
|
/>
|
||||||
</ACollapsePanel>
|
</ACollapsePanel>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { CertificateInfo } from '@/api/cert'
|
import type { CertificateInfo } from '@/api/cert'
|
||||||
import type { NgxConfig, NgxDirective } from '@/api/ngx'
|
import type { NgxConfig, NgxDirective } from '@/api/ngx'
|
||||||
|
import type { SiteStatus } from '@/api/site'
|
||||||
|
import { ConfigStatus } from '@/constants'
|
||||||
import Cert from '@/views/site/cert/Cert.vue'
|
import Cert from '@/views/site/cert/Cert.vue'
|
||||||
import ConfigTemplate from '@/views/site/ngx_conf/config_template/ConfigTemplate.vue'
|
import ConfigTemplate from '@/views/site/ngx_conf/config_template/ConfigTemplate.vue'
|
||||||
import DirectiveEditor from '@/views/site/ngx_conf/directive/DirectiveEditor.vue'
|
import DirectiveEditor from '@/views/site/ngx_conf/directive/DirectiveEditor.vue'
|
||||||
|
@ -10,13 +12,14 @@ import { MoreOutlined, PlusOutlined } from '@ant-design/icons-vue'
|
||||||
import { Modal } from 'ant-design-vue'
|
import { Modal } from 'ant-design-vue'
|
||||||
|
|
||||||
withDefaults(defineProps<{
|
withDefaults(defineProps<{
|
||||||
enabled: boolean
|
|
||||||
certInfo?: {
|
certInfo?: {
|
||||||
[key: number]: CertificateInfo[]
|
[key: number]: CertificateInfo[]
|
||||||
}
|
}
|
||||||
context?: 'http' | 'stream'
|
context?: 'http' | 'stream'
|
||||||
|
status?: SiteStatus
|
||||||
}>(), {
|
}>(), {
|
||||||
context: 'http',
|
context: 'http',
|
||||||
|
status: ConfigStatus.Enabled,
|
||||||
})
|
})
|
||||||
|
|
||||||
const [modal, ContextHolder] = Modal.useModal()
|
const [modal, ContextHolder] = Modal.useModal()
|
||||||
|
@ -125,7 +128,7 @@ provide('ngx_directives', ngx_directives)
|
||||||
v-model:enabled="autoCert"
|
v-model:enabled="autoCert"
|
||||||
v-model:current_server_directives="ngx_config.servers[current_server_index].directives"
|
v-model:current_server_directives="ngx_config.servers[current_server_index].directives"
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
:site-enabled="enabled"
|
:site-status="status"
|
||||||
:config-name="ngx_config.name"
|
:config-name="ngx_config.name"
|
||||||
:cert-info="certInfo?.[k]"
|
:cert-info="certInfo?.[k]"
|
||||||
:current-server-index="current_server_index"
|
:current-server-index="current_server_index"
|
||||||
|
|
|
@ -1,39 +1,30 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { ChatComplicationMessage } from '@/api/openai'
|
import type { ChatComplicationMessage } from '@/api/openai'
|
||||||
import type { Site } from '@/api/site'
|
import type { Site, SiteStatus } from '@/api/site'
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
import envGroup from '@/api/env_group'
|
import envGroup from '@/api/env_group'
|
||||||
import ChatGPT from '@/components/ChatGPT/ChatGPT.vue'
|
import ChatGPT from '@/components/ChatGPT/ChatGPT.vue'
|
||||||
import NodeSelector from '@/components/NodeSelector/NodeSelector.vue'
|
import NodeSelector from '@/components/NodeSelector/NodeSelector.vue'
|
||||||
import StdSelector from '@/components/StdDesign/StdDataEntry/components/StdSelector.vue'
|
import StdSelector from '@/components/StdDesign/StdDataEntry/components/StdSelector.vue'
|
||||||
import { ConfigStatus } from '@/constants'
|
|
||||||
import { formatDateTime } from '@/lib/helper'
|
import { formatDateTime } from '@/lib/helper'
|
||||||
import { useSettingsStore } from '@/pinia'
|
import { useSettingsStore } from '@/pinia'
|
||||||
import envGroupColumns from '@/views/environments/group/columns'
|
import envGroupColumns from '@/views/environments/group/columns'
|
||||||
|
import SiteStatusSegmented from '@/views/site/components/SiteStatusSegmented.vue'
|
||||||
import ConfigName from '@/views/site/site_edit/components/ConfigName.vue'
|
import ConfigName from '@/views/site/site_edit/components/ConfigName.vue'
|
||||||
import SiteStatusSegmented from '@/views/site/site_edit/components/SiteStatusSegmented.vue'
|
|
||||||
import { InfoCircleOutlined } from '@ant-design/icons-vue'
|
import { InfoCircleOutlined } from '@ant-design/icons-vue'
|
||||||
|
|
||||||
const settings = useSettingsStore()
|
const settings = useSettingsStore()
|
||||||
|
|
||||||
const configText = inject('configText') as Ref<string>
|
const configText = inject('configText') as Ref<string>
|
||||||
const enabled = inject('enabled') as Ref<boolean>
|
|
||||||
const name = inject('name') as ComputedRef<string>
|
const name = inject('name') as ComputedRef<string>
|
||||||
const filepath = inject('filepath') as Ref<string>
|
const filepath = inject('filepath') as Ref<string>
|
||||||
const historyChatgptRecord = inject('history_chatgpt_record') as Ref<ChatComplicationMessage[]>
|
const historyChatgptRecord = inject('history_chatgpt_record') as Ref<ChatComplicationMessage[]>
|
||||||
const data = inject('data') as Ref<Site>
|
const data = inject('data') as Ref<Site>
|
||||||
|
|
||||||
const activeKey = ref(['1', '2', '3'])
|
const activeKey = ref(['1', '2', '3'])
|
||||||
const siteStatus = computed(() => {
|
|
||||||
if (!data.value?.status) {
|
|
||||||
return enabled.value ? ConfigStatus.Enabled : ConfigStatus.Disabled
|
|
||||||
}
|
|
||||||
return data.value.status
|
|
||||||
})
|
|
||||||
|
|
||||||
function handleStatusChanged(event: { status: string, enabled: boolean }) {
|
function handleStatusChanged(event: { status: SiteStatus }) {
|
||||||
data.value.status = event.status
|
data.value.status = event.status
|
||||||
enabled.value = event.enabled
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -54,9 +45,8 @@ function handleStatusChanged(event: { status: string, enabled: boolean }) {
|
||||||
<AForm layout="vertical">
|
<AForm layout="vertical">
|
||||||
<AFormItem :label="$gettext('Status')">
|
<AFormItem :label="$gettext('Status')">
|
||||||
<SiteStatusSegmented
|
<SiteStatusSegmented
|
||||||
v-model="siteStatus"
|
v-model="data.status"
|
||||||
:site-name="name"
|
:site-name="name"
|
||||||
:enabled="enabled"
|
|
||||||
@status-changed="handleStatusChanged"
|
@status-changed="handleStatusChanged"
|
||||||
/>
|
/>
|
||||||
</AFormItem>
|
</AFormItem>
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import type { CertificateInfo } from '@/api/cert'
|
import type { CertificateInfo } from '@/api/cert'
|
||||||
import type { NgxConfig } from '@/api/ngx'
|
import type { NgxConfig } from '@/api/ngx'
|
||||||
import type { ChatComplicationMessage } from '@/api/openai'
|
import type { ChatComplicationMessage } from '@/api/openai'
|
||||||
|
|
||||||
import type { Site } from '@/api/site'
|
import type { Site } from '@/api/site'
|
||||||
import type { CheckedType } from '@/types'
|
import type { CheckedType } from '@/types'
|
||||||
import config from '@/api/config'
|
import config from '@/api/config'
|
||||||
|
@ -11,6 +10,7 @@ import site from '@/api/site'
|
||||||
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
||||||
import { ConfigHistory } from '@/components/ConfigHistory'
|
import { ConfigHistory } from '@/components/ConfigHistory'
|
||||||
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
|
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
|
||||||
|
import { ConfigStatus } from '@/constants'
|
||||||
import NgxConfigEditor from '@/views/site/ngx_conf/NgxConfigEditor.vue'
|
import NgxConfigEditor from '@/views/site/ngx_conf/NgxConfigEditor.vue'
|
||||||
import RightSettings from '@/views/site/site_edit/RightSettings.vue'
|
import RightSettings from '@/views/site/site_edit/RightSettings.vue'
|
||||||
import { HistoryOutlined } from '@ant-design/icons-vue'
|
import { HistoryOutlined } from '@ant-design/icons-vue'
|
||||||
|
@ -30,7 +30,6 @@ const ngx_config: NgxConfig = reactive({
|
||||||
const certInfoMap: Ref<Record<number, CertificateInfo[]>> = ref({})
|
const certInfoMap: Ref<Record<number, CertificateInfo[]>> = ref({})
|
||||||
|
|
||||||
const autoCert = ref(false)
|
const autoCert = ref(false)
|
||||||
const enabled = ref(false)
|
|
||||||
const filepath = ref('')
|
const filepath = ref('')
|
||||||
const configText = ref('')
|
const configText = ref('')
|
||||||
const advanceModeRef = ref(false)
|
const advanceModeRef = ref(false)
|
||||||
|
@ -64,7 +63,6 @@ async function handleResponse(r: Site) {
|
||||||
filename.value = r.name
|
filename.value = r.name
|
||||||
filepath.value = r.filepath
|
filepath.value = r.filepath
|
||||||
configText.value = r.config
|
configText.value = r.config
|
||||||
enabled.value = r.enabled
|
|
||||||
autoCert.value = r.auto_cert
|
autoCert.value = r.auto_cert
|
||||||
historyChatgptRecord.value = r.chatgpt_messages
|
historyChatgptRecord.value = r.chatgpt_messages
|
||||||
data.value = r
|
data.value = r
|
||||||
|
@ -168,7 +166,6 @@ provide('save_config', save)
|
||||||
provide('configText', configText)
|
provide('configText', configText)
|
||||||
provide('ngx_config', ngx_config)
|
provide('ngx_config', ngx_config)
|
||||||
provide('history_chatgpt_record', historyChatgptRecord)
|
provide('history_chatgpt_record', historyChatgptRecord)
|
||||||
provide('enabled', enabled)
|
|
||||||
provide('name', name)
|
provide('name', name)
|
||||||
provide('filepath', filepath)
|
provide('filepath', filepath)
|
||||||
provide('data', data)
|
provide('data', data)
|
||||||
|
@ -187,17 +184,23 @@ provide('data', data)
|
||||||
<template #title>
|
<template #title>
|
||||||
<span style="margin-right: 10px">{{ $gettext('Edit %{n}', { n: name }) }}</span>
|
<span style="margin-right: 10px">{{ $gettext('Edit %{n}', { n: name }) }}</span>
|
||||||
<ATag
|
<ATag
|
||||||
v-if="enabled"
|
v-if="data.status === ConfigStatus.Enabled"
|
||||||
color="blue"
|
color="blue"
|
||||||
>
|
>
|
||||||
{{ $gettext('Enabled') }}
|
{{ $gettext('Enabled') }}
|
||||||
</ATag>
|
</ATag>
|
||||||
<ATag
|
<ATag
|
||||||
v-else
|
v-else-if="data.status === ConfigStatus.Disabled"
|
||||||
color="orange"
|
color="red"
|
||||||
>
|
>
|
||||||
{{ $gettext('Disabled') }}
|
{{ $gettext('Disabled') }}
|
||||||
</ATag>
|
</ATag>
|
||||||
|
<ATag
|
||||||
|
v-else-if="data.status === ConfigStatus.Maintenance"
|
||||||
|
color="orange"
|
||||||
|
>
|
||||||
|
{{ $gettext('Maintenance') }}
|
||||||
|
</ATag>
|
||||||
</template>
|
</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<ASpace>
|
<ASpace>
|
||||||
|
@ -260,7 +263,7 @@ provide('data', data)
|
||||||
<NgxConfigEditor
|
<NgxConfigEditor
|
||||||
v-model:auto-cert="autoCert"
|
v-model:auto-cert="autoCert"
|
||||||
:cert-info="certInfoMap"
|
:cert-info="certInfoMap"
|
||||||
:enabled="enabled"
|
:status="data.status"
|
||||||
@callback="save"
|
@callback="save"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { SiteStatus } from '@/api/site'
|
||||||
import type {
|
import type {
|
||||||
CustomRender,
|
CustomRender,
|
||||||
} from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
|
} from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
|
||||||
|
@ -10,7 +11,7 @@ import {
|
||||||
import { input, select, selector } from '@/components/StdDesign/StdDataEntry'
|
import { input, select, selector } from '@/components/StdDesign/StdDataEntry'
|
||||||
import { ConfigStatus } from '@/constants'
|
import { ConfigStatus } from '@/constants'
|
||||||
import envGroupColumns from '@/views/environments/group/columns'
|
import envGroupColumns from '@/views/environments/group/columns'
|
||||||
import SiteStatusSegmented from '@/views/site/site_edit/components/SiteStatusSegmented.vue'
|
import SiteStatusSegmented from '@/views/site/components/SiteStatusSegmented.vue'
|
||||||
import { Tag } from 'ant-design-vue'
|
import { Tag } from 'ant-design-vue'
|
||||||
|
|
||||||
const columns: Column[] = [{
|
const columns: Column[] = [{
|
||||||
|
@ -98,9 +99,8 @@ const columns: Column[] = [{
|
||||||
// This will be handled by the component internal events
|
// This will be handled by the component internal events
|
||||||
record.status = val
|
record.status = val
|
||||||
},
|
},
|
||||||
'onStatusChanged': ({ status, enabled }: { status: string, enabled: boolean }) => {
|
'onStatusChanged': ({ status }: { status: SiteStatus }) => {
|
||||||
record.status = status
|
record.status = status
|
||||||
record.enabled = enabled
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/tufanbarisyildirim/gonginx/config"
|
"github.com/tufanbarisyildirim/gonginx/config"
|
||||||
"github.com/tufanbarisyildirim/gonginx/dumper"
|
"github.com/tufanbarisyildirim/gonginx/dumper"
|
||||||
"github.com/tufanbarisyildirim/gonginx/parser"
|
"github.com/tufanbarisyildirim/gonginx/parser"
|
||||||
|
"github.com/uozi-tech/cosy/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProxyCacheConfig struct {
|
type ProxyCacheConfig struct {
|
||||||
|
@ -189,7 +190,10 @@ func updateOrRemoveProxyCachePath(block config.IBlock, directives []config.IDire
|
||||||
// First parameter is the path (required)
|
// First parameter is the path (required)
|
||||||
if proxyCache.Path != "" {
|
if proxyCache.Path != "" {
|
||||||
params = append(params, config.Parameter{Value: proxyCache.Path})
|
params = append(params, config.Parameter{Value: proxyCache.Path})
|
||||||
_ = os.MkdirAll(proxyCache.Path, 0755)
|
err := os.MkdirAll(proxyCache.Path, 0755)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to create proxy cache path", err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// No path specified, can't add the directive
|
// No path specified, can't add the directive
|
||||||
return
|
return
|
||||||
|
|
21
internal/site/status.go
Normal file
21
internal/site/status.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package site
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/0xJacky/Nginx-UI/internal/helper"
|
||||||
|
"github.com/0xJacky/Nginx-UI/internal/nginx"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetSiteStatus returns the status of the site
|
||||||
|
func GetSiteStatus(name string) SiteStatus {
|
||||||
|
enabledFilePath := nginx.GetConfPath("sites-enabled", name)
|
||||||
|
if helper.FileExists(enabledFilePath) {
|
||||||
|
return SiteStatusEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
mantainanceFilePath := nginx.GetConfPath("sites-enabled", name+MaintenanceSuffix)
|
||||||
|
if helper.FileExists(mantainanceFilePath) {
|
||||||
|
return SiteStatusMaintenance
|
||||||
|
}
|
||||||
|
|
||||||
|
return SiteStatusDisabled
|
||||||
|
}
|
|
@ -1,18 +1,27 @@
|
||||||
package sites
|
package site
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/0xJacky/Nginx-UI/internal/cert"
|
"github.com/0xJacky/Nginx-UI/internal/cert"
|
||||||
"github.com/0xJacky/Nginx-UI/internal/nginx"
|
"github.com/0xJacky/Nginx-UI/internal/nginx"
|
||||||
"github.com/0xJacky/Nginx-UI/model"
|
"github.com/0xJacky/Nginx-UI/model"
|
||||||
"github.com/sashabaranov/go-openai"
|
"github.com/sashabaranov/go-openai"
|
||||||
"time"
|
)
|
||||||
|
|
||||||
|
type SiteStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
SiteStatusEnabled SiteStatus = "enabled"
|
||||||
|
SiteStatusDisabled SiteStatus = "disabled"
|
||||||
|
SiteStatusMaintenance SiteStatus = "maintenance"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Site struct {
|
type Site struct {
|
||||||
*model.Site
|
*model.Site
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ModifiedAt time.Time `json:"modified_at"`
|
ModifiedAt time.Time `json:"modified_at"`
|
||||||
Enabled bool `json:"enabled"`
|
Status SiteStatus `json:"status"`
|
||||||
Config string `json:"config"`
|
Config string `json:"config"`
|
||||||
AutoCert bool `json:"auto_cert"`
|
AutoCert bool `json:"auto_cert"`
|
||||||
ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"`
|
ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"`
|
Loading…
Add table
Add a link
Reference in a new issue