diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index 6e23be86f..529cf149a 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -10,6 +10,7 @@ import { DealAdminRoutingModule } from '../features/deal/admin/deal-admin-routin import { EventAdminRoutingModule } from '../features/event/admin/event-admin-routing.module'; import { GuestArticleAdminRoutingModule } from '../features/guest-article/admin/guest-article-admin-routing.module'; import { MediaAdminRoutingModule } from '../features/media/admin/media-admin-routing.module'; +import { NavigatorAdminRoutingModule } from '../features/navigator/admin/navigator-admin-routing.module'; import { OrganisationAdminRoutingModule } from '../features/organisation/admin/organisation-admin-routing.module'; import { ReportAdminRoutingModule } from '../features/report/admin/report-admin-routing.module'; import { SurveyAdminRoutingModule } from '../features/survey/admin/survey-admin-routing.module'; @@ -35,6 +36,7 @@ const routes = [ ReportAdminRoutingModule, GuestArticleAdminRoutingModule, AuthorAdminRoutingModule, + NavigatorAdminRoutingModule, AdminRoutingModule, //TODO: always last entry duet to order and redirect to 404, Remove 404 and put in AppRouter ]; diff --git a/src/app/core/api/generated/schema.ts b/src/app/core/api/generated/schema.ts index 3e063b3de..f86385a8f 100644 --- a/src/app/core/api/generated/schema.ts +++ b/src/app/core/api/generated/schema.ts @@ -1820,6 +1820,12 @@ export type Mutation = { deleteMilestoneMedia?: Maybe; deleteMilestoneMedium?: Maybe; deleteMilestones?: Maybe; + deleteNavigatorChoice?: Maybe; + deleteNavigatorChoices?: Maybe; + deleteNavigatorPage?: Maybe; + deleteNavigatorPages?: Maybe; + deleteNavigatorResultPage?: Maybe; + deleteNavigatorResultPages?: Maybe; deleteNotification?: Maybe; deleteNotifications?: Maybe; deleteOrganisation?: Maybe; @@ -1971,6 +1977,12 @@ export type Mutation = { saveMilestoneMedia?: Maybe>>; saveMilestoneMedium?: Maybe; saveMilestones?: Maybe>>; + saveNavigatorChoice?: Maybe; + saveNavigatorChoices?: Maybe>>; + saveNavigatorPage?: Maybe; + saveNavigatorPages?: Maybe>>; + saveNavigatorResultPage?: Maybe; + saveNavigatorResultPages?: Maybe>>; saveNotification?: Maybe; saveNotifications?: Maybe>>; saveOrganisation?: Maybe; @@ -2617,6 +2629,42 @@ export type MutationDeleteMilestonesArgs = { }; +/** Mutation root */ +export type MutationDeleteNavigatorChoiceArgs = { + id?: InputMaybe; +}; + + +/** Mutation root */ +export type MutationDeleteNavigatorChoicesArgs = { + ids?: InputMaybe>>; +}; + + +/** Mutation root */ +export type MutationDeleteNavigatorPageArgs = { + id?: InputMaybe; +}; + + +/** Mutation root */ +export type MutationDeleteNavigatorPagesArgs = { + ids?: InputMaybe>>; +}; + + +/** Mutation root */ +export type MutationDeleteNavigatorResultPageArgs = { + id?: InputMaybe; +}; + + +/** Mutation root */ +export type MutationDeleteNavigatorResultPagesArgs = { + ids?: InputMaybe>>; +}; + + /** Mutation root */ export type MutationDeleteNotificationArgs = { id?: InputMaybe; @@ -3524,6 +3572,42 @@ export type MutationSaveMilestonesArgs = { }; +/** Mutation root */ +export type MutationSaveNavigatorChoiceArgs = { + entity?: InputMaybe; +}; + + +/** Mutation root */ +export type MutationSaveNavigatorChoicesArgs = { + entities?: InputMaybe>>; +}; + + +/** Mutation root */ +export type MutationSaveNavigatorPageArgs = { + entity?: InputMaybe; +}; + + +/** Mutation root */ +export type MutationSaveNavigatorPagesArgs = { + entities?: InputMaybe>>; +}; + + +/** Mutation root */ +export type MutationSaveNavigatorResultPageArgs = { + entity?: InputMaybe; +}; + + +/** Mutation root */ +export type MutationSaveNavigatorResultPagesArgs = { + entities?: InputMaybe>>; +}; + + /** Mutation root */ export type MutationSaveNotificationArgs = { entity?: InputMaybe; @@ -3973,6 +4057,135 @@ export type MutationVerifyAddressArgs = { entity?: InputMaybe; }; +export type NavigatorChoiceEntity = { + __typename?: 'NavigatorChoiceEntity'; + created?: Maybe; + description?: Maybe; + id?: Maybe; + modified?: Maybe; + name?: Maybe; + nextPage?: Maybe; + parent?: Maybe; + resultPage?: Maybe; + slug?: Maybe; + translatables?: Maybe>>; +}; + +export type NavigatorChoiceEntityInput = { + created?: InputMaybe; + description?: InputMaybe; + id?: InputMaybe; + modified?: InputMaybe; + name?: InputMaybe; + nextPage?: InputMaybe; + parent?: InputMaybe; + resultPage?: InputMaybe; + slug?: InputMaybe; + translatables?: InputMaybe>>; +}; + +export type NavigatorChoiceTranslatableEntity = { + __typename?: 'NavigatorChoiceTranslatableEntity'; + created?: Maybe; + description?: Maybe; + id?: Maybe; + language?: Maybe; + modified?: Maybe; + name?: Maybe; +}; + +export type NavigatorChoiceTranslatableEntityInput = { + created?: InputMaybe; + description?: InputMaybe; + id?: InputMaybe; + modified?: InputMaybe; + name?: InputMaybe; +}; + +export type NavigatorPageEntity = { + __typename?: 'NavigatorPageEntity'; + additionalInformation?: Maybe; + choices?: Maybe>>; + created?: Maybe; + id?: Maybe; + isResultPage?: Maybe; + links?: Maybe>>; + modified?: Maybe; + parentChoices?: Maybe>>; + slug?: Maybe; + title?: Maybe; + translatables?: Maybe>>; +}; + +export type NavigatorPageEntityInput = { + additionalInformation?: InputMaybe; + choices?: InputMaybe>>; + created?: InputMaybe; + id?: InputMaybe; + isResultPage?: InputMaybe; + links?: InputMaybe>>; + modified?: InputMaybe; + parentChoices?: InputMaybe>>; + slug?: InputMaybe; + title?: InputMaybe; + translatables?: InputMaybe>>; +}; + +export type NavigatorPageTranslatableEntity = { + __typename?: 'NavigatorPageTranslatableEntity'; + additionalInformation?: Maybe; + created?: Maybe; + id?: Maybe; + language?: Maybe; + modified?: Maybe; + title?: Maybe; +}; + +export type NavigatorPageTranslatableEntityInput = { + additionalInformation?: InputMaybe; + created?: InputMaybe; + id?: InputMaybe; + modified?: InputMaybe; + title?: InputMaybe; +}; + +export type NavigatorResultLinkEntity = { + __typename?: 'NavigatorResultLinkEntity'; + created?: Maybe; + id?: Maybe; + modified?: Maybe; + name?: Maybe; + parent?: Maybe; + translatables?: Maybe>>; + url?: Maybe; +}; + +export type NavigatorResultLinkEntityInput = { + created?: InputMaybe; + id?: InputMaybe; + modified?: InputMaybe; + name?: InputMaybe; + parent?: InputMaybe; + translatables?: InputMaybe>>; + url?: InputMaybe; +}; + +export type NavigatorResultLinkTranslatableEntity = { + __typename?: 'NavigatorResultLinkTranslatableEntity'; + created?: Maybe; + id?: Maybe; + language?: Maybe; + modified?: Maybe; + name?: Maybe; +}; + +export type NavigatorResultLinkTranslatableEntityInput = { + created?: InputMaybe; + id?: InputMaybe; + modified?: InputMaybe; + name?: InputMaybe; +}; + export type NotificationEntity = { __typename?: 'NotificationEntity'; created?: Maybe; @@ -4687,6 +4900,24 @@ export type PageableList_MilestoneMediaEntity = { total: Scalars['Long']['output']; }; +export type PageableList_NavigatorChoiceEntity = { + __typename?: 'PageableList_NavigatorChoiceEntity'; + result?: Maybe>>; + total: Scalars['Long']['output']; +}; + +export type PageableList_NavigatorPageEntity = { + __typename?: 'PageableList_NavigatorPageEntity'; + result?: Maybe>>; + total: Scalars['Long']['output']; +}; + +export type PageableList_NavigatorResultLinkEntity = { + __typename?: 'PageableList_NavigatorResultLinkEntity'; + result?: Maybe>>; + total: Scalars['Long']['output']; +}; + export type PageableList_NotificationEntity = { __typename?: 'PageableList_NotificationEntity'; result?: Maybe>>; @@ -5065,6 +5296,13 @@ export type Query = { getMilestoneMedia?: Maybe; getMilestoneMedium?: Maybe; getMilestones?: Maybe; + getNavigatorChoice?: Maybe; + getNavigatorChoices?: Maybe; + getNavigatorPage?: Maybe; + getNavigatorPages?: Maybe; + getNavigatorResultPage?: Maybe; + getNavigatorResultPages?: Maybe; + getNavigatorStartPage?: Maybe; getNotification?: Maybe; getNotifications?: Maybe; getOrganisation?: Maybe; @@ -5615,6 +5853,42 @@ export type QueryGetMilestonesArgs = { }; +/** Query root */ +export type QueryGetNavigatorChoiceArgs = { + entity?: InputMaybe; +}; + + +/** Query root */ +export type QueryGetNavigatorChoicesArgs = { + params?: InputMaybe; +}; + + +/** Query root */ +export type QueryGetNavigatorPageArgs = { + entity?: InputMaybe; +}; + + +/** Query root */ +export type QueryGetNavigatorPagesArgs = { + params?: InputMaybe; +}; + + +/** Query root */ +export type QueryGetNavigatorResultPageArgs = { + entity?: InputMaybe; +}; + + +/** Query root */ +export type QueryGetNavigatorResultPagesArgs = { + params?: InputMaybe; +}; + + /** Query root */ export type QueryGetNotificationArgs = { entity?: InputMaybe; diff --git a/src/app/core/constants/feature.constants.ts b/src/app/core/constants/feature.constants.ts index 86c3261c1..2b1269372 100644 --- a/src/app/core/constants/feature.constants.ts +++ b/src/app/core/constants/feature.constants.ts @@ -11,6 +11,7 @@ export const formsFeatureKey = 'forms'; export const guestArticlesFeatureKey = 'guestarticle'; export const mapFeatureKey = 'map'; export const mediaFeatureKey = 'media'; +export const navigatorFeatureKey = 'navigator'; export const organisationsFeatureKey = 'organisations'; export const reportsFeatureKey = 'reports'; export const surveysFeatureKey = 'surveys'; diff --git a/src/app/core/typings/privilege.ts b/src/app/core/typings/privilege.ts index 894d4a43d..22e34a0f1 100644 --- a/src/app/core/typings/privilege.ts +++ b/src/app/core/typings/privilege.ts @@ -20,4 +20,5 @@ export type Privilege = 'addresses_admin' | 'surveys_admin' | 'surveys_manage' | 'translator_admin' - | 'user_admin'; \ No newline at end of file + | 'user_admin' + | 'navigator_admin'; \ No newline at end of file diff --git a/src/app/features/article/admin/details/article-admin-details-routing.module.ts b/src/app/features/article/admin/details/article-admin-details-routing.module.ts index 7ce2bc380..02c1fea16 100644 --- a/src/app/features/article/admin/details/article-admin-details-routing.module.ts +++ b/src/app/features/article/admin/details/article-admin-details-routing.module.ts @@ -15,7 +15,7 @@ const routes: Routes = [ .then((imported) => imported.ArticleAdminDetailsLandingModule), component: ArticleAdminDetailsLandingComponent }, - { + { path: searchRoute, loadChildren: () => import('./modules/search/article-admin-details-search.module') .then((imported) => imported.ArticleAdminDetailsSearchModule), diff --git a/src/app/features/contest/portal/details/modules/landing/contest-portal-details-landing.module.ts b/src/app/features/contest/portal/details/modules/landing/contest-portal-details-landing.module.ts index f2ef91578..26592bed1 100644 --- a/src/app/features/contest/portal/details/modules/landing/contest-portal-details-landing.module.ts +++ b/src/app/features/contest/portal/details/modules/landing/contest-portal-details-landing.module.ts @@ -39,7 +39,6 @@ const components = [ ContestPortalDetailsCommentComponent, ContestPortalDetailsSummaryComponent, PortalContestDetailsMediaComponent - ]; const framework = [ diff --git a/src/app/features/navigator/admin/form/constants/event-admin-details.constants.ts b/src/app/features/navigator/admin/form/constants/event-admin-details.constants.ts new file mode 100644 index 000000000..4a8b2d55f --- /dev/null +++ b/src/app/features/navigator/admin/form/constants/event-admin-details.constants.ts @@ -0,0 +1,3 @@ +export const pageRoute = 'page'; +export const choiceRoute = 'choice'; +export const overviewRoute = 'overview'; \ No newline at end of file diff --git a/src/app/features/navigator/admin/form/modules/choice/components/navigator-admin-form-choice.component.html b/src/app/features/navigator/admin/form/modules/choice/components/navigator-admin-form-choice.component.html new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/features/navigator/admin/form/modules/choice/components/navigator-admin-form-choice.component.scss b/src/app/features/navigator/admin/form/modules/choice/components/navigator-admin-form-choice.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/features/navigator/admin/form/modules/choice/components/navigator-admin-form-choice.component.ts b/src/app/features/navigator/admin/form/modules/choice/components/navigator-admin-form-choice.component.ts new file mode 100644 index 000000000..f7f2164eb --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/choice/components/navigator-admin-form-choice.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-navigator-admin-form-choice', + templateUrl: './navigator-admin-form-choice.component.html', + styleUrls: ['./navigator-admin-form-choice.component.scss'] +}) +export class NavigatorAdminFormChoiceComponent { +} \ No newline at end of file diff --git a/src/app/features/navigator/admin/form/modules/choice/constants/navigator-admin-form-choice.constants.ts b/src/app/features/navigator/admin/form/modules/choice/constants/navigator-admin-form-choice.constants.ts new file mode 100644 index 000000000..5a52f9114 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/choice/constants/navigator-admin-form-choice.constants.ts @@ -0,0 +1 @@ +export const navigatorAdminFormChoiceStateKey = 'navigatorAdminFormChoiceState'; \ No newline at end of file diff --git a/src/app/features/navigator/admin/form/modules/choice/navigator-admin-form-choice.module.ts b/src/app/features/navigator/admin/form/modules/choice/navigator-admin-form-choice.module.ts new file mode 100644 index 000000000..6a63382ab --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/choice/navigator-admin-form-choice.module.ts @@ -0,0 +1,48 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { EffectsModule } from '@ngrx/effects'; +import { StoreModule } from '@ngrx/store'; +import { TableComponent } from 'ngx-cinlib/tables'; +import { CoreModule } from 'src/app/core/core.module'; +import { NavigatorAdminFormChoiceComponent } from './components/navigator-admin-form-choice.component'; +import { navigatorAdminFormChoiceStateKey } from './constants/navigator-admin-form-choice.constants'; +import { NavigatorAdminFormChoiceEffects } from './state/navigator-admin-form-choice.effects'; +import { navigatorAdminFormChoiceReducer } from './state/navigator-admin-form-choice.reducer'; + +const components = [ + NavigatorAdminFormChoiceComponent, +] + +const framework = [ + CommonModule, +]; + +const materials = [ + MatButtonModule, + MatCardModule, +]; + +const modules = [ + CoreModule, +]; + +const libs = [ + StoreModule.forFeature(navigatorAdminFormChoiceStateKey, navigatorAdminFormChoiceReducer), + EffectsModule.forFeature([NavigatorAdminFormChoiceEffects]), + + TableComponent, +]; + +@NgModule({ + declarations: [...components], + imports: [ + ...framework, + ...libs, + ...materials, + ...modules, + ], + exports: [...components], +}) +export class NavigatorAdminFormChoiceModule { } diff --git a/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.actions.ts b/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.actions.ts new file mode 100644 index 000000000..d0a1dfa40 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.actions.ts @@ -0,0 +1,6 @@ +import { createActionGroup } from '@ngrx/store'; + +export const NavigatorAdminFormChoiceActions = createActionGroup({ + source: 'Navigator Admin Form choice', + events: {} +}); diff --git a/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.effects.ts b/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.effects.ts new file mode 100644 index 000000000..b48bb1f51 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.effects.ts @@ -0,0 +1,7 @@ +import { Injectable } from '@angular/core'; + + +@Injectable() +export class NavigatorAdminFormChoiceEffects { + constructor() { } +} diff --git a/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.reducer.ts b/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.reducer.ts new file mode 100644 index 000000000..ae82df72d --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.reducer.ts @@ -0,0 +1,14 @@ +import { createReducer } from '@ngrx/store'; + + + +export interface NavigatorAdminFormChoiceState { + +} + +export const initialState: NavigatorAdminFormChoiceState = { +}; + +export const navigatorAdminFormChoiceReducer = createReducer( + initialState, +); diff --git a/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.selectors.ts b/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.selectors.ts new file mode 100644 index 000000000..e27e7e6f0 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/choice/state/navigator-admin-form-choice.selectors.ts @@ -0,0 +1,7 @@ +import { createFeatureSelector } from '@ngrx/store'; +import { navigatorAdminFormChoiceStateKey } from '../constants/navigator-admin-form-choice.constants'; +import { NavigatorAdminFormChoiceState } from './navigator-admin-form-choice.reducer'; + + +export const selectNavigatorAdminFormChoiceState = createFeatureSelector(navigatorAdminFormChoiceStateKey); + diff --git a/src/app/features/navigator/admin/form/modules/layout/components/navigator-admin-form-layout.component.html b/src/app/features/navigator/admin/form/modules/layout/components/navigator-admin-form-layout.component.html new file mode 100644 index 000000000..393434d2f --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/layout/components/navigator-admin-form-layout.component.html @@ -0,0 +1,3 @@ + + + diff --git a/src/app/features/navigator/admin/form/modules/layout/components/navigator-admin-form-layout.component.scss b/src/app/features/navigator/admin/form/modules/layout/components/navigator-admin-form-layout.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/features/navigator/admin/form/modules/layout/components/navigator-admin-form-layout.component.ts b/src/app/features/navigator/admin/form/modules/layout/components/navigator-admin-form-layout.component.ts new file mode 100644 index 000000000..56f55213d --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/layout/components/navigator-admin-form-layout.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-navigator-admin-form-layout', + templateUrl: './navigator-admin-form-layout.component.html', + styleUrls: ['./navigator-admin-form-layout.component.scss'] +}) +export class NavigatorAdminFormLayoutComponent { +} \ No newline at end of file diff --git a/src/app/features/navigator/admin/form/modules/layout/constants/navigator-admin-form-layout.constants.ts b/src/app/features/navigator/admin/form/modules/layout/constants/navigator-admin-form-layout.constants.ts new file mode 100644 index 000000000..ebcdc47ed --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/layout/constants/navigator-admin-form-layout.constants.ts @@ -0,0 +1 @@ +export const navigatorAdminFormLayoutStateKey = 'navigatorAdminFormLayoutState'; \ No newline at end of file diff --git a/src/app/features/navigator/admin/form/modules/layout/navigator-admin-form-layout.module.ts b/src/app/features/navigator/admin/form/modules/layout/navigator-admin-form-layout.module.ts new file mode 100644 index 000000000..8cd42e7c8 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/layout/navigator-admin-form-layout.module.ts @@ -0,0 +1,52 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { EffectsModule } from '@ngrx/effects'; +import { StoreModule } from '@ngrx/store'; +import { PageTitleComponent } from 'ngx-cinlib/layouts/title'; +import { TableComponent } from 'ngx-cinlib/tables'; +import { CoreModule } from 'src/app/core/core.module'; +import { NavigatorAdminFormOverviewModule } from '../overview/navigator-admin-form-overview.module'; +import { NavigatorAdminFormLayoutComponent } from './components/navigator-admin-form-layout.component'; +import { navigatorAdminFormLayoutStateKey } from './constants/navigator-admin-form-layout.constants'; +import { NavigatorAdminFormLayoutEffects } from './state/navigator-admin-form-layout.effects'; +import { navigatorAdminFormLayoutReducer } from './state/navigator-admin-form-layout.reducer'; + +const components = [ + NavigatorAdminFormLayoutComponent, +] + +const framework = [ + CommonModule, +]; + +const materials = [ + MatButtonModule, + MatCardModule, +]; + +const modules = [ + CoreModule, + NavigatorAdminFormOverviewModule, +]; + +const libs = [ + StoreModule.forFeature(navigatorAdminFormLayoutStateKey, navigatorAdminFormLayoutReducer), + EffectsModule.forFeature([NavigatorAdminFormLayoutEffects]), + + TableComponent, + PageTitleComponent, +]; + +@NgModule({ + declarations: [...components], + imports: [ + ...framework, + ...libs, + ...materials, + ...modules, + ], + exports: [...components], +}) +export class NavigatorAdminFormLayoutModule { } diff --git a/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.actions.ts b/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.actions.ts new file mode 100644 index 000000000..d00c1dd49 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.actions.ts @@ -0,0 +1,10 @@ +import { createActionGroup } from '@ngrx/store'; + + + +export const NavigatorAdminFormLayoutActions = createActionGroup({ + source: 'Navigator Admin Form page', + events: { + + } +}); diff --git a/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.effects.ts b/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.effects.ts new file mode 100644 index 000000000..70ba833c1 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.effects.ts @@ -0,0 +1,11 @@ +import { Injectable } from '@angular/core'; + + +@Injectable() +export class NavigatorAdminFormLayoutEffects { + + + + constructor( + ) { } +} diff --git a/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.reducer.ts b/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.reducer.ts new file mode 100644 index 000000000..f99763514 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.reducer.ts @@ -0,0 +1,14 @@ +import { createReducer } from '@ngrx/store'; + + + +export interface NavigatorAdminFormLayoutState { + +} + +export const initialState: NavigatorAdminFormLayoutState = { +}; + +export const navigatorAdminFormLayoutReducer = createReducer( + initialState, +); diff --git a/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.selectors.ts b/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.selectors.ts new file mode 100644 index 000000000..7d07c6a88 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/layout/state/navigator-admin-form-layout.selectors.ts @@ -0,0 +1,7 @@ +import { createFeatureSelector } from '@ngrx/store'; +import { navigatorAdminFormLayoutStateKey } from '../constants/navigator-admin-form-layout.constants'; +import { NavigatorAdminFormLayoutState } from './navigator-admin-form-layout.reducer'; + + +export const selectNavigatorAdminFormLayoutState = createFeatureSelector(navigatorAdminFormLayoutStateKey); + diff --git a/src/app/features/navigator/admin/form/modules/overview/components/navigator-admin-form-overview.component.html b/src/app/features/navigator/admin/form/modules/overview/components/navigator-admin-form-overview.component.html new file mode 100644 index 000000000..cf396b59e --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/overview/components/navigator-admin-form-overview.component.html @@ -0,0 +1,25 @@ + + + + + {{ (node.item | translatable: 'title' | async) ?? + (node.item | translatable: 'name' | async) }} + + + + + {{ (node.item | translatable: 'title' | async) ?? + (node.item | translatable: 'name' | async) }} + + + diff --git a/src/app/features/navigator/admin/form/modules/overview/components/navigator-admin-form-overview.component.scss b/src/app/features/navigator/admin/form/modules/overview/components/navigator-admin-form-overview.component.scss new file mode 100644 index 000000000..c7ebfde37 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/overview/components/navigator-admin-form-overview.component.scss @@ -0,0 +1,10 @@ +span { + cursor: pointer; + border-radius: 5rem; + padding-left: .5rem; + padding-right: .5rem; +} + +span:hover{ + background-color: var(--color-light); +} \ No newline at end of file diff --git a/src/app/features/navigator/admin/form/modules/overview/components/navigator-admin-form-overview.component.ts b/src/app/features/navigator/admin/form/modules/overview/components/navigator-admin-form-overview.component.ts new file mode 100644 index 000000000..d4967a713 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/overview/components/navigator-admin-form-overview.component.ts @@ -0,0 +1,82 @@ +import { FlatTreeControl } from '@angular/cdk/tree'; +import { Component, OnInit } from '@angular/core'; +import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree'; +import { Store } from '@ngrx/store'; +import { TranslationService } from 'ngx-cinlib/i18n'; +import { NavigatorChoiceEntity, NavigatorPageEntity } from 'src/app/core/api/generated/schema'; +import { NavigatorAdminFormOverviewActions } from '../state/navigator-admin-form-overview.actions'; +import { selectStartPage } from '../state/navigator-admin-form-overview.selectors'; + +interface TreeNode { + item: NavigatorPageEntity | NavigatorChoiceEntity, + children?: TreeNode[], +} + +interface FlatNode { + expandable: boolean, + item: NavigatorPageEntity | NavigatorChoiceEntity, + level: number, +} + +const TREE_DATA: TreeNode[] = []; + +@Component({ + selector: 'app-navigator-admin-form-overview', + templateUrl: './navigator-admin-form-overview.component.html', + styleUrls: ['./navigator-admin-form-overview.component.scss'] +}) +export class NavigatorAdminFormOverviewComponent implements OnInit { + +getNextPage() { + +} + +pageDetails() { +throw new Error('Method not implemented.'); +} + + constructor(private store: Store, private translationService: TranslationService) { + this.dataSource.data = TREE_DATA; + } + + ngOnInit(): void { + this.store.dispatch(NavigatorAdminFormOverviewActions.getStartPage()); + this.store.select(selectStartPage).subscribe(page => { + if (page) { + const children = page.choices?.map((choice) => ({ + item: choice!, + children: choice?.nextPage ? [{item: choice?.nextPage!}] : undefined + })) ?? []; + const treeNode: TreeNode = { + item: page!, + children: children + }; + this.dataSource.data = [...this.dataSource.data, treeNode]; + } + }); + } + + treeControl = new FlatTreeControl( + node => node.level, + node => node.expandable, + ); + + private transformer = (node: TreeNode, level: number) => { + return { + expandable: !!node.children && node.children.length > 0, + item: node.item, + level: level + } + } + + private treeFlattener = new MatTreeFlattener( + this.transformer, + node => node.level, + node => node.expandable, + node => node.children + ); + + dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); + + hasChild = (_: number, node: FlatNode) => node.expandable; +} \ No newline at end of file diff --git a/src/app/features/navigator/admin/form/modules/overview/constants/navigator-admin-form-overview.constants.ts b/src/app/features/navigator/admin/form/modules/overview/constants/navigator-admin-form-overview.constants.ts new file mode 100644 index 000000000..bb8bd63e3 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/overview/constants/navigator-admin-form-overview.constants.ts @@ -0,0 +1 @@ +export const navigatorAdminFormOverviewStateKey = 'navigatorAdminFormOverviewState'; \ No newline at end of file diff --git a/src/app/features/navigator/admin/form/modules/overview/navigator-admin-form-overview.module.ts b/src/app/features/navigator/admin/form/modules/overview/navigator-admin-form-overview.module.ts new file mode 100644 index 000000000..321e23a1b --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/overview/navigator-admin-form-overview.module.ts @@ -0,0 +1,55 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatProgressBar } from '@angular/material/progress-bar'; +import { MatTreeModule } from '@angular/material/tree'; +import { EffectsModule } from '@ngrx/effects'; +import { StoreModule } from '@ngrx/store'; +import { TranslatablePipe } from 'ngx-cinlib/i18n'; +import { IconComponent } from 'ngx-cinlib/icons'; +import { TableComponent } from 'ngx-cinlib/tables'; +import { CoreModule } from 'src/app/core/core.module'; +import { NavigatorAdminFormOverviewComponent } from './components/navigator-admin-form-overview.component'; +import { navigatorAdminFormOverviewStateKey } from './constants/navigator-admin-form-overview.constants'; +import { NavigatorAdminFormOverviewEffects } from './state/navigator-admin-form-overview.effects'; +import { navigatorAdminFormOverviewReducer } from './state/navigator-admin-form-overview.reducer'; + +const components = [ + NavigatorAdminFormOverviewComponent, +] + +const framework = [ + CommonModule, +]; + +const materials = [ + MatButtonModule, + MatCardModule, + MatTreeModule, + MatProgressBar +]; + +const modules = [ + CoreModule, +]; + +const libs = [ + StoreModule.forFeature(navigatorAdminFormOverviewStateKey, navigatorAdminFormOverviewReducer), + EffectsModule.forFeature([NavigatorAdminFormOverviewEffects]), + IconComponent, + TableComponent, + TranslatablePipe, +]; + +@NgModule({ + declarations: [...components], + imports: [ + ...framework, + ...libs, + ...materials, + ...modules, + ], + exports: [...components], +}) +export class NavigatorAdminFormOverviewModule { } diff --git a/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.actions.ts b/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.actions.ts new file mode 100644 index 000000000..ebf35f28f --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.actions.ts @@ -0,0 +1,13 @@ +import { createActionGroup, emptyProps } from '@ngrx/store'; +import { Maybe, NavigatorPageEntity } from 'src/app/core/api/generated/schema'; + +export const NavigatorAdminFormOverviewActions = createActionGroup({ + source: 'Navigator Admin Form overview', + events: { + 'get start page': emptyProps(), + 'set start page': (startPage: Maybe) => ({ startPage }), + + 'get page': (slug: Maybe) => ({ slug }), + 'set page': (page: Maybe) => ({ page }), + } +}); diff --git a/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.effects.ts b/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.effects.ts new file mode 100644 index 000000000..21afabcfd --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.effects.ts @@ -0,0 +1,39 @@ +import { Injectable } from '@angular/core'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; +import { filter, map, switchMap } from 'rxjs'; +import { AdminActions } from 'src/app/admin/state/admin.actions'; +import { NavigatorPageEntity } from 'src/app/core/api/generated/schema'; +import { GetNavigatorPageGQL } from 'src/app/features/navigator/api/generated/get-navigator-page.query.generated'; +import { GetNavigatorStartPageGQL } from 'src/app/features/navigator/api/generated/get-navigator-start-page.query.generated'; +import { NavigatorAdminFormOverviewActions } from './navigator-admin-form-overview.actions'; + + +@Injectable() +export class NavigatorAdminFormOverviewEffects { + + getStartPage = createEffect(() => this.actions.pipe( + ofType(NavigatorAdminFormOverviewActions.getStartPage), + switchMap( () => this.getNavigatorStartPageService.watch().valueChanges), + filter(response => !!response.data.getNavigatorStartPage?.id), + map(response => NavigatorAdminFormOverviewActions.setStartPage(response.data.getNavigatorStartPage as NavigatorPageEntity)) + )); + + getPage = createEffect(() => this.actions.pipe( + ofType(NavigatorAdminFormOverviewActions.getPage), + switchMap((action) => this.getNavigatorPageService.watch({ + entity: { + slug: action.slug + } + }).valueChanges), + map(response => response.data.getNavigatorPage?.id + ? NavigatorAdminFormOverviewActions.setPage(response.data.getNavigatorPage as NavigatorPageEntity) + : AdminActions.notFound()) + )); + + constructor( + private actions: Actions, + private getNavigatorStartPageService: GetNavigatorStartPageGQL, + private getNavigatorPageService: GetNavigatorPageGQL + + ) {} +} diff --git a/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.reducer.ts b/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.reducer.ts new file mode 100644 index 000000000..bf9955031 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.reducer.ts @@ -0,0 +1,22 @@ +import { createReducer, on } from '@ngrx/store'; +import { Maybe, NavigatorPageEntity } from 'src/app/core/api/generated/schema'; +import { NavigatorAdminFormOverviewActions } from './navigator-admin-form-overview.actions'; + + + +export interface NavigatorAdminFormOverviewState { + startPage?: Maybe; +} + +export const initialState: NavigatorAdminFormOverviewState = { +}; + +export const navigatorAdminFormOverviewReducer = createReducer( + initialState, + + on( + NavigatorAdminFormOverviewActions.setStartPage, + (state, action): NavigatorAdminFormOverviewState => ({ + ...state, startPage: action.startPage + })), +); diff --git a/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.selectors.ts b/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.selectors.ts new file mode 100644 index 000000000..59154b5f3 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/overview/state/navigator-admin-form-overview.selectors.ts @@ -0,0 +1,11 @@ +import { createFeatureSelector, createSelector } from '@ngrx/store'; +import { navigatorAdminFormOverviewStateKey } from '../constants/navigator-admin-form-overview.constants'; +import { NavigatorAdminFormOverviewState } from './navigator-admin-form-overview.reducer'; + + +export const selectNavigatorAdminFormOverviewState = createFeatureSelector(navigatorAdminFormOverviewStateKey); + +export const selectStartPage = createSelector( + selectNavigatorAdminFormOverviewState, + state => state.startPage +); diff --git a/src/app/features/navigator/admin/form/modules/page/components/navigator-admin-form-page.component.html b/src/app/features/navigator/admin/form/modules/page/components/navigator-admin-form-page.component.html new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/features/navigator/admin/form/modules/page/components/navigator-admin-form-page.component.scss b/src/app/features/navigator/admin/form/modules/page/components/navigator-admin-form-page.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/features/navigator/admin/form/modules/page/components/navigator-admin-form-page.component.ts b/src/app/features/navigator/admin/form/modules/page/components/navigator-admin-form-page.component.ts new file mode 100644 index 000000000..af5a5fd70 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/page/components/navigator-admin-form-page.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-navigator-admin-form-page', + templateUrl: './navigator-admin-form-page.component.html', + styleUrls: ['./navigator-admin-form-page.component.scss'] +}) +export class NavigatorAdminFormPageComponent { +} \ No newline at end of file diff --git a/src/app/features/navigator/admin/form/modules/page/constants/navigator-admin-form-page.constants.ts b/src/app/features/navigator/admin/form/modules/page/constants/navigator-admin-form-page.constants.ts new file mode 100644 index 000000000..5564a3100 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/page/constants/navigator-admin-form-page.constants.ts @@ -0,0 +1 @@ +export const navigatorAdminFormPageStateKey = 'navigatorAdminFormPageState'; \ No newline at end of file diff --git a/src/app/features/navigator/admin/form/modules/page/navigator-admin-form-page.module.ts b/src/app/features/navigator/admin/form/modules/page/navigator-admin-form-page.module.ts new file mode 100644 index 000000000..ceba788a1 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/page/navigator-admin-form-page.module.ts @@ -0,0 +1,48 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { EffectsModule } from '@ngrx/effects'; +import { StoreModule } from '@ngrx/store'; +import { TableComponent } from 'ngx-cinlib/tables'; +import { CoreModule } from 'src/app/core/core.module'; +import { NavigatorAdminFormPageComponent } from './components/navigator-admin-form-page.component'; +import { navigatorAdminFormPageStateKey } from './constants/navigator-admin-form-page.constants'; +import { NavigatorAdminFormPageEffects } from './state/navigator-admin-form-page.effects'; +import { navigatorAdminFormPageReducer } from './state/navigator-admin-form-page.reducer'; + +const components = [ + NavigatorAdminFormPageComponent, +] + +const framework = [ + CommonModule, +]; + +const materials = [ + MatButtonModule, + MatCardModule, +]; + +const modules = [ + CoreModule, +]; + +const libs = [ + StoreModule.forFeature(navigatorAdminFormPageStateKey, navigatorAdminFormPageReducer), + EffectsModule.forFeature([NavigatorAdminFormPageEffects]), + + TableComponent, +]; + +@NgModule({ + declarations: [...components], + imports: [ + ...framework, + ...libs, + ...materials, + ...modules, + ], + exports: [...components], +}) +export class NavigatorAdminFormPageModule { } diff --git a/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.actions.ts b/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.actions.ts new file mode 100644 index 000000000..cc7c2b3b4 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.actions.ts @@ -0,0 +1,10 @@ +import { createActionGroup } from '@ngrx/store'; + + + +export const NavigatorAdminFormPageActions = createActionGroup({ + source: 'Navigator Admin Form page', + events: { + + } +}); diff --git a/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.effects.ts b/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.effects.ts new file mode 100644 index 000000000..1ec0068b6 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.effects.ts @@ -0,0 +1,11 @@ +import { Injectable } from '@angular/core'; + + +@Injectable() +export class NavigatorAdminFormPageEffects { + + + + constructor( + ) { } +} diff --git a/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.reducer.ts b/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.reducer.ts new file mode 100644 index 000000000..e05d40d97 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.reducer.ts @@ -0,0 +1,14 @@ +import { createReducer } from '@ngrx/store'; + + + +export interface NavigatorAdminFormPageState { + +} + +export const initialState: NavigatorAdminFormPageState = { +}; + +export const navigatorAdminFormPageReducer = createReducer( + initialState, +); diff --git a/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.selectors.ts b/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.selectors.ts new file mode 100644 index 000000000..6af580d43 --- /dev/null +++ b/src/app/features/navigator/admin/form/modules/page/state/navigator-admin-form-page.selectors.ts @@ -0,0 +1,7 @@ +import { createFeatureSelector } from '@ngrx/store'; +import { navigatorAdminFormPageStateKey } from '../constants/navigator-admin-form-page.constants'; +import { NavigatorAdminFormPageState } from './navigator-admin-form-page.reducer'; + + +export const selectNavigatorAdminFormPageState = createFeatureSelector(navigatorAdminFormPageStateKey); + diff --git a/src/app/features/navigator/admin/form/navigator-admin-form-routing.module.ts b/src/app/features/navigator/admin/form/navigator-admin-form-routing.module.ts new file mode 100644 index 000000000..f77b588f8 --- /dev/null +++ b/src/app/features/navigator/admin/form/navigator-admin-form-routing.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { NavigatorAdminFormLayoutComponent } from './modules/layout/components/navigator-admin-form-layout.component'; + +const routes: Routes = [ + { + path: '', + loadChildren: () => import('./modules/layout/navigator-admin-form-layout.module') + .then((imported) => imported.NavigatorAdminFormLayoutModule), + component: NavigatorAdminFormLayoutComponent + }, + // { + // path: visitorsRoute, + // loadChildren: () => import('./modules/visitors/event-admin-details-visitors.module') + // .then((imported) => imported.NavigatorAdminDetailsVisitorsModule), + // component: NavigatorAdminDetailsVisitorsComponent + // }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class NavigatorAdminFormRoutingModule { } + diff --git a/src/app/features/navigator/admin/form/navigator-admin-form.module.ts b/src/app/features/navigator/admin/form/navigator-admin-form.module.ts new file mode 100644 index 000000000..d571219a6 --- /dev/null +++ b/src/app/features/navigator/admin/form/navigator-admin-form.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { NavigatorAdminFormLayoutModule } from './modules/layout/navigator-admin-form-layout.module'; +import { NavigatorAdminFormRoutingModule } from './navigator-admin-form-routing.module'; + +const modules = [ + NavigatorAdminFormLayoutModule, + NavigatorAdminFormRoutingModule, +]; + +@NgModule({ + imports: [ + ...modules, + ], + exports: [], +}) +export class NavigatorAdminFormModule { } diff --git a/src/app/features/navigator/admin/navigator-admin-routing.module.ts b/src/app/features/navigator/admin/navigator-admin-routing.module.ts new file mode 100644 index 000000000..81e05389d --- /dev/null +++ b/src/app/features/navigator/admin/navigator-admin-routing.module.ts @@ -0,0 +1,42 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { AdminActions } from 'src/app/admin/state/admin.actions'; +import { AdminFeatureRoute } from 'src/app/admin/typings/menu'; +import { navigatorFeatureKey } from 'src/app/core/constants/feature.constants'; +import { requireAnyPrivilege } from 'src/app/core/utils/privilege.utils'; + +const menuRoutes: AdminFeatureRoute[] = [ + { + path: navigatorFeatureKey, + loadChildren: () => import('src/app/features/navigator/admin/form/navigator-admin-form.module') + .then((imported) => imported.NavigatorAdminFormModule), + data: { + label: 'create/edit', + privileges: ['navigator_admin'], + }, + canActivate: [requireAnyPrivilege('navigator_admin')] + }, +]; + +const routes: Routes = [ +] + +@NgModule({ + imports: [RouterModule.forChild([ + ...menuRoutes, + ...routes, + ])], + exports: [RouterModule] +}) +export class NavigatorAdminRoutingModule { + + constructor( + public store: Store + ) { + this.store.dispatch(AdminActions.addMainRoutes({ + code: navigatorFeatureKey, + routes: menuRoutes, + })); + } +} diff --git a/src/app/features/navigator/api/codegen/codegen.ts b/src/app/features/navigator/api/codegen/codegen.ts new file mode 100644 index 000000000..ca5629f16 --- /dev/null +++ b/src/app/features/navigator/api/codegen/codegen.ts @@ -0,0 +1,32 @@ +import type { CodegenConfig } from '@graphql-codegen/cli'; +import { graphqlGenerationApi } from '../../../../core/api/codegen/constants'; + +const config: CodegenConfig = { + schema: graphqlGenerationApi, + documents: [ + 'src/app/core/api/documents/fragments/**/*.graphql', + 'src/app/features/navigator/api/documents/**/*.graphql', + ], + generates: { + 'src/app/core/api/generated': { + preset: 'near-operation-file-preset', + presetConfig: { + baseTypesPath: 'schema.ts', + folder: '../../generated' + }, + plugins: [ + 'typescript-operations', + 'typescript-apollo-angular', + { + 'add': { + content: '/* eslint-disable */' + } + } + ], + config: { + addExplicitOverride: true, + }, + }, + }, +}; +export default config; \ No newline at end of file diff --git a/src/app/features/navigator/api/documents/mutation/delete-navigator-node.mutation.graphql b/src/app/features/navigator/api/documents/mutation/delete-navigator-node.mutation.graphql new file mode 100644 index 000000000..cb3abee76 --- /dev/null +++ b/src/app/features/navigator/api/documents/mutation/delete-navigator-node.mutation.graphql @@ -0,0 +1,3 @@ +mutation deleteNavigatorPage($id: String) { + deleteNavigatorPage(id: $id) +} \ No newline at end of file diff --git a/src/app/features/navigator/api/documents/queries/get-navigator-page.query.graphql b/src/app/features/navigator/api/documents/queries/get-navigator-page.query.graphql new file mode 100644 index 000000000..0d065acc8 --- /dev/null +++ b/src/app/features/navigator/api/documents/queries/get-navigator-page.query.graphql @@ -0,0 +1,73 @@ +query getNavigatorPage($entity: NavigatorPageEntityInput) { + getNavigatorPage(entity: $entity) { + id + modified + created + slug + title + additionalInformation + + translatables { + id + additionalInformation + title + language { + id + locale + name + } + } + + choices { + id + description + name + parent { + id + slug + } + nextPage { + id + slug + } + translatables { + id + name + description + language { + id + locale + name + } + } + } + + parentChoices { + id + translatables { + id + name + language { + id + locale + name + } + } + } + + links { + id + name + url + translatables { + id + name + language { + id + locale + name + } + } + } + } +} \ No newline at end of file diff --git a/src/app/features/navigator/api/documents/queries/get-navigator-start-page.query.graphql b/src/app/features/navigator/api/documents/queries/get-navigator-start-page.query.graphql new file mode 100644 index 000000000..97a45e01f --- /dev/null +++ b/src/app/features/navigator/api/documents/queries/get-navigator-start-page.query.graphql @@ -0,0 +1,46 @@ +query getNavigatorStartPage { + getNavigatorStartPage { + id + modified + created + slug + title + additionalInformation + isResultPage + + choices { + id + description + name + nextPage { + id + slug + } + translatables { + id + name + description + language { + id + locale + name + } + } + } + + parentChoices { + id + } + + translatables { + id + additionalInformation + title + language { + id + locale + name + } + } + } +} \ No newline at end of file diff --git a/src/app/features/navigator/api/generated/delete-navigator-node.mutation.generated.ts b/src/app/features/navigator/api/generated/delete-navigator-node.mutation.generated.ts new file mode 100644 index 000000000..79eb982c6 --- /dev/null +++ b/src/app/features/navigator/api/generated/delete-navigator-node.mutation.generated.ts @@ -0,0 +1,29 @@ +/* eslint-disable */ +import * as Types from '../../../../core/api/generated/schema'; + +import { gql } from 'apollo-angular'; +import { Injectable } from '@angular/core'; +import * as Apollo from 'apollo-angular'; +export type DeleteNavigatorPageMutationVariables = Types.Exact<{ + id?: Types.InputMaybe; +}>; + + +export type DeleteNavigatorPageMutation = { __typename?: 'Mutation', deleteNavigatorPage?: boolean | null }; + +export const DeleteNavigatorPageDocument = gql` + mutation deleteNavigatorPage($id: String) { + deleteNavigatorPage(id: $id) +} + `; + + @Injectable({ + providedIn: 'root' + }) + export class DeleteNavigatorPageGQL extends Apollo.Mutation { + override document = DeleteNavigatorPageDocument; + + constructor(apollo: Apollo.Apollo) { + super(apollo); + } + } \ No newline at end of file diff --git a/src/app/features/navigator/api/generated/get-articles.query.generated.ts b/src/app/features/navigator/api/generated/get-articles.query.generated.ts new file mode 100644 index 000000000..5cfce10e9 --- /dev/null +++ b/src/app/features/navigator/api/generated/get-articles.query.generated.ts @@ -0,0 +1,74 @@ +/* eslint-disable */ +import * as Types from '../../../../core/api/generated/schema'; + +import { gql } from 'apollo-angular'; +import { LanguageFragmentDoc } from '../../../../core/api/generated/language.fragment.generated'; +import { Injectable } from '@angular/core'; +import * as Apollo from 'apollo-angular'; +export type GetNavigatorPagesQueryVariables = Types.Exact<{ + params?: Types.InputMaybe; +}>; + + +export type GetNavigatorPagesQuery = { __typename?: 'Query', getNavigatorPages?: { __typename?: 'PageableList_NavigatorPageEntity', total: any, result?: Array<{ __typename?: 'NavigatorPageEntity', id?: string | null, created?: any | null, modified?: any | null, slug?: string | null, title?: string | null, additionalInformation?: string | null, isResultPage?: boolean | null, translatables?: Array<{ __typename?: 'NavigatorPageTranslatableEntity', id?: string | null, title?: string | null, additionalInformation?: string | null, language?: { __typename?: 'LanguageEntity', id?: string | null, locale?: string | null, name?: string | null } | null } | null> | null, parentChoices?: Array<{ __typename?: 'NavigatorChoiceEntity', id?: string | null, translatables?: Array<{ __typename?: 'NavigatorChoiceTranslatableEntity', id?: string | null, name?: string | null, description?: string | null, language?: { __typename?: 'LanguageEntity', id?: string | null, locale?: string | null, name?: string | null } | null } | null> | null } | null> | null, choices?: Array<{ __typename?: 'NavigatorChoiceEntity', id?: string | null, nextPage?: { __typename?: 'NavigatorPageEntity', id?: string | null } | null, translatables?: Array<{ __typename?: 'NavigatorChoiceTranslatableEntity', id?: string | null, name?: string | null, description?: string | null, language?: { __typename?: 'LanguageEntity', id?: string | null, locale?: string | null, name?: string | null } | null } | null> | null } | null> | null } | null> | null } | null }; + +export const GetNavigatorPagesDocument = gql` + query getNavigatorPages($params: FilterSortPaginateInput) { + getNavigatorPages(params: $params) { + result { + id + created + modified + slug + title + additionalInformation + isResultPage + translatables { + id + title + additionalInformation + language { + ...Language + } + } + parentChoices { + id + translatables { + id + name + description + language { + ...Language + } + } + } + choices { + id + nextPage { + id + } + translatables { + id + name + description + language { + ...Language + } + } + } + } + total + } +} + ${LanguageFragmentDoc}`; + + @Injectable({ + providedIn: 'root' + }) + export class GetNavigatorPagesGQL extends Apollo.Query { + override document = GetNavigatorPagesDocument; + + constructor(apollo: Apollo.Apollo) { + super(apollo); + } + } \ No newline at end of file diff --git a/src/app/features/navigator/api/generated/get-navigator-page.query.generated.ts b/src/app/features/navigator/api/generated/get-navigator-page.query.generated.ts new file mode 100644 index 000000000..7c1e27a8e --- /dev/null +++ b/src/app/features/navigator/api/generated/get-navigator-page.query.generated.ts @@ -0,0 +1,95 @@ +/* eslint-disable */ +import * as Types from '../../../../core/api/generated/schema'; + +import { gql } from 'apollo-angular'; +import { Injectable } from '@angular/core'; +import * as Apollo from 'apollo-angular'; +export type GetNavigatorPageQueryVariables = Types.Exact<{ + entity?: Types.InputMaybe; +}>; + + +export type GetNavigatorPageQuery = { __typename?: 'Query', getNavigatorPage?: { __typename?: 'NavigatorPageEntity', id?: string | null, modified?: any | null, created?: any | null, slug?: string | null, title?: string | null, additionalInformation?: string | null, translatables?: Array<{ __typename?: 'NavigatorPageTranslatableEntity', id?: string | null, additionalInformation?: string | null, title?: string | null, language?: { __typename?: 'LanguageEntity', id?: string | null, locale?: string | null, name?: string | null } | null } | null> | null, choices?: Array<{ __typename?: 'NavigatorChoiceEntity', id?: string | null, description?: string | null, name?: string | null, parent?: { __typename?: 'NavigatorPageEntity', id?: string | null, slug?: string | null } | null, nextPage?: { __typename?: 'NavigatorPageEntity', id?: string | null, slug?: string | null } | null, translatables?: Array<{ __typename?: 'NavigatorChoiceTranslatableEntity', id?: string | null, name?: string | null, description?: string | null, language?: { __typename?: 'LanguageEntity', id?: string | null, locale?: string | null, name?: string | null } | null } | null> | null } | null> | null, parentChoices?: Array<{ __typename?: 'NavigatorChoiceEntity', id?: string | null, translatables?: Array<{ __typename?: 'NavigatorChoiceTranslatableEntity', id?: string | null, name?: string | null, language?: { __typename?: 'LanguageEntity', id?: string | null, locale?: string | null, name?: string | null } | null } | null> | null } | null> | null, links?: Array<{ __typename?: 'NavigatorResultLinkEntity', id?: string | null, name?: string | null, url?: string | null, translatables?: Array<{ __typename?: 'NavigatorResultLinkTranslatableEntity', id?: string | null, name?: string | null, language?: { __typename?: 'LanguageEntity', id?: string | null, locale?: string | null, name?: string | null } | null } | null> | null } | null> | null } | null }; + +export const GetNavigatorPageDocument = gql` + query getNavigatorPage($entity: NavigatorPageEntityInput) { + getNavigatorPage(entity: $entity) { + id + modified + created + slug + title + additionalInformation + translatables { + id + additionalInformation + title + language { + id + locale + name + } + } + choices { + id + description + name + parent { + id + slug + } + nextPage { + id + slug + } + translatables { + id + name + description + language { + id + locale + name + } + } + } + parentChoices { + id + translatables { + id + name + language { + id + locale + name + } + } + } + links { + id + name + url + translatables { + id + name + language { + id + locale + name + } + } + } + } +} + `; + + @Injectable({ + providedIn: 'root' + }) + export class GetNavigatorPageGQL extends Apollo.Query { + override document = GetNavigatorPageDocument; + + constructor(apollo: Apollo.Apollo) { + super(apollo); + } + } \ No newline at end of file diff --git a/src/app/features/navigator/api/generated/get-navigator-start-page.query.generated.ts b/src/app/features/navigator/api/generated/get-navigator-start-page.query.generated.ts new file mode 100644 index 000000000..3ed457362 --- /dev/null +++ b/src/app/features/navigator/api/generated/get-navigator-start-page.query.generated.ts @@ -0,0 +1,67 @@ +/* eslint-disable */ +import * as Types from '../../../../core/api/generated/schema'; + +import { gql } from 'apollo-angular'; +import { Injectable } from '@angular/core'; +import * as Apollo from 'apollo-angular'; +export type GetNavigatorStartPageQueryVariables = Types.Exact<{ [key: string]: never; }>; + + +export type GetNavigatorStartPageQuery = { __typename?: 'Query', getNavigatorStartPage?: { __typename?: 'NavigatorPageEntity', id?: string | null, modified?: any | null, created?: any | null, slug?: string | null, title?: string | null, additionalInformation?: string | null, isResultPage?: boolean | null, choices?: Array<{ __typename?: 'NavigatorChoiceEntity', id?: string | null, description?: string | null, name?: string | null, nextPage?: { __typename?: 'NavigatorPageEntity', id?: string | null, slug?: string | null } | null, translatables?: Array<{ __typename?: 'NavigatorChoiceTranslatableEntity', id?: string | null, name?: string | null, description?: string | null, language?: { __typename?: 'LanguageEntity', id?: string | null, locale?: string | null, name?: string | null } | null } | null> | null } | null> | null, parentChoices?: Array<{ __typename?: 'NavigatorChoiceEntity', id?: string | null } | null> | null, translatables?: Array<{ __typename?: 'NavigatorPageTranslatableEntity', id?: string | null, additionalInformation?: string | null, title?: string | null, language?: { __typename?: 'LanguageEntity', id?: string | null, locale?: string | null, name?: string | null } | null } | null> | null } | null }; + +export const GetNavigatorStartPageDocument = gql` + query getNavigatorStartPage { + getNavigatorStartPage { + id + modified + created + slug + title + additionalInformation + isResultPage + choices { + id + description + name + nextPage { + id + slug + } + translatables { + id + name + description + language { + id + locale + name + } + } + } + parentChoices { + id + } + translatables { + id + additionalInformation + title + language { + id + locale + name + } + } + } +} + `; + + @Injectable({ + providedIn: 'root' + }) + export class GetNavigatorStartPageGQL extends Apollo.Query { + override document = GetNavigatorStartPageDocument; + + constructor(apollo: Apollo.Apollo) { + super(apollo); + } + } \ No newline at end of file diff --git a/src/app/features/navigator/portal/details/constants/navigator-details.constant.ts b/src/app/features/navigator/portal/details/constants/navigator-details.constant.ts new file mode 100644 index 000000000..7e445eec4 --- /dev/null +++ b/src/app/features/navigator/portal/details/constants/navigator-details.constant.ts @@ -0,0 +1,2 @@ +export const navigatorStartRoute = 'start'; +export const navigatorResultRoute = 'result'; \ No newline at end of file diff --git a/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.component.html b/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.component.html new file mode 100644 index 000000000..22c7e76a0 --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.component.html @@ -0,0 +1,15 @@ +
+ hero-section +
+
+ + +

