어나운스 바 설정 정규화 로직 분리
This commit is contained in:
@@ -32,6 +32,7 @@
|
|||||||
| lib/admin-post-settings-section.js | 관리자 설정 POST 설정 필드 목록·기본 스냅샷·정규화·스냅샷 복사·변경 비교 helper |
|
| lib/admin-post-settings-section.js | 관리자 설정 POST 설정 필드 목록·기본 스냅샷·정규화·스냅샷 복사·변경 비교 helper |
|
||||||
| lib/admin-spam-settings-section.js | 관리자 설정 스팸 필터 필드 목록·기본 스냅샷·정규화·textarea 변환·스냅샷 복사·변경 비교 helper |
|
| lib/admin-spam-settings-section.js | 관리자 설정 스팸 필터 필드 목록·기본 스냅샷·정규화·textarea 변환·스냅샷 복사·변경 비교 helper |
|
||||||
| lib/admin-brand-settings-section.js | 관리자 설정 브랜드 설정 필드 목록·기본 스냅샷·정규화·스냅샷 복사·변경 비교 helper |
|
| lib/admin-brand-settings-section.js | 관리자 설정 브랜드 설정 필드 목록·기본 스냅샷·정규화·스냅샷 복사·변경 비교 helper |
|
||||||
|
| lib/admin-announcement-settings-section.js | 관리자 설정 어나운스 바 설정 필드 목록·기본 스냅샷·정규화·스냅샷 복사·변경 비교 helper |
|
||||||
| lib/post-card-thumbnail-url.js | 게시물 카드 썸네일 `thumbs/*-card.webp`, Pages 커버 썸네일 `thumbs/*-page-cover.webp`, 본문 표시용 `body-1600`/`body-720`·라이트박스용 `body-2560` 파생 이미지 URL 판별과 레거시 `body`/`lightbox` 판별, 자동 생성 이미지 캐시 버전 URL 생성(대표 이미지·본문 이미지·갤러리·Pages 커버 선택 및 서버 검증 공용) |
|
| lib/post-card-thumbnail-url.js | 게시물 카드 썸네일 `thumbs/*-card.webp`, Pages 커버 썸네일 `thumbs/*-page-cover.webp`, 본문 표시용 `body-1600`/`body-720`·라이트박스용 `body-2560` 파생 이미지 URL 판별과 레거시 `body`/`lightbox` 판별, 자동 생성 이미지 캐시 버전 URL 생성(대표 이미지·본문 이미지·갤러리·Pages 커버 선택 및 서버 검증 공용) |
|
||||||
| lib/external-favicon-url.js | 외부 URL origin 기준 Google `gstatic.com/faviconV2` 파비콘 URL 생성(내부 경로는 빈 문자열) |
|
| lib/external-favicon-url.js | 외부 URL origin 기준 Google `gstatic.com/faviconV2` 파비콘 URL 생성(내부 경로는 빈 문자열) |
|
||||||
| lib/navigation-url.js | 네비게이션 URL 접두사 분리·합성·정규화(`https://` 자동 보정, `/` 내부 경로) |
|
| lib/navigation-url.js | 네비게이션 URL 접두사 분리·합성·정규화(`https://` 자동 보정, `/` 내부 경로) |
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
- 거대 컴포넌트 책임 분리 진행.
|
- 거대 컴포넌트 책임 분리 진행.
|
||||||
- `components/admin/AdminMarkdownEditor.vue`: 미디어 모달, 슬래시 명령, 히스토리·선택 복원, 라이브/소스 전환 로직을 단계적으로 composable 또는 하위 컴포넌트로 분리.
|
- `components/admin/AdminMarkdownEditor.vue`: 미디어 모달, 슬래시 명령, 히스토리·선택 복원, 라이브/소스 전환 로직을 단계적으로 composable 또는 하위 컴포넌트로 분리.
|
||||||
- `pages/admin/settings/index.vue`: 정규화가 필요한 설정 섹션(어나운스 바)의 편집 상태·스냅샷·저장 요청 로직을 composable 단위로 추가 분리.
|
|
||||||
- `components/content/ContentMarkdownRenderer.vue`: 파싱·블록 렌더링·라이브 편집 중개·라이트박스·광고 삽입 책임을 분리.
|
- `components/content/ContentMarkdownRenderer.vue`: 파싱·블록 렌더링·라이브 편집 중개·라이트박스·광고 삽입 책임을 분리.
|
||||||
- `components/admin/AdminPostForm.vue`: 태그 입력, 대표 이미지 선택, 발행/초안 저장 상태, 우측 설정 패널 책임을 분리.
|
- `components/admin/AdminPostForm.vue`: 태그 입력, 대표 이미지 선택, 발행/초안 저장 상태, 우측 설정 패널 책임을 분리.
|
||||||
- `pages/admin/media/index.vue`: 미디어 목록, 폴더 트리, 상세 모달, 재생성 액션을 작은 단위로 분리.
|
- `pages/admin/media/index.vue`: 미디어 목록, 폴더 트리, 상세 모달, 재생성 액션을 작은 단위로 분리.
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# 업데이트 이력
|
# 업데이트 이력
|
||||||
|
|
||||||
|
## v1.11.39
|
||||||
|
|
||||||
|
- 어나운스 바 설정 정규화·스냅샷 복사·변경 비교 로직을 `lib/admin-announcement-settings-section.js`로 분리.
|
||||||
|
- 설정 화면의 어나운스 바 편집 시작·취소·저장 로직을 공통 helper 기반으로 정리.
|
||||||
|
- 설정 저장 payload의 어나운스 바 설정 필드 정규화를 한 경로로 통합.
|
||||||
|
|
||||||
## v1.11.38
|
## v1.11.38
|
||||||
|
|
||||||
- 브랜드 설정 정규화·스냅샷 복사·변경 비교 로직을 `lib/admin-brand-settings-section.js`로 분리.
|
- 브랜드 설정 정규화·스냅샷 복사·변경 비교 로직을 `lib/admin-brand-settings-section.js`로 분리.
|
||||||
|
|||||||
64
lib/admin-announcement-settings-section.js
Normal file
64
lib/admin-announcement-settings-section.js
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import {
|
||||||
|
DEFAULT_ANNOUNCEMENT_ALIGNMENT,
|
||||||
|
DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR,
|
||||||
|
normalizeAnnouncementAlignment,
|
||||||
|
normalizeAnnouncementBackgroundColor
|
||||||
|
} from './announcement-bar.js'
|
||||||
|
|
||||||
|
export const ANNOUNCEMENT_SETTINGS_FIELDS = [
|
||||||
|
'announcementEnabled',
|
||||||
|
'announcementText',
|
||||||
|
'announcementUrl',
|
||||||
|
'announcementBackgroundColor',
|
||||||
|
'announcementAlignment'
|
||||||
|
]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 어나운스 바 설정 기본 스냅샷을 만든다.
|
||||||
|
* @returns {Object} 기본 어나운스 바 설정 값
|
||||||
|
*/
|
||||||
|
export const createDefaultAnnouncementSettingsSnapshot = () => ({
|
||||||
|
announcementEnabled: false,
|
||||||
|
announcementText: '',
|
||||||
|
announcementUrl: '',
|
||||||
|
announcementBackgroundColor: DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR,
|
||||||
|
announcementAlignment: DEFAULT_ANNOUNCEMENT_ALIGNMENT
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 어나운스 바 설정 값을 저장·비교 가능한 형태로 정규화한다.
|
||||||
|
* @param {Object} source - 원본 설정 값
|
||||||
|
* @returns {Object} 정규화된 어나운스 바 설정 값
|
||||||
|
*/
|
||||||
|
export const normalizeAnnouncementSettingsSection = (source = {}) => ({
|
||||||
|
announcementEnabled: Boolean(source.announcementEnabled),
|
||||||
|
announcementText: source.announcementText || '',
|
||||||
|
announcementUrl: source.announcementUrl || '',
|
||||||
|
announcementBackgroundColor: normalizeAnnouncementBackgroundColor(source.announcementBackgroundColor || DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR),
|
||||||
|
announcementAlignment: normalizeAnnouncementAlignment(source.announcementAlignment || DEFAULT_ANNOUNCEMENT_ALIGNMENT)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 어나운스 바 설정 필드만 대상 객체에 복사한다.
|
||||||
|
* @param {Object} target - 값을 받을 객체
|
||||||
|
* @param {Object} source - 값을 제공할 객체
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
export const assignAnnouncementSettingsSection = (target, source = {}) => {
|
||||||
|
const normalized = normalizeAnnouncementSettingsSection(source)
|
||||||
|
ANNOUNCEMENT_SETTINGS_FIELDS.forEach((field) => {
|
||||||
|
target[field] = normalized[field]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 두 어나운스 바 설정 값이 다른지 확인한다.
|
||||||
|
* @param {Object} current - 현재 설정 값
|
||||||
|
* @param {Object} snapshot - 비교할 스냅샷
|
||||||
|
* @returns {boolean} 변경 여부
|
||||||
|
*/
|
||||||
|
export const hasAnnouncementSettingsSectionChanges = (current, snapshot) => {
|
||||||
|
const normalizedCurrent = normalizeAnnouncementSettingsSection(current)
|
||||||
|
const normalizedSnapshot = normalizeAnnouncementSettingsSection(snapshot)
|
||||||
|
return ANNOUNCEMENT_SETTINGS_FIELDS.some((field) => normalizedCurrent[field] !== normalizedSnapshot[field])
|
||||||
|
}
|
||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "sori.studio",
|
"name": "sori.studio",
|
||||||
"version": "1.11.38",
|
"version": "1.11.39",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sori.studio",
|
"name": "sori.studio",
|
||||||
"version": "1.11.38",
|
"version": "1.11.39",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sori.studio",
|
"name": "sori.studio",
|
||||||
"version": "1.11.38",
|
"version": "1.11.39",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"imports": {
|
"imports": {
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {
|
|
||||||
DEFAULT_ANNOUNCEMENT_ALIGNMENT,
|
|
||||||
DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR,
|
|
||||||
normalizeAnnouncementAlignment,
|
|
||||||
normalizeAnnouncementBackgroundColor
|
|
||||||
} from '~/lib/announcement-bar.js'
|
|
||||||
import {
|
import {
|
||||||
DISPLAY_COUNT_OPTIONS,
|
DISPLAY_COUNT_OPTIONS,
|
||||||
POST_LIST_COUNT_OPTIONS
|
POST_LIST_COUNT_OPTIONS
|
||||||
@@ -44,6 +38,13 @@ import {
|
|||||||
hasBrandSettingsSectionChanges,
|
hasBrandSettingsSectionChanges,
|
||||||
normalizeBrandSettingsSection
|
normalizeBrandSettingsSection
|
||||||
} from '~/lib/admin-brand-settings-section.js'
|
} from '~/lib/admin-brand-settings-section.js'
|
||||||
|
import {
|
||||||
|
ANNOUNCEMENT_SETTINGS_FIELDS,
|
||||||
|
assignAnnouncementSettingsSection,
|
||||||
|
createDefaultAnnouncementSettingsSnapshot,
|
||||||
|
hasAnnouncementSettingsSectionChanges,
|
||||||
|
normalizeAnnouncementSettingsSection
|
||||||
|
} from '~/lib/admin-announcement-settings-section.js'
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: 'admin'
|
layout: 'admin'
|
||||||
@@ -182,13 +183,7 @@ const homeCoverSnapshot = reactive({
|
|||||||
/** 편집 시작 시점의 브랜드 설정(취소 시 복원용) */
|
/** 편집 시작 시점의 브랜드 설정(취소 시 복원용) */
|
||||||
const brandSnapshot = reactive(createDefaultBrandSettingsSnapshot())
|
const brandSnapshot = reactive(createDefaultBrandSettingsSnapshot())
|
||||||
/** 맞춤 설정 시작 시점의 어나운스 바(취소 시 복원용) */
|
/** 맞춤 설정 시작 시점의 어나운스 바(취소 시 복원용) */
|
||||||
const announcementSnapshot = reactive({
|
const announcementSnapshot = reactive(createDefaultAnnouncementSettingsSnapshot())
|
||||||
announcementEnabled: false,
|
|
||||||
announcementText: '',
|
|
||||||
announcementUrl: '',
|
|
||||||
announcementBackgroundColor: DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR,
|
|
||||||
announcementAlignment: DEFAULT_ANNOUNCEMENT_ALIGNMENT
|
|
||||||
})
|
|
||||||
/** 편집 시작 시점의 스팸 필터(취소 시 복원용) */
|
/** 편집 시작 시점의 스팸 필터(취소 시 복원용) */
|
||||||
const spamSnapshot = reactive(createDefaultSpamSettingsSnapshot())
|
const spamSnapshot = reactive(createDefaultSpamSettingsSnapshot())
|
||||||
/** 편집 시작 시점의 사이트 코드(취소 시 복원용) */
|
/** 편집 시작 시점의 사이트 코드(취소 시 복원용) */
|
||||||
@@ -234,6 +229,7 @@ const initialPostSettings = normalizePostSettingsSection(settings.value)
|
|||||||
const initialSocialSettings = normalizeSocialSettingsSection(settings.value)
|
const initialSocialSettings = normalizeSocialSettingsSection(settings.value)
|
||||||
const initialSpamSettings = normalizeSpamSettingsSection(settings.value)
|
const initialSpamSettings = normalizeSpamSettingsSection(settings.value)
|
||||||
const initialBrandSettings = normalizeBrandSettingsSection(settings.value)
|
const initialBrandSettings = normalizeBrandSettingsSection(settings.value)
|
||||||
|
const initialAnnouncementSettings = normalizeAnnouncementSettingsSection(settings.value)
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
title: settings.value?.title || 'sori.studio',
|
title: settings.value?.title || 'sori.studio',
|
||||||
@@ -250,11 +246,7 @@ const form = reactive({
|
|||||||
homeCoverTitle: settings.value?.homeCoverTitle || '',
|
homeCoverTitle: settings.value?.homeCoverTitle || '',
|
||||||
homeCoverText: settings.value?.homeCoverText || '',
|
homeCoverText: settings.value?.homeCoverText || '',
|
||||||
...initialBrandSettings,
|
...initialBrandSettings,
|
||||||
announcementEnabled: Boolean(settings.value?.announcementEnabled),
|
...initialAnnouncementSettings,
|
||||||
announcementText: settings.value?.announcementText || '',
|
|
||||||
announcementUrl: settings.value?.announcementUrl || '',
|
|
||||||
announcementBackgroundColor: normalizeAnnouncementBackgroundColor(settings.value?.announcementBackgroundColor || DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR),
|
|
||||||
announcementAlignment: normalizeAnnouncementAlignment(settings.value?.announcementAlignment || DEFAULT_ANNOUNCEMENT_ALIGNMENT),
|
|
||||||
...initialSpamSettings,
|
...initialSpamSettings,
|
||||||
adsTxt: settings.value?.adsTxt || '',
|
adsTxt: settings.value?.adsTxt || '',
|
||||||
customHeadCode: settings.value?.customHeadCode || '',
|
customHeadCode: settings.value?.customHeadCode || '',
|
||||||
@@ -326,11 +318,7 @@ const hasBrandChanges = computed(() => editBrand.value
|
|||||||
* @returns {boolean} 변경 여부
|
* @returns {boolean} 변경 여부
|
||||||
*/
|
*/
|
||||||
const hasAnnouncementChanges = computed(() => customizeAnnouncement.value && (
|
const hasAnnouncementChanges = computed(() => customizeAnnouncement.value && (
|
||||||
form.announcementEnabled !== announcementSnapshot.announcementEnabled
|
hasAnnouncementSettingsSectionChanges(form, announcementSnapshot)
|
||||||
|| form.announcementText !== announcementSnapshot.announcementText
|
|
||||||
|| form.announcementUrl !== announcementSnapshot.announcementUrl
|
|
||||||
|| normalizeAnnouncementBackgroundColor(form.announcementBackgroundColor) !== normalizeAnnouncementBackgroundColor(announcementSnapshot.announcementBackgroundColor)
|
|
||||||
|| normalizeAnnouncementAlignment(form.announcementAlignment) !== normalizeAnnouncementAlignment(announcementSnapshot.announcementAlignment)
|
|
||||||
))
|
))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1084,11 +1072,7 @@ const buildSiteSettingsPayload = (fields = null) => {
|
|||||||
homeCoverTitle: form.homeCoverTitle || '',
|
homeCoverTitle: form.homeCoverTitle || '',
|
||||||
homeCoverText: form.homeCoverText || '',
|
homeCoverText: form.homeCoverText || '',
|
||||||
...normalizeBrandSettingsSection(form),
|
...normalizeBrandSettingsSection(form),
|
||||||
announcementEnabled: Boolean(form.announcementEnabled),
|
...normalizeAnnouncementSettingsSection(form),
|
||||||
announcementText: form.announcementText || '',
|
|
||||||
announcementUrl: form.announcementUrl || '',
|
|
||||||
announcementBackgroundColor: normalizeAnnouncementBackgroundColor(form.announcementBackgroundColor || DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR),
|
|
||||||
announcementAlignment: normalizeAnnouncementAlignment(form.announcementAlignment || DEFAULT_ANNOUNCEMENT_ALIGNMENT),
|
|
||||||
...normalizeSpamSettingsSection(form),
|
...normalizeSpamSettingsSection(form),
|
||||||
adsTxt: form.adsTxt || '',
|
adsTxt: form.adsTxt || '',
|
||||||
customHeadCode: form.customHeadCode || '',
|
customHeadCode: form.customHeadCode || '',
|
||||||
@@ -1514,11 +1498,8 @@ const saveBrandSection = async () => {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
const beginCustomizeAnnouncement = () => {
|
const beginCustomizeAnnouncement = () => {
|
||||||
announcementSnapshot.announcementEnabled = form.announcementEnabled
|
assignAnnouncementSettingsSection(announcementSnapshot, form)
|
||||||
announcementSnapshot.announcementText = form.announcementText
|
assignAnnouncementSettingsSection(form, announcementSnapshot)
|
||||||
announcementSnapshot.announcementUrl = form.announcementUrl
|
|
||||||
announcementSnapshot.announcementBackgroundColor = normalizeAnnouncementBackgroundColor(form.announcementBackgroundColor || DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR)
|
|
||||||
announcementSnapshot.announcementAlignment = normalizeAnnouncementAlignment(form.announcementAlignment || DEFAULT_ANNOUNCEMENT_ALIGNMENT)
|
|
||||||
customizeAnnouncement.value = true
|
customizeAnnouncement.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1527,11 +1508,7 @@ const beginCustomizeAnnouncement = () => {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
const cancelCustomizeAnnouncement = () => {
|
const cancelCustomizeAnnouncement = () => {
|
||||||
form.announcementEnabled = announcementSnapshot.announcementEnabled
|
assignAnnouncementSettingsSection(form, announcementSnapshot)
|
||||||
form.announcementText = announcementSnapshot.announcementText
|
|
||||||
form.announcementUrl = announcementSnapshot.announcementUrl
|
|
||||||
form.announcementBackgroundColor = announcementSnapshot.announcementBackgroundColor
|
|
||||||
form.announcementAlignment = announcementSnapshot.announcementAlignment
|
|
||||||
customizeAnnouncement.value = false
|
customizeAnnouncement.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1547,21 +1524,12 @@ const saveAnnouncementSection = async () => {
|
|||||||
const ok = await persistSiteSettings({
|
const ok = await persistSiteSettings({
|
||||||
successToast: '어나운스 바 설정이 저장되었습니다.',
|
successToast: '어나운스 바 설정이 저장되었습니다.',
|
||||||
savingFlag: savingAnnouncement,
|
savingFlag: savingAnnouncement,
|
||||||
fields: [
|
fields: ANNOUNCEMENT_SETTINGS_FIELDS
|
||||||
'announcementEnabled',
|
|
||||||
'announcementText',
|
|
||||||
'announcementUrl',
|
|
||||||
'announcementBackgroundColor',
|
|
||||||
'announcementAlignment'
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
announcementSnapshot.announcementEnabled = form.announcementEnabled
|
assignAnnouncementSettingsSection(announcementSnapshot, form)
|
||||||
announcementSnapshot.announcementText = form.announcementText
|
assignAnnouncementSettingsSection(form, announcementSnapshot)
|
||||||
announcementSnapshot.announcementUrl = form.announcementUrl
|
|
||||||
announcementSnapshot.announcementBackgroundColor = normalizeAnnouncementBackgroundColor(form.announcementBackgroundColor || DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR)
|
|
||||||
announcementSnapshot.announcementAlignment = normalizeAnnouncementAlignment(form.announcementAlignment || DEFAULT_ANNOUNCEMENT_ALIGNMENT)
|
|
||||||
customizeAnnouncement.value = false
|
customizeAnnouncement.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user