Repository: go-gitea/gitea
File: web_src/js/components/RepoActionView.vue (Vue)

Code before:
      default: '',
    },
    actionsURL: {
      type: String,
      default: '',
    },
    locale: {
      type: Object as PropType<Record<string, any>>,
      default: null,
    },
  },

  data() {
    const defaultViewOptions: LocaleStorageOptions = {autoScroll: true, expandRunning: false, actionsLogShowSeconds: false, actionsLogShowTimestamps: false};
    const {autoScroll, expandRunning, actionsLogShowSeconds, actionsLogShowTimestamps} = localUserSettings.getJsonObject('actions-view-options', defaultViewOptions);
    return {
      // internal state
      loadingAbortController: null as AbortController | null,
      intervalID: null as IntervalId | null,
      currentJobStepsStates: [] as Array<JobStepState>,
      artifacts: [] as Array<Record<string, any>>,
      menuVisible: false,
      isFullScreen: false,
      timeVisible: {
        'log-time-stamp': actionsLogShowTimestamps ?? false,
        'log-time-seconds': actionsLogShowSeconds ?? false,
      },
      optionAlwaysAutoScroll: autoScroll ?? false,
      optionAlwaysExpandRunning: expandRunning ?? false,

      // provided by backend
      run: {
        link: '',
        title: '',
        titleHTML: '',
        status: '' as RunStatus, // do not show the status before initialized, otherwise it would show an incorrect "error" icon
        canCancel: false,
        canApprove: false,
        canRerun: false,
        canDeleteArtifact: false,
        done: false,
        workflowID: '',
        workflowLink: '',
        isSchedule: false,
        jobs: [
          // {
          //   id: 0,
          //   name: '',
          //   status: '',
          //   canRerun: false,
          //   duration: '',

Review comment (suggestion):
It needs to make `getJsonObject` merge the default options and get rid of such `??`.

For newly added options, as long as they are in `defaultViewOptions`, then they should have default values even if they don't exist in the saved local storage item.

Code after:
      default: '',
    },
    actionsURL: {
      type: String,
      default: '',
    },
    locale: {
      type: Object as PropType<Record<string, any>>,
      default: null,
    },
  },

  data() {
    const defaultViewOptions: LocaleStorageOptions = {autoScroll: true, expandRunning: false, actionsLogShowSeconds: false, actionsLogShowTimestamps: false};
    const {autoScroll, expandRunning, actionsLogShowSeconds, actionsLogShowTimestamps} = localUserSettings.getJsonObject('actions-view-options', defaultViewOptions);
    return {
      // internal state
      loadingAbortController: null as AbortController | null,
      intervalID: null as IntervalId | null,
      currentJobStepsStates: [] as Array<JobStepState>,
      artifacts: [] as Array<Record<string, any>>,
      menuVisible: false,
      isFullScreen: false,
      timeVisible: {
        'log-time-stamp': actionsLogShowTimestamps,
        'log-time-seconds': actionsLogShowSeconds,
      },
      optionAlwaysAutoScroll: autoScroll,
      optionAlwaysExpandRunning: expandRunning,

      // provided by backend
      run: {
        link: '',
        title: '',
        titleHTML: '',
        status: '' as RunStatus, // do not show the status before initialized, otherwise it would show an incorrect "error" icon
        canCancel: false,
        canApprove: false,
        canRerun: false,
        canDeleteArtifact: false,
        done: false,
        workflowID: '',
        workflowLink: '',
        isSchedule: false,
        jobs: [
          // {
          //   id: 0,
          //   name: '',
          //   status: '',
          //   canRerun: false,
          //   duration: '',