+ + + +
+
+
\ No newline at end of file diff --git a/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.component.scss b/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.component.scss new file mode 100644 index 000000000..1d9eb1072 --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.component.scss @@ -0,0 +1,51 @@ +@import 'ngx-cinlib/styles/mobile-mixins.scss'; + +header { + display: flex; + justify-content: center; + min-height: 80vh; + gap: 5rem; + flex-flow: row-reverse; + + img { + max-width: 40%; + @include responsive(phone) { + display: none; + } + } + + cin-page-title{ + width: min-content; + } + + section { + display: flex; + align-self: center; + justify-content: center; + + div { + display: flex; + flex-direction: column; + gap: var(--gap); + } + + app-gradient-button { + width: fit-content; + } + + p { + color: var(--color-dark-gray); + font-size: 1.25rem; + font-weight: 500; + line-height: 1.5; + max-width: 35vw; + overflow-wrap: break-word; + hyphens: auto; + -webkit-hyphens: auto; + + @include responsive(phone) { + max-width: 90vw; + } + } + } +} diff --git a/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.component.ts b/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.component.ts new file mode 100644 index 000000000..3ec1fbad3 --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-navigator-portal-details-landing', + templateUrl: './navigator-portal-details-landing.component.html', + styleUrls: ['./navigator-portal-details-landing.component.scss'] +}) +export class NavigatorPortalDetailsLandingComponent { +} \ No newline at end of file diff --git a/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.module.ts b/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.module.ts new file mode 100644 index 000000000..ee6ff45dc --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/landing/navigator-portal-details-landing.module.ts @@ -0,0 +1,52 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { RouterModule } from '@angular/router'; +import { RadioCardGroupComponent } from 'ngx-cinlib/forms/radio-card'; +import { I18nDirective, TranslatablePipe } from 'ngx-cinlib/i18n'; +import { IconComponent } from 'ngx-cinlib/icons'; +import { PageTitleComponent, SubTitleComponent } from 'ngx-cinlib/layouts/title'; +import { CoreModule } from 'src/app/core/core.module'; +import { GradientButtonComponent } from 'src/app/shared/widgets/gradient-button/gradient-button.component'; +import { NavigatorPortalDetailsLandingComponent } from './navigator-portal-details-landing.component'; + +const components = [ + NavigatorPortalDetailsLandingComponent, +] + +const framework = [ + CommonModule, + RouterModule, +]; + +const materials = [ + MatButtonModule, + MatCardModule, +]; + +const modules = [ + CoreModule, +]; + +const libs = [ + GradientButtonComponent, + IconComponent, + I18nDirective, + PageTitleComponent, + SubTitleComponent, + RadioCardGroupComponent, + TranslatablePipe, +]; + +@NgModule({ + declarations: [...components], + imports: [ + ...framework, + ...libs, + ...materials, + ...modules, + ], + exports: [...components], +}) +export class NavigatorPortalDetailsLandingModule { } diff --git a/src/app/features/navigator/portal/details/modules/layout/components/choice/navigator-portal-details-layout-choice.component.html b/src/app/features/navigator/portal/details/modules/layout/components/choice/navigator-portal-details-layout-choice.component.html new file mode 100644 index 000000000..b8ea9c1af --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/components/choice/navigator-portal-details-layout-choice.component.html @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/app/features/navigator/portal/details/modules/layout/components/choice/navigator-portal-details-layout-choice.component.scss b/src/app/features/navigator/portal/details/modules/layout/components/choice/navigator-portal-details-layout-choice.component.scss new file mode 100644 index 000000000..bb53f5a2c --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/components/choice/navigator-portal-details-layout-choice.component.scss @@ -0,0 +1,4 @@ +app-gradient-button { + width: 100%; +} + diff --git a/src/app/features/navigator/portal/details/modules/layout/components/choice/navigator-portal-details-layout-choice.component.ts b/src/app/features/navigator/portal/details/modules/layout/components/choice/navigator-portal-details-layout-choice.component.ts new file mode 100644 index 000000000..474e939bb --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/components/choice/navigator-portal-details-layout-choice.component.ts @@ -0,0 +1,51 @@ +import { Component, Input } from '@angular/core'; +import { Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { RadioCardInput } from 'ngx-cinlib/forms/radio-card'; +import { TranslationService } from 'ngx-cinlib/i18n'; +import { Maybe, NavigatorChoiceEntity } from 'src/app/core/api/generated/schema'; +import { navigatorFeatureKey } from 'src/app/core/constants/feature.constants'; +import { portalUrl } from 'src/app/core/constants/module.constants'; +import { navigatorStartRoute } from '../../../../constants/navigator-details.constant'; +import { NavigatorPortalDetailsLayoutActions } from '../../state/navigator-portal-details-layout.actions'; +import { selectNavigatorStateInputs } from '../../state/navigator-portal-details-layout.selectors'; + +@Component({ + selector: 'app-navigator-portal-details-layout-choice', + templateUrl: './navigator-portal-details-layout-choice.component.html', + styleUrls: ['./navigator-portal-details-layout-choice.component.scss'], +}) +export class NavigatorPortalDetailsLayoutChoiceComponent { + + @Input() + public choice?: Maybe; + + private inputs: RadioCardInput[] = []; + + public showDescription = false; + + constructor( + private router: Router, + private store: Store, + private translationService: TranslationService) { } + + public toNewPage(choice: Maybe){ + var choiceName: Maybe; + this.translationService.translatable(choice?.translatables, 'name').subscribe(name => choiceName = name); + + this.store.select(selectNavigatorStateInputs).subscribe(inputs => { + this.inputs = inputs.slice(0, (inputs.findIndex(input => input.value == (choice?.parent?.slug ?? '')) + 1)); + }); + + this.inputs = [...this.inputs, { + display: (this.inputs.length + 1).toString(), + label: choiceName ?? '', + value: choice?.nextPage?.slug, + }]; + + this.store.dispatch(NavigatorPortalDetailsLayoutActions + .setNavigatorState(this.inputs, this.inputs.length)); + + this.router.navigate([portalUrl, navigatorFeatureKey, navigatorStartRoute, choice?.nextPage?.slug]); + } +} \ No newline at end of file diff --git a/src/app/features/navigator/portal/details/modules/layout/components/navigator-portal-details-layout.component.html b/src/app/features/navigator/portal/details/modules/layout/components/navigator-portal-details-layout.component.html new file mode 100644 index 000000000..1bd020e9f --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/components/navigator-portal-details-layout.component.html @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/app/features/navigator/portal/details/modules/layout/components/navigator-portal-details-layout.component.scss b/src/app/features/navigator/portal/details/modules/layout/components/navigator-portal-details-layout.component.scss new file mode 100644 index 000000000..fb1d5aede --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/components/navigator-portal-details-layout.component.scss @@ -0,0 +1,22 @@ +:host { + display: flex; + flex-direction: column; + gap: 1rem; + align-items: center; + margin: var(--gap) auto; +} + +cin-radio-card-group { + max-width: calc(100% - var(--gap)); + margin: var(--gap) auto; +} + +::ng-deep cin-radio-card-group cin-radio-card { + margin: auto; +} + + +app-navigator-portal-details-layout-page { + width: 40rem; + max-width: calc(100% - var(--gap)); +} \ No newline at end of file diff --git a/src/app/features/navigator/portal/details/modules/layout/components/navigator-portal-details-layout.component.ts b/src/app/features/navigator/portal/details/modules/layout/components/navigator-portal-details-layout.component.ts new file mode 100644 index 000000000..611af5789 --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/components/navigator-portal-details-layout.component.ts @@ -0,0 +1,64 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { RadioCardInput } from 'ngx-cinlib/forms/radio-card'; +import { Subject, filter, switchMap } from 'rxjs'; +import { Maybe, NavigatorPageEntity } from 'src/app/core/api/generated/schema'; +import { navigatorFeatureKey } from 'src/app/core/constants/feature.constants'; +import { portalUrl } from 'src/app/core/constants/module.constants'; +import { slug } from 'src/app/core/constants/queryparam.constants'; +import { navigatorStartRoute } from '../../../constants/navigator-details.constant'; +import { NavigatorPortalDetailsLayoutActions } from '../state/navigator-portal-details-layout.actions'; +import { selectCurrentPage, selectNavigatorStateInputs } from '../state/navigator-portal-details-layout.selectors'; + +@Component({ + selector: 'app-navigator-portal-details-layout', + templateUrl: './navigator-portal-details-layout.component.html', + styleUrls: ['./navigator-portal-details-layout.component.scss'], +}) +export class NavigatorPortalDetailsLayoutComponent implements OnInit, OnDestroy { + + public currentPage?: Maybe; + + private destroy = new Subject(); + + public inputs: RadioCardInput[] = []; + + public initValue = ''; + + public showDescription: number | null = null; + + toggleDescription(index: number) { + this.showDescription = this.showDescription === index ? null : index; + } + + constructor( + private activatedRoute: ActivatedRoute, + private router: Router, + private store: Store) {} + + public ngOnInit(): void { + this.activatedRoute?.params.pipe( + switchMap(params => { + const action = params[slug] + ? NavigatorPortalDetailsLayoutActions.getPage(params[slug]) + : NavigatorPortalDetailsLayoutActions.getStartPage(); + this.store.dispatch(action); + return this.store.select(selectCurrentPage); + }), + filter(page => !!page), + ).subscribe(page => { + this.currentPage = page; + this.initValue = (page?.parentChoices?.length ?? 0) > 0 ? page?.slug! : ''}); + this.store.select(selectNavigatorStateInputs).subscribe(inputs => this.inputs = inputs); + } + + public route(route: string | null): void { + this.router.navigate([portalUrl, navigatorFeatureKey, navigatorStartRoute, route]); + } + + public ngOnDestroy(): void { + this.destroy.next(); + this.destroy.complete(); + } +} \ No newline at end of file diff --git a/src/app/features/navigator/portal/details/modules/layout/components/page/navigator-portal-details-layout-page.component.html b/src/app/features/navigator/portal/details/modules/layout/components/page/navigator-portal-details-layout-page.component.html new file mode 100644 index 000000000..312d827de --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/components/page/navigator-portal-details-layout-page.component.html @@ -0,0 +1,31 @@ + + + +@if (page?.choices){ +
+ @for (choice of page?.choices; track choice; let index = $index) { + + + } +
+} + +@if (page?.links){ + @for (link of page?.links; track link) { + + + } +} + +@if (page | translatable: 'additionalInformation' | async) { +
+ {{ (page | translatable: 'additionalInformation' | async) }} +
+} + + diff --git a/src/app/features/navigator/portal/details/modules/layout/components/page/navigator-portal-details-layout-page.component.scss b/src/app/features/navigator/portal/details/modules/layout/components/page/navigator-portal-details-layout-page.component.scss new file mode 100644 index 000000000..d2848bbd9 --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/components/page/navigator-portal-details-layout-page.component.scss @@ -0,0 +1,29 @@ +:host{ + display: flex; + gap: 3rem; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + + section { + display: flex; + gap: 1rem; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + span{ + width: 100% !important; + } + + app-navigator-portal-details-layout-choice { + width: 100%; + } + } + + a { + background-color: var(--color-primary-200); + } +} + diff --git a/src/app/features/navigator/portal/details/modules/layout/components/page/navigator-portal-details-layout-page.component.ts b/src/app/features/navigator/portal/details/modules/layout/components/page/navigator-portal-details-layout-page.component.ts new file mode 100644 index 000000000..c6b4f6ab4 --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/components/page/navigator-portal-details-layout-page.component.ts @@ -0,0 +1,17 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Maybe, NavigatorPageEntity } from 'src/app/core/api/generated/schema'; + +@Component({ + selector: 'app-navigator-portal-details-layout-page', + templateUrl: './navigator-portal-details-layout-page.component.html', + styleUrls: ['./navigator-portal-details-layout-page.component.scss'], +}) +export class NavigatorPortalDetailsLayoutPageComponent implements OnInit { + + @Input() + public page?: Maybe; + + constructor() { } + ngOnInit(): void { + } +} \ No newline at end of file diff --git a/src/app/features/navigator/portal/details/modules/layout/constants/navigator-portal-details-layout.constants.ts b/src/app/features/navigator/portal/details/modules/layout/constants/navigator-portal-details-layout.constants.ts new file mode 100644 index 000000000..066033273 --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/constants/navigator-portal-details-layout.constants.ts @@ -0,0 +1 @@ +export const navigatorPortalDetailsLayoutStateKey = 'navigatorPortalDetailsLayoutState'; \ No newline at end of file diff --git a/src/app/features/navigator/portal/details/modules/layout/navigator-guard/page-refresh-guard.service.ts b/src/app/features/navigator/portal/details/modules/layout/navigator-guard/page-refresh-guard.service.ts new file mode 100644 index 000000000..0321b6a0f --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/navigator-guard/page-refresh-guard.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { Observable, map, tap } from 'rxjs'; +import { navigatorFeatureKey } from 'src/app/core/constants/feature.constants'; +import { portalUrl } from 'src/app/core/constants/module.constants'; +import { navigatorStartRoute } from '../../../constants/navigator-details.constant'; +import { selectNavigatorStateInputs } from '../state/navigator-portal-details-layout.selectors'; + +//TODO: replace with function isAuthenticated in privileges.utils.ts +@Injectable({ + providedIn: 'root' +}) +export class NavigatorRefreshGuard { + + constructor(private store: Store, private router: Router) {} + + canActivate(): Observable { + return this.store.select(selectNavigatorStateInputs).pipe( + map(inputs => inputs.length > 1), + tap(canActivate => { + if (!canActivate) { + this.router.navigate([portalUrl, navigatorFeatureKey, navigatorStartRoute]); + } + }) + ); + } +} \ No newline at end of file diff --git a/src/app/features/navigator/portal/details/modules/layout/navigator-portal-details-layout.module.ts b/src/app/features/navigator/portal/details/modules/layout/navigator-portal-details-layout.module.ts new file mode 100644 index 000000000..9f3bee351 --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/navigator-portal-details-layout.module.ts @@ -0,0 +1,65 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { RouterModule } from '@angular/router'; +import { EffectsModule } from '@ngrx/effects'; +import { StoreModule } from '@ngrx/store'; +import { RadioCardGroupComponent } from 'ngx-cinlib/forms/radio-card'; +import { I18nDirective, TranslatablePipe } from 'ngx-cinlib/i18n'; +import { IconComponent } from 'ngx-cinlib/icons'; +import { DetailsTitleComponent } from 'ngx-cinlib/layouts/title'; +import { CoreModule } from 'src/app/core/core.module'; +import { GradientButtonComponent } from 'src/app/shared/widgets/gradient-button/gradient-button.component'; +import { NavigatorPortalDetailsLayoutChoiceComponent } from './components/choice/navigator-portal-details-layout-choice.component'; +import { NavigatorPortalDetailsLayoutComponent } from './components/navigator-portal-details-layout.component'; +import { NavigatorPortalDetailsLayoutPageComponent } from './components/page/navigator-portal-details-layout-page.component'; +import { navigatorPortalDetailsLayoutStateKey } from './constants/navigator-portal-details-layout.constants'; +import { NavigatorPortalDetailsLayoutEffects } from './state/navigator-portal-details-layout.effects'; +import { navigatorAdminDetailsLayoutReducer } from './state/navigator-portal-details-layout.reducer'; + +const components = [ + NavigatorPortalDetailsLayoutComponent, + NavigatorPortalDetailsLayoutPageComponent, + NavigatorPortalDetailsLayoutChoiceComponent, +] + +const framework = [ + CommonModule, + RouterModule, +]; + +const materials = [ + MatButtonModule, + MatCardModule, + MatExpansionModule +]; + +const modules = [ + CoreModule, +]; + +const libs = [ + StoreModule.forFeature(navigatorPortalDetailsLayoutStateKey, navigatorAdminDetailsLayoutReducer), + EffectsModule.forFeature([NavigatorPortalDetailsLayoutEffects]), + + GradientButtonComponent, + IconComponent, + I18nDirective, + DetailsTitleComponent, + RadioCardGroupComponent, + TranslatablePipe, +]; + +@NgModule({ + declarations: [...components], + imports: [ + ...framework, + ...libs, + ...materials, + ...modules, + ], + exports: [...components], +}) +export class NavigatorPortalDetailsLayoutModule { } diff --git a/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.actions.ts b/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.actions.ts new file mode 100644 index 000000000..9fda3d73b --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.actions.ts @@ -0,0 +1,16 @@ +import { createActionGroup, emptyProps } from '@ngrx/store'; +import { RadioCardInput } from 'ngx-cinlib/forms/radio-card'; +import { Maybe, NavigatorPageEntity } from 'src/app/core/api/generated/schema'; + +export const NavigatorPortalDetailsLayoutActions = createActionGroup({ + source: 'Navigator Portal Details Layout', + events: { + 'get start page': emptyProps(), + 'set start page': (startPage: Maybe) => ({ startPage }), + + 'get page': (slug: Maybe) => ({ slug }), + 'set page': (page: Maybe) => ({ page }), + + 'set navigator state': (inputs: RadioCardInput[], currentIndex: number) => ({ inputs, currentIndex }) + } +}); diff --git a/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.effects.ts b/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.effects.ts new file mode 100644 index 000000000..26f12a0ad --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.effects.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; +import { filter, map, switchMap } from 'rxjs'; +import { AdminActions } from 'src/app/admin/state/admin.actions'; +import { NavigatorPageEntity } from 'src/app/core/api/generated/schema'; +import { GetNavigatorPageGQL } from 'src/app/features/navigator/api/generated/get-navigator-page.query.generated'; +import { GetNavigatorStartPageGQL } from 'src/app/features/navigator/api/generated/get-navigator-start-page.query.generated'; +import { NavigatorPortalDetailsLayoutActions } from './navigator-portal-details-layout.actions'; + +@Injectable() +export class NavigatorPortalDetailsLayoutEffects { + + getStartPage = createEffect(() => this.actions.pipe( + ofType(NavigatorPortalDetailsLayoutActions.getStartPage), + switchMap( () => this.getNavigatorStartPageService.watch().valueChanges), + filter(response => !!response.data.getNavigatorStartPage?.id), + map(response => NavigatorPortalDetailsLayoutActions.setStartPage(response.data.getNavigatorStartPage as NavigatorPageEntity)) + )); + + getPage = createEffect(() => this.actions.pipe( + ofType(NavigatorPortalDetailsLayoutActions.getPage), + switchMap((action) => this.getNavigatorPageService.watch({ + entity: { + slug: action.slug + } + }).valueChanges), + map(response => response.data.getNavigatorPage?.id + ? NavigatorPortalDetailsLayoutActions.setPage(response.data.getNavigatorPage as NavigatorPageEntity) + : AdminActions.notFound()) + )); + + constructor( + private actions: Actions, + private getNavigatorStartPageService: GetNavigatorStartPageGQL, + private getNavigatorPageService: GetNavigatorPageGQL + + ) {} +} diff --git a/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.reducer.ts b/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.reducer.ts new file mode 100644 index 000000000..5f99db12c --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.reducer.ts @@ -0,0 +1,50 @@ +import { createReducer, on } from '@ngrx/store'; + +import { RadioCardInput } from 'ngx-cinlib/forms/radio-card'; +import { Maybe, NavigatorPageEntity } from 'src/app/core/api/generated/schema'; +import { NavigatorPortalDetailsLayoutActions } from './navigator-portal-details-layout.actions'; + +export interface NavigatorPortalDetailsLayoutState { + currentPage?: Maybe; + inputs: RadioCardInput[]; + currentIndex: number; +} + +export const initialState: NavigatorPortalDetailsLayoutState = { + inputs: [ + { + display: '1', + label: 'Start', + value: '' + } + ], + currentIndex: 0 +}; + +export const navigatorAdminDetailsLayoutReducer = createReducer( + initialState, + + on( + NavigatorPortalDetailsLayoutActions.setStartPage, + (state, action): NavigatorPortalDetailsLayoutState => ({ + ...state, currentPage: action.startPage + })), + + on( + NavigatorPortalDetailsLayoutActions.setPage, + (state, action): NavigatorPortalDetailsLayoutState => ({ + ...state, currentPage: action.page + })), + + on( + NavigatorPortalDetailsLayoutActions.setNavigatorState, + (state, action): NavigatorPortalDetailsLayoutState => ({ + ...state, inputs: action.inputs + })), + + on( + NavigatorPortalDetailsLayoutActions.setNavigatorState, + (state, action): NavigatorPortalDetailsLayoutState => ({ + ...state, currentIndex: action.currentIndex + })), +); diff --git a/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.selectors.ts b/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.selectors.ts new file mode 100644 index 000000000..a6e09457b --- /dev/null +++ b/src/app/features/navigator/portal/details/modules/layout/state/navigator-portal-details-layout.selectors.ts @@ -0,0 +1,20 @@ +import { createFeatureSelector, createSelector } from '@ngrx/store'; +import { navigatorPortalDetailsLayoutStateKey } from '../constants/navigator-portal-details-layout.constants'; +import { NavigatorPortalDetailsLayoutState } from './navigator-portal-details-layout.reducer'; + +export const selectNavigatorPortalDetailsLayoutState = createFeatureSelector(navigatorPortalDetailsLayoutStateKey); + +export const selectCurrentPage = createSelector( + selectNavigatorPortalDetailsLayoutState, + state => state.currentPage +); + +export const selectNavigatorStateInputs = createSelector( + selectNavigatorPortalDetailsLayoutState, + state => state.inputs +); + +export const selectNavigatorStateIndex = createSelector( + selectNavigatorPortalDetailsLayoutState, + state => state.currentIndex +); \ No newline at end of file diff --git a/src/app/features/navigator/portal/details/navigator-portal-details-routing.module.ts b/src/app/features/navigator/portal/details/navigator-portal-details-routing.module.ts new file mode 100644 index 000000000..56c2c6aa8 --- /dev/null +++ b/src/app/features/navigator/portal/details/navigator-portal-details-routing.module.ts @@ -0,0 +1,43 @@ + +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { slug } from 'src/app/core/constants/queryparam.constants'; +import { NavigatorRefreshGuard } from 'src/app/features/navigator/portal/details/modules/layout/navigator-guard/page-refresh-guard.service'; +import { navigatorResultRoute, navigatorStartRoute } from './constants/navigator-details.constant'; +import { NavigatorPortalDetailsLandingComponent } from './modules/landing/navigator-portal-details-landing.component'; +import { NavigatorPortalDetailsLayoutComponent } from './modules/layout/components/navigator-portal-details-layout.component'; + +const routes: Routes = [ + { + path: '', + loadChildren: () => import('./modules/landing/navigator-portal-details-landing.module') + .then((imported) => imported.NavigatorPortalDetailsLandingModule), + component: NavigatorPortalDetailsLandingComponent + }, + { + path: navigatorStartRoute, + loadChildren: () => import('./modules/layout/navigator-portal-details-layout.module') + .then((imported) => imported.NavigatorPortalDetailsLayoutModule), + component: NavigatorPortalDetailsLayoutComponent + }, + { + path: `${navigatorStartRoute}/:${slug}`, + loadChildren: () => import('./modules/layout/navigator-portal-details-layout.module') + .then((imported) => imported.NavigatorPortalDetailsLayoutModule), + component: NavigatorPortalDetailsLayoutComponent, + canActivate: [NavigatorRefreshGuard] + }, + { + path: `${navigatorResultRoute}/:${slug}`, + loadChildren: () => import('./modules/layout/navigator-portal-details-layout.module') + .then((imported) => imported.NavigatorPortalDetailsLayoutModule), + component: NavigatorPortalDetailsLayoutComponent, + canActivate: [NavigatorRefreshGuard] + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class NavigatorPortalDetailsRoutingModule { } diff --git a/src/app/features/navigator/portal/details/navigator-portal-details.module.ts b/src/app/features/navigator/portal/details/navigator-portal-details.module.ts new file mode 100644 index 000000000..606273425 --- /dev/null +++ b/src/app/features/navigator/portal/details/navigator-portal-details.module.ts @@ -0,0 +1,10 @@ +import { NgModule } from '@angular/core'; +import { NavigatorPortalDetailsRoutingModule } from './navigator-portal-details-routing.module'; + +const modules = [NavigatorPortalDetailsRoutingModule]; + +@NgModule({ + imports: [...modules], + exports: [], +}) +export class NavigatorPortalDetailsModule {} diff --git a/src/app/features/navigator/portal/navigator-portal-routing.module.ts b/src/app/features/navigator/portal/navigator-portal-routing.module.ts new file mode 100644 index 000000000..929c6642c --- /dev/null +++ b/src/app/features/navigator/portal/navigator-portal-routing.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { navigatorFeatureKey } from 'src/app/core/constants/feature.constants'; + +const routes: Routes = [ + // { + // path: navigatorFeatureKey, + // loadChildren: () => import('src/app/features/navigator/portal/details/navigator-portal-details.module') + // .then((imported) => imported.NavigatorPortalDetailsModule), + // }, + { + path: navigatorFeatureKey, + loadChildren: () => import('src/app/features/navigator/portal/details/navigator-portal-details.module') + .then((imported) => imported.NavigatorPortalDetailsModule), + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class NavigatorPortalRoutingModule { } diff --git a/src/app/portal/modules/embedding/components/hero/portal-page-embedding-hero.component.html b/src/app/portal/modules/embedding/components/hero/portal-page-embedding-hero.component.html index 6fe6a2989..93cfea9f0 100644 --- a/src/app/portal/modules/embedding/components/hero/portal-page-embedding-hero.component.html +++ b/src/app/portal/modules/embedding/components/hero/portal-page-embedding-hero.component.html @@ -11,12 +11,12 @@

@if (element?.url) { - - + + } diff --git a/src/app/portal/modules/embedding/components/hero/portal-page-embedding-hero.component.scss b/src/app/portal/modules/embedding/components/hero/portal-page-embedding-hero.component.scss index beb42e42b..2a28935b1 100644 --- a/src/app/portal/modules/embedding/components/hero/portal-page-embedding-hero.component.scss +++ b/src/app/portal/modules/embedding/components/hero/portal-page-embedding-hero.component.scss @@ -42,24 +42,8 @@ header { gap: var(--gap); } - a { - padding: 1.75rem; + app-gradient-button { width: fit-content; - color: var(--color-primary-contrast-900); - background-image: linear-gradient(45deg, - var(--color-primary-900), - var(--color-primary-700), - var(--color-primary-500), - var(--color-accent-500), - var(--color-accent-700), - var(--color-accent-900)); - background-size: 300%; - background-position: left; - transition: background-position .5s; - } - - a:hover { - background-position: right; } p { diff --git a/src/app/portal/modules/embedding/portal-page-embedding.module.ts b/src/app/portal/modules/embedding/portal-page-embedding.module.ts index 4c5f10fe1..3606bbdf6 100644 --- a/src/app/portal/modules/embedding/portal-page-embedding.module.ts +++ b/src/app/portal/modules/embedding/portal-page-embedding.module.ts @@ -18,6 +18,7 @@ import { MediaEmbeddingModule } from 'src/app/features/media/embedding/media-emb import { OrganisationEmbeddingModule } from 'src/app/features/organisation/embedding/organisation-embedding.module'; import { ReportEmbeddingModule } from 'src/app/features/report/embedding/report-embedding.module'; import { SurveyEmbeddingModule } from 'src/app/features/survey/embedding/survey-embedding.module'; +import { GradientButtonComponent } from 'src/app/shared/widgets/gradient-button/gradient-button.component'; import { PortalPageEmbeddingBannerComponent } from './components/banner/portal-page-embedding-banner.component'; import { PortalPageEmbeddingBoxComponent } from './components/box/portal-page-embedding-box.component'; import { PortalPageEmbeddingExpansionComponent } from './components/expansion/portal-page-embedding-expansion.component'; @@ -44,6 +45,7 @@ const framework = [ ]; const libs = [ + GradientButtonComponent, I18nDirective, MediaElementComponent, MediaSliderComponent, diff --git a/src/app/portal/portal.module.ts b/src/app/portal/portal.module.ts index b60a4a5f4..b3523dd49 100644 --- a/src/app/portal/portal.module.ts +++ b/src/app/portal/portal.module.ts @@ -14,6 +14,7 @@ import { EventPortalRoutingModule } from '../features/event/portal/event-portal- import { GuestArticlePortalRoutingModule } from '../features/guest-article/portal/guest-article-portal-routing.module'; import { MapPortalRoutingModule } from '../features/map/portal/map-portal-routing.module'; import { MediaPortalRoutingModule } from '../features/media/portal/media-portal-routing.module'; +import { NavigatorPortalRoutingModule } from '../features/navigator/portal/navigator-portal-routing.module'; import { OrganisationPortalRoutingModule } from '../features/organisation/portal/organisation-portal-routing.module'; import { ReportPortalRoutingModule } from '../features/report/portal/report-portal-routing.module'; import { SurveyPortalRoutingModule } from '../features/survey/portal/survey-portal-routing.module'; @@ -41,6 +42,7 @@ const routes = [ GuestArticlePortalRoutingModule, MapPortalRoutingModule, MediaPortalRoutingModule, + NavigatorPortalRoutingModule, OrganisationPortalRoutingModule, ReportPortalRoutingModule, SurveyPortalRoutingModule, diff --git a/src/app/shared/widgets/gradient-button/gradient-button.component.html b/src/app/shared/widgets/gradient-button/gradient-button.component.html new file mode 100644 index 000000000..1c31e3eff --- /dev/null +++ b/src/app/shared/widgets/gradient-button/gradient-button.component.html @@ -0,0 +1,32 @@ +@if (url) { + + {{ name }} + @if(description){ + + } + @if(icon) { } + +
+

{{ description }}

+
+} + +@if (!url) { + + {{ name }} + @if(description){ + + } + @if(icon) { } + + +
+

{{ description }}

+
+} diff --git a/src/app/shared/widgets/gradient-button/gradient-button.component.scss b/src/app/shared/widgets/gradient-button/gradient-button.component.scss new file mode 100644 index 000000000..d30588129 --- /dev/null +++ b/src/app/shared/widgets/gradient-button/gradient-button.component.scss @@ -0,0 +1,56 @@ +a { + display: flex; + justify-content: space-between; + width: 100%; + padding: 1.75rem; + background-image: linear-gradient(45deg, + var(--color-primary-900), + var(--color-primary-700), + var(--color-primary-500), + var(--color-accent-500), + var(--color-accent-700), + var(--color-accent-900)); + background-size: 300%; + background-position: left; + transition: background-position .5s; +} + +a:hover { + background-position: right; +} + +button { + background-color: transparent; + cursor: pointer; + border: none; + border-radius: 5rem; + padding: .75rem; +} + +button:hover { + background-color: var(--color-primary-500); +} + +cin-icon { + color: var(--color-primary-contrast-900); +} + +:host ::ng-deep { + .mdc-button__label { + color: var(--color-primary-contrast-900); + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + gap: .5rem; + } +} + +p { + padding: 1rem; + display: flex; + width: auto; + background-color: var(--color-primary-50); + border-radius: 0 0 var(--mdc-shape-small) var(--mdc-shape-small); + box-shadow: 0px 2px 8px 0px var(--color-box-shadow); +} \ No newline at end of file diff --git a/src/app/shared/widgets/gradient-button/gradient-button.component.ts b/src/app/shared/widgets/gradient-button/gradient-button.component.ts new file mode 100644 index 000000000..855c17e60 --- /dev/null +++ b/src/app/shared/widgets/gradient-button/gradient-button.component.ts @@ -0,0 +1,46 @@ +import { CommonModule } from '@angular/common'; +import { Component, Input } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { Maybe, collapse } from 'ngx-cinlib/core'; +import { I18nDirective } from 'ngx-cinlib/i18n'; +import { IconComponent, RegularIcon, SolidIcon } from 'ngx-cinlib/icons'; +import { CoreModule } from 'src/app/core/core.module'; +@Component({ + selector: 'app-gradient-button', + templateUrl: './gradient-button.component.html', + styleUrls: ['./gradient-button.component.scss'], + standalone: true, + imports: [ + CommonModule, + CoreModule, + I18nDirective, + MatButtonModule, + IconComponent + ], + animations:[ + collapse() + ] +}) +export class GradientButtonComponent { + + @Input() + public url?: Maybe; + + @Input() + public label?: Maybe; + + @Input() + public name?: Maybe; + + @Input() + public description?: Maybe; + + @Input() + public icon?: SolidIcon | RegularIcon; + + @Input() + public openNewTab = false; + + public showDescription = false; + +} \ No newline at end of file diff --git a/src/assets/in-progress.svg b/src/assets/in-progress.svg new file mode 100644 index 000000000..10ad4e81b --- /dev/null +++ b/src/assets/in-progress.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/navigator-choose.svg b/src/assets/navigator-choose.svg new file mode 100644 index 000000000..aef3a8b60 --- /dev/null +++ b/src/assets/navigator-choose.svg @@ -0,0 +1 @@ + \ No newline at end of file