mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-07 05:52:57 +00:00
feat: job portal
fix: disable function scoping lint rule fix: outdated contributing docs for adding SCThings
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
"unicorn/no-nested-ternary": "off",
|
||||
"unicorn/better-regex": "off",
|
||||
"unicorn/no-non-null-assertion": "off",
|
||||
"unicorn/consistent-function-scoping": ["error", {"checkArrowFunctions": false}],
|
||||
"jsdoc/no-types": "error",
|
||||
"jsdoc/require-param": "off",
|
||||
"jsdoc/require-param-description": "error",
|
||||
|
||||
@@ -129,7 +129,9 @@ describe('dashboard', async function () {
|
||||
fixture: 'search/types/message/single-message.json',
|
||||
}).as('search');
|
||||
|
||||
cy.get('stapps-news-section').contains('ion-item', 'Mehr Nachrichten').click();
|
||||
cy.get('stapps-news-section')
|
||||
.contains('ion-item', 'Mehr Nachrichten')
|
||||
.click({scrollBehavior: false, force: true});
|
||||
cy.url().should('include', '/news');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,6 +35,7 @@ const config: IconConfig = {
|
||||
'settings',
|
||||
'info',
|
||||
'rate_review',
|
||||
'work',
|
||||
],
|
||||
},
|
||||
codePoints: {
|
||||
|
||||
@@ -47,6 +47,7 @@ import {UtilModule} from './util/util.module';
|
||||
import {initLogger} from './_helpers/ts-logger';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {AboutModule} from './modules/about/about.module';
|
||||
import {JobModule} from './modules/jobs/jobs.module';
|
||||
import {FavoritesModule} from './modules/favorites/favorites.module';
|
||||
import {ProfilePageModule} from './modules/profile/profile.module';
|
||||
import {FeedbackModule} from './modules/feedback/feedback.module';
|
||||
@@ -147,6 +148,7 @@ export function createTranslateLoader(http: HttpClient) {
|
||||
HebisModule,
|
||||
IonicModule.forRoot(),
|
||||
IonIconModule,
|
||||
JobModule,
|
||||
FavoritesModule,
|
||||
LibraryModule,
|
||||
HttpClientModule,
|
||||
|
||||
@@ -48,11 +48,12 @@ export class AuthHelperService {
|
||||
private browser: SimpleBrowser,
|
||||
private alertController: AlertController,
|
||||
) {
|
||||
this.userConfigurationMap = (
|
||||
this.configProvider.getAnyValue('auth') as {
|
||||
default: SCAuthorizationProvider;
|
||||
}
|
||||
).default.endpoints.mapping;
|
||||
this.userConfigurationMap =
|
||||
(
|
||||
this.configProvider.getAnyValue('auth') as {
|
||||
default: SCAuthorizationProvider;
|
||||
}
|
||||
).default?.endpoints.mapping ?? {};
|
||||
}
|
||||
|
||||
public getAuthMessage(provider: SCAuthorizationProviderType, action: IAuthAction | IPAIAAuthAction) {
|
||||
|
||||
@@ -48,4 +48,5 @@
|
||||
<stapps-news-section></stapps-news-section>
|
||||
<stapps-mensa-section></stapps-mensa-section>
|
||||
<stapps-favorites-section></stapps-favorites-section>
|
||||
<stapps-job-section></stapps-job-section>
|
||||
</ion-content>
|
||||
|
||||
@@ -32,6 +32,8 @@ import {ThingTranslateModule} from '../../translation/thing-translate.module';
|
||||
import {UtilModule} from '../../util/util.module';
|
||||
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
|
||||
import {NewsModule} from '../news/news.module';
|
||||
import {JobSectionComponent} from './sections/jobs-section/job-section.component';
|
||||
import {JobModule} from '../jobs/jobs.module';
|
||||
|
||||
const catalogRoutes: Routes = [
|
||||
{
|
||||
@@ -51,6 +53,7 @@ const catalogRoutes: Routes = [
|
||||
MensaSectionContentComponent,
|
||||
FavoritesSectionComponent,
|
||||
DashboardComponent,
|
||||
JobSectionComponent,
|
||||
],
|
||||
imports: [
|
||||
IonicModule.forRoot(),
|
||||
@@ -65,6 +68,7 @@ const catalogRoutes: Routes = [
|
||||
ThingTranslateModule.forChild(),
|
||||
UtilModule,
|
||||
NewsModule,
|
||||
JobModule,
|
||||
],
|
||||
providers: [SettingsProvider, TranslatePipe],
|
||||
})
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<!--
|
||||
~ Copyright (C) 2023 StApps
|
||||
~ This program is free software: you can redistribute it and/or modify it
|
||||
~ under the terms of the GNU General Public License as published by the Free
|
||||
~ Software Foundation, version 3.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
~ more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along with
|
||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<stapps-section [title]="'dashboard.jobs.title' | translate">
|
||||
<ion-button slot="button-end" fill="clear" color="medium" [routerLink]="['/jobs']">
|
||||
<ion-icon slot="icon-only" name="search" size="24"></ion-icon>
|
||||
</ion-button>
|
||||
<simple-swiper *ngIf="jobs | async as jobs; else noItems" @fade>
|
||||
<stapps-data-list-item
|
||||
*ngFor="let item of jobs"
|
||||
[hideThumbnail]="true"
|
||||
[item]="item"
|
||||
appearance="square"
|
||||
></stapps-data-list-item>
|
||||
<ion-item [routerLink]="['/jobs']" class="more-jobs" lines="none">
|
||||
<ion-label>{{ 'dashboard.jobs.title' | translate | titlecase }}</ion-label>
|
||||
<ion-icon color="medium" name="read_more" size="40"></ion-icon>
|
||||
</ion-item>
|
||||
</simple-swiper>
|
||||
<ng-template #noItems>
|
||||
<ion-item class="nothing-selected" lines="none">
|
||||
<ion-label class="ion-text-wrap">
|
||||
{{ 'dashboard.jobs.noJobs' | translate }}
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-button slot="button-end" fill="clear" color="medium" [routerLink]="['/jobs']">
|
||||
<ion-icon slot="icon-only" name="search" size="24"></ion-icon>
|
||||
</ion-button>
|
||||
</ng-template>
|
||||
</stapps-section>
|
||||
@@ -0,0 +1,48 @@
|
||||
/*!
|
||||
* Copyright (C) 2023 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.nothing-selected::part(native) {
|
||||
color: var(--ion-color-medium-shade);
|
||||
background: none;
|
||||
}
|
||||
|
||||
simple-swiper {
|
||||
--swiper-slide-width: 280px;
|
||||
}
|
||||
|
||||
.more-jobs {
|
||||
--color: var(--ion-color-medium-tint);
|
||||
|
||||
font-size: var(--font-size-xl);
|
||||
|
||||
&::part(native) {
|
||||
height: 100%;
|
||||
background: none;
|
||||
border-radius: var(--border-radius-default);
|
||||
}
|
||||
|
||||
ion-label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
ion-icon {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2023 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
|
||||
import {SCSearchResult, SCThingType} from '@openstapps/core';
|
||||
import {DataProvider} from 'src/app/modules/data/data.provider';
|
||||
import {fadeAnimation} from '../../fade.animation';
|
||||
|
||||
/**
|
||||
* Shows a section with meals of the chosen mensa
|
||||
*/
|
||||
@Component({
|
||||
selector: 'stapps-job-section',
|
||||
templateUrl: 'job-section.component.html',
|
||||
styleUrls: ['job-section.component.scss'],
|
||||
animations: [fadeAnimation],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class JobSectionComponent {
|
||||
jobs = inject(DataProvider)
|
||||
.search({
|
||||
filter: {type: 'value', arguments: {field: 'type', value: SCThingType.JobPosting}},
|
||||
size: 5,
|
||||
from: 0,
|
||||
})
|
||||
.then((result: SCSearchResult) => result.data);
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {SCDateSeries, SCThings, SCThingType} from '@openstapps/core';
|
||||
import {SCDateSeries, SCThingType, SCThings} from '@openstapps/core';
|
||||
|
||||
/**
|
||||
* Shows a horizontal list of action chips
|
||||
@@ -37,12 +37,20 @@ export class ActionChipListComponent {
|
||||
@Input() set item(item: SCThings) {
|
||||
this._item = item;
|
||||
|
||||
const isInPlace = 'inPlace' in item && !!item.inPlace && 'geo' in item.inPlace;
|
||||
const hasDirectGeo = 'geo' in item;
|
||||
const maybeCoords = isInPlace
|
||||
? item?.inPlace?.geo.point.coordinates
|
||||
: hasDirectGeo
|
||||
? item.geo.point.coordinates
|
||||
: undefined;
|
||||
const isNullIsland = maybeCoords ? maybeCoords[0] === 0 && maybeCoords[1] === 0 : false;
|
||||
this.applicable = {
|
||||
locate: false, // TODO: reimplement this at a later date
|
||||
event:
|
||||
item.type === SCThingType.AcademicEvent ||
|
||||
(item.type === SCThingType.DateSeries && (item as SCDateSeries).dates.length > 0),
|
||||
navigate: ('inPlace' in item && item.inPlace && 'geo' in item.inPlace) || 'geo' in item,
|
||||
navigate: (hasDirectGeo || isInPlace) && !isNullIsland,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -46,4 +46,5 @@ export const DataIcons: Record<SCThingType, string> = {
|
||||
'tour': SCIcon`tour`,
|
||||
'video': SCIcon`movie`,
|
||||
'diff': SCIcon`difference`,
|
||||
'job posting': SCIcon`work`,
|
||||
};
|
||||
|
||||
@@ -17,93 +17,95 @@ import {CommonModule} from '@angular/common';
|
||||
import {HttpClientModule} from '@angular/common/http';
|
||||
import {NgModule} from '@angular/core';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {LeafletModule} from '@asymmetrik/ngx-leaflet';
|
||||
import {IonicModule, Platform} from '@ionic/angular';
|
||||
import {TranslateModule} from '@ngx-translate/core';
|
||||
import {MarkdownModule} from 'ngx-markdown';
|
||||
import {MomentModule} from 'ngx-moment';
|
||||
import {ThingTranslateModule} from '../../translation/thing-translate.module';
|
||||
import {MenuModule} from '../menu/menu.module';
|
||||
import {SimpleBrowser, browserFactory} from '../../util/browser.factory';
|
||||
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
|
||||
import {RoutingStackService} from '../../util/routing-stack.service';
|
||||
import {UtilModule} from '../../util/util.module';
|
||||
import {CalendarService} from '../calendar/calendar.service';
|
||||
import {ScheduleProvider} from '../calendar/schedule.provider';
|
||||
import {GeoNavigationDirective} from '../map/geo-navigation.directive';
|
||||
import {MapWidgetComponent} from '../map/widget/map-widget.component';
|
||||
import {MenuModule} from '../menu/menu.module';
|
||||
import {SettingsProvider} from '../settings/settings.provider';
|
||||
import {StorageModule} from '../storage/storage.module';
|
||||
import {ActionChipListComponent} from './chips/action-chip-list.component';
|
||||
import {EditEventSelectionComponent} from './chips/edit-event-selection.component';
|
||||
import {AddEventActionChipComponent} from './chips/data/add-event-action-chip.component';
|
||||
import {LocateActionChipComponent} from './chips/data/locate-action-chip.component';
|
||||
import {NavigateActionChipComponent} from './chips/data/navigate-action-chip.component';
|
||||
import {EditEventSelectionComponent} from './chips/edit-event-selection.component';
|
||||
import {CoordinatedSearchProvider} from './coordinated-search.provider';
|
||||
import {DataFacetsProvider} from './data-facets.provider';
|
||||
import {DataIconPipe} from './data-icon.pipe';
|
||||
import {DataRoutingModule} from './data-routing.module';
|
||||
import {DataProvider} from './data.provider';
|
||||
import {DataDetailContentComponent} from './detail/data-detail-content.component';
|
||||
import {DataDetailComponent} from './detail/data-detail.component';
|
||||
import {DataPathComponent} from './detail/data-path.component';
|
||||
import {AddressDetailComponent} from './elements/address-detail.component';
|
||||
import {CertificationsInDetailComponent} from './elements/certifications-in-detail.component';
|
||||
import {ExternalLinkComponent} from './elements/external-link.component';
|
||||
import {FavoriteButtonComponent} from './elements/favorite-button.component';
|
||||
import {LongInlineTextComponent} from './elements/long-inline-text.component';
|
||||
import {OffersDetailComponent} from './elements/offers-detail.component';
|
||||
import {OffersInListComponent} from './elements/offers-in-list.component';
|
||||
import {OriginDetailComponent} from './elements/origin-detail.component';
|
||||
import {OriginInListComponent} from './elements/origin-in-list.component';
|
||||
import {StappsRatingComponent} from './elements/rating.component';
|
||||
import {SimpleCardComponent} from './elements/simple-card.component';
|
||||
import {SkeletonListItemComponent} from './elements/skeleton-list-item.component';
|
||||
import {SkeletonSegmentComponent} from './elements/skeleton-segment-button.component';
|
||||
import {SkeletonSimpleCardComponent} from './elements/skeleton-simple-card.component';
|
||||
import {TitleCardComponent} from './elements/title-card.component';
|
||||
import {DataListItemHostDefaultComponent} from './list/data-list-item-host-default.component';
|
||||
import {DataListItemHostDirective} from './list/data-list-item-host.directive';
|
||||
import {DataListItemComponent} from './list/data-list-item.component';
|
||||
import {DataListComponent} from './list/data-list.component';
|
||||
import {FoodDataListComponent} from './list/food-data-list.component';
|
||||
import {SearchPageComponent} from './list/search-page.component';
|
||||
import {SimpleDataListComponent} from './list/simple-data-list.component';
|
||||
import {SkeletonListComponent} from './list/skeleton-list.component';
|
||||
import {TreeListFragmentComponent} from './list/tree-list-fragment.component';
|
||||
import {TreeListComponent} from './list/tree-list.component';
|
||||
import {StAppsWebHttpClient} from './stapps-web-http-client.provider';
|
||||
import {ArticleContentComponent} from './types/article/article-content.component';
|
||||
import {ArticleListItemComponent} from './types/article/article-item.component';
|
||||
import {BookDetailContentComponent} from './types/book/book-detail-content.component';
|
||||
import {BookListItemComponent} from './types/book/book-list-item.component';
|
||||
import {CatalogDetailContentComponent} from './types/catalog/catalog-detail-content.component';
|
||||
import {CatalogListItemComponent} from './types/catalog/catalog-list-item.component';
|
||||
import {DateSeriesDetailContentComponent} from './types/date-series/date-series-detail-content.component';
|
||||
import {DateSeriesListItemComponent} from './types/date-series/date-series-list-item.component';
|
||||
import {DishCharacteristicsComponent} from './types/dish/dish-characteristics.component';
|
||||
import {DishDetailContentComponent} from './types/dish/dish-detail-content.component';
|
||||
import {DishListItemComponent} from './types/dish/dish-list-item.component';
|
||||
import {EventDetailContentComponent} from './types/event/event-detail-content.component';
|
||||
import {EventListItemComponent} from './types/event/event-list-item.component';
|
||||
import {EventRoutePathComponent} from './types/event/event-route-path.component';
|
||||
import {FavoriteDetailContentComponent} from './types/favorite/favorite-detail-content.component';
|
||||
import {FavoriteListItemComponent} from './types/favorite/favorite-list-item.component';
|
||||
import {JobPostingDetailContentComponent} from './types/job-posting/job-posting-detail-content.component';
|
||||
import {JobPostingListItemComponent} from './types/job-posting/job-posting-list-item.component';
|
||||
import {MessageDetailContentComponent} from './types/message/message-detail-content.component';
|
||||
import {MessageListItemComponent} from './types/message/message-list-item.component';
|
||||
import {OrganizationDetailContentComponent} from './types/organization/organization-detail-content.component';
|
||||
import {OrganizationListItemComponent} from './types/organization/organization-list-item.component';
|
||||
import {PeriodicalDetailContentComponent} from './types/periodical/periodical-detail-content.component';
|
||||
import {PeriodicalListItemComponent} from './types/periodical/periodical-list-item.component';
|
||||
import {PersonDetailContentComponent} from './types/person/person-detail-content.component';
|
||||
import {PersonListItemComponent} from './types/person/person-list-item.component';
|
||||
import {PlaceDetailContentComponent} from './types/place/place-detail-content.component';
|
||||
import {PlaceListItemComponent} from './types/place/place-list-item.component';
|
||||
import {PlaceMensaDetailComponent} from './types/place/special/mensa/place-mensa-detail.component';
|
||||
import {SemesterDetailContentComponent} from './types/semester/semester-detail-content.component';
|
||||
import {MapWidgetComponent} from '../map/widget/map-widget.component';
|
||||
import {LeafletModule} from '@asymmetrik/ngx-leaflet';
|
||||
import {SkeletonSimpleCardComponent} from './elements/skeleton-simple-card.component';
|
||||
import {CatalogListItemComponent} from './types/catalog/catalog-list-item.component';
|
||||
import {DataListItemComponent} from './list/data-list-item.component';
|
||||
import {DateSeriesListItemComponent} from './types/date-series/date-series-list-item.component';
|
||||
import {DishListItemComponent} from './types/dish/dish-list-item.component';
|
||||
import {FavoriteListItemComponent} from './types/favorite/favorite-list-item.component';
|
||||
import {LongInlineTextComponent} from './elements/long-inline-text.component';
|
||||
import {MessageListItemComponent} from './types/message/message-list-item.component';
|
||||
import {OrganizationListItemComponent} from './types/organization/organization-list-item.component';
|
||||
import {PersonListItemComponent} from './types/person/person-list-item.component';
|
||||
import {SkeletonListItemComponent} from './elements/skeleton-list-item.component';
|
||||
import {SkeletonSegmentComponent} from './elements/skeleton-segment-button.component';
|
||||
import {VideoDetailContentComponent} from './types/video/video-detail-content.component';
|
||||
import {SemesterListItemComponent} from './types/semester/semester-list-item.component';
|
||||
import {VideoDetailContentComponent} from './types/video/video-detail-content.component';
|
||||
import {VideoListItemComponent} from './types/video/video-list-item.component';
|
||||
import {OriginInListComponent} from './elements/origin-in-list.component';
|
||||
import {CoordinatedSearchProvider} from './coordinated-search.provider';
|
||||
import {FavoriteButtonComponent} from './elements/favorite-button.component';
|
||||
import {SimpleDataListComponent} from './list/simple-data-list.component';
|
||||
import {TitleCardComponent} from './elements/title-card.component';
|
||||
import {CalendarService} from '../calendar/calendar.service';
|
||||
import {RoutingStackService} from '../../util/routing-stack.service';
|
||||
import {DataPathComponent} from './detail/data-path.component';
|
||||
import {EventRoutePathComponent} from './types/event/event-route-path.component';
|
||||
import {UtilModule} from '../../util/util.module';
|
||||
import {TreeListComponent} from './list/tree-list.component';
|
||||
import {TreeListFragmentComponent} from './list/tree-list-fragment.component';
|
||||
import {SettingsProvider} from '../settings/settings.provider';
|
||||
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
|
||||
import {ExternalLinkComponent} from './elements/external-link.component';
|
||||
import {ArticleListItemComponent} from './types/article/article-item.component';
|
||||
import {ArticleContentComponent} from './types/article/article-content.component';
|
||||
import {BookDetailContentComponent} from './types/book/book-detail-content.component';
|
||||
import {BookListItemComponent} from './types/book/book-list-item.component';
|
||||
import {PeriodicalListItemComponent} from './types/periodical/periodical-list-item.component';
|
||||
import {PeriodicalDetailContentComponent} from './types/periodical/periodical-detail-content.component';
|
||||
import {DataListItemHostDirective} from './list/data-list-item-host.directive';
|
||||
import {DataListItemHostDefaultComponent} from './list/data-list-item-host-default.component';
|
||||
import {browserFactory, SimpleBrowser} from '../../util/browser.factory';
|
||||
import {StappsRatingComponent} from './elements/rating.component';
|
||||
import {DishCharacteristicsComponent} from './types/dish/dish-characteristics.component';
|
||||
import {SkeletonListComponent} from './list/skeleton-list.component';
|
||||
import {CertificationsInDetailComponent} from './elements/certifications-in-detail.component';
|
||||
import {GeoNavigationDirective} from '../map/geo-navigation.directive';
|
||||
import {NavigateActionChipComponent} from './chips/data/navigate-action-chip.component';
|
||||
|
||||
/**
|
||||
* Module for handling data
|
||||
@@ -142,6 +144,8 @@ import {NavigateActionChipComponent} from './chips/data/navigate-action-chip.com
|
||||
MapWidgetComponent,
|
||||
MessageDetailContentComponent,
|
||||
MessageListItemComponent,
|
||||
JobPostingDetailContentComponent,
|
||||
JobPostingListItemComponent,
|
||||
OffersDetailComponent,
|
||||
OffersInListComponent,
|
||||
OrganizationDetailContentComponent,
|
||||
|
||||
@@ -58,6 +58,10 @@
|
||||
[item]="$any(item)"
|
||||
*ngSwitchCase="'message'"
|
||||
></stapps-message-detail-content>
|
||||
<stapps-job-posting-detail-content
|
||||
[item]="$any(item)"
|
||||
*ngSwitchCase="'job posting'"
|
||||
></stapps-job-posting-detail-content>
|
||||
<stapps-person-detail-content [item]="$any(item)" *ngSwitchCase="'person'"></stapps-person-detail-content>
|
||||
<stapps-place-detail-content [item]="$any(item)" *ngSwitchCase="'building'"></stapps-place-detail-content>
|
||||
<stapps-place-detail-content [item]="$any(item)" *ngSwitchCase="'floor'"></stapps-place-detail-content>
|
||||
|
||||
@@ -30,15 +30,17 @@
|
||||
<div *ngIf="$any(item).openingHours" class="opening-hours">
|
||||
<stapps-opening-hours [openingHours]="item.openingHours"></stapps-opening-hours>
|
||||
</div>
|
||||
<div *ngIf="item.description" class="description">
|
||||
<!-- TODO obviously this is bad style. Tbd where to put the differentiation. Job Postings always have a description, but it's going to be shown in `stapps-job-posting-detail-content` anyways, no need to repeat here. For this view, I would use other fields of the schema.org JobPosting like the `ThingWithCategory.category` -->
|
||||
<div *ngIf="item.description && item.type !== 'job posting'" class="description">
|
||||
<div class="text-accordion" [style.-webkit-line-clamp]="descriptionLinesToDisplay" #accordionTextArea>
|
||||
{{ 'description' | thingTranslate : item }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- TODO see above -->
|
||||
<ion-button
|
||||
expand="full"
|
||||
fill="clear"
|
||||
*ngIf="item.description && buttonShown"
|
||||
*ngIf="item.description && item.type !== 'job posting' && buttonShown"
|
||||
(click)="toggleDescriptionAccordion()"
|
||||
>
|
||||
<ion-icon [name]="buttonState" size="large"></ion-icon>
|
||||
|
||||
@@ -29,6 +29,7 @@ import {PeriodicalListItemComponent} from '../types/periodical/periodical-list-i
|
||||
import {DataListItemHostDefaultComponent} from './data-list-item-host-default.component';
|
||||
import {ArticleListItemComponent} from '../types/article/article-item.component';
|
||||
import {DishListItemComponent} from '../types/dish/dish-list-item.component';
|
||||
import {JobPostingListItemComponent} from '../types/job-posting/job-posting-list-item.component';
|
||||
|
||||
export interface DataListItem {
|
||||
item: SCThings;
|
||||
@@ -53,6 +54,7 @@ const DataListItemIndex: Partial<Record<SCThingType, Type<DataListItem>>> = {
|
||||
[SCThingType.Periodical]: PeriodicalListItemComponent,
|
||||
[SCThingType.Book]: BookListItemComponent,
|
||||
[SCThingType.Article]: ArticleListItemComponent,
|
||||
[SCThingType.JobPosting]: JobPostingListItemComponent,
|
||||
};
|
||||
|
||||
@Directive({
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {SCJobPosting} from '@openstapps/core';
|
||||
|
||||
@Component({
|
||||
selector: 'stapps-job-posting-detail-content',
|
||||
templateUrl: 'job-posting-detail-content.html',
|
||||
styleUrls: ['job-posting-detail-content.scss'],
|
||||
})
|
||||
export class JobPostingDetailContentComponent {
|
||||
@Input() item: SCJobPosting;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<!--
|
||||
~ Copyright (C) 2023 StApps
|
||||
~ This program is free software: you can redistribute it and/or modify it
|
||||
~ under the terms of the GNU General Public License as published by the Free
|
||||
~ Software Foundation, version 3.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
~ more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along with
|
||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<ion-card>
|
||||
<ion-card-content [innerHtml]="item.description"> </ion-card-content>
|
||||
</ion-card>
|
||||
<ion-card *ngIf="item.sameAs">
|
||||
<ion-card-header> {{ 'sameAs' | propertyNameTranslate : item | titlecase }} </ion-card-header>
|
||||
<ion-card-content>
|
||||
<stapps-external-link [link]="item.sameAs" [text]="item.name"></stapps-external-link>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
|
||||
<ion-card *ngIf="item.employerOverview">
|
||||
<ion-card-header> {{ 'jobs.employer' | translate }} </ion-card-header>
|
||||
<ion-card-content>
|
||||
<stapps-external-link
|
||||
*ngIf="item.employerOverview.sameAs"
|
||||
[link]="item.employerOverview.sameAs"
|
||||
[text]="item.employerOverview.name"
|
||||
></stapps-external-link>
|
||||
<p *ngIf="!item.employerOverview.sameAs">{{ item.employerOverview.name }}</p>
|
||||
<ion-img
|
||||
*ngIf="item.employerOverview.image"
|
||||
class="company-image"
|
||||
src="{{ item.employerOverview.image }}"
|
||||
></ion-img>
|
||||
<p [innerHtml]="item.employerOverview.description"></p>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
@@ -0,0 +1,6 @@
|
||||
.company-image {
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
margin: var(--spacing-md) 0 var(--spacing-md) 0;
|
||||
object-position: left;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {SCJobPosting} from '@openstapps/core';
|
||||
import {DataListItemComponent} from '../../list/data-list-item.component';
|
||||
|
||||
@Component({
|
||||
selector: 'stapps-job-posting-list-item',
|
||||
templateUrl: 'job-posting-list-item.html',
|
||||
styleUrls: ['job-posting-list-item.scss'],
|
||||
})
|
||||
export class JobPostingListItemComponent extends DataListItemComponent {
|
||||
@Input() item: SCJobPosting;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
~ Copyright (C) 2022 StApps
|
||||
~ This program is free software: you can redistribute it and/or modify it
|
||||
~ under the terms of the GNU General Public License as published by the Free
|
||||
~ Software Foundation, version 3.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
~ more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along with
|
||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-label class="title">{{ 'name' | thingTranslate: item }}</ion-label>
|
||||
<ion-label class="title-sub categories">
|
||||
{{ 'categories' | thingTranslate: item | join: ', ' | titlecase }}
|
||||
</ion-label>
|
||||
<ion-label class="employer">{{ item.employerOverview?.name }}</ion-label>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
@@ -0,0 +1,13 @@
|
||||
// since we have three lines of information, clamp harder than usual
|
||||
ion-col ion-label {
|
||||
-webkit-line-clamp: 2;
|
||||
|
||||
&.title-sub,
|
||||
&.employer {
|
||||
-webkit-line-clamp: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
ion-label.categories {
|
||||
color: var(--ion-color-medium);
|
||||
}
|
||||
31
frontend/app/src/app/modules/jobs/jobs.module.ts
Normal file
31
frontend/app/src/app/modules/jobs/jobs.module.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {IonicModule} from '@ionic/angular';
|
||||
import {TranslateModule} from '@ngx-translate/core';
|
||||
import {MomentModule} from 'ngx-moment';
|
||||
import {DataModule} from '../data/data.module';
|
||||
import {UtilModule} from '../../util/util.module';
|
||||
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
|
||||
import {ConfigProvider} from '../config/config.provider';
|
||||
import {ThingTranslateModule} from '../../translation/thing-translate.module';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {JobsPageComponent} from './page/jobs-page.component';
|
||||
|
||||
const jobsRoutes: Routes = [{path: 'jobs', component: JobsPageComponent}];
|
||||
|
||||
@NgModule({
|
||||
declarations: [JobsPageComponent],
|
||||
imports: [
|
||||
IonicModule.forRoot(),
|
||||
ThingTranslateModule.forChild(),
|
||||
TranslateModule.forChild(),
|
||||
RouterModule.forChild(jobsRoutes),
|
||||
IonIconModule,
|
||||
CommonModule,
|
||||
MomentModule,
|
||||
DataModule,
|
||||
UtilModule,
|
||||
],
|
||||
providers: [ConfigProvider],
|
||||
})
|
||||
export class JobModule {}
|
||||
@@ -0,0 +1,17 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {SCSearchFilter, SCThingType} from '@openstapps/core';
|
||||
|
||||
@Component({
|
||||
selector: 'stapps-jobs-page',
|
||||
templateUrl: 'jobs-page.html',
|
||||
styleUrls: ['jobs-page.scss'],
|
||||
})
|
||||
export class JobsPageComponent {
|
||||
forcedFilter: SCSearchFilter = {
|
||||
type: 'value',
|
||||
arguments: {
|
||||
field: 'type',
|
||||
value: SCThingType.JobPosting,
|
||||
},
|
||||
};
|
||||
}
|
||||
7
frontend/app/src/app/modules/jobs/page/jobs-page.html
Normal file
7
frontend/app/src/app/modules/jobs/page/jobs-page.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<stapps-search-page
|
||||
[title]="'jobs.title' | translate"
|
||||
[placeholder]="'jobs.placeholder' | translate"
|
||||
[showDefaultData]="true"
|
||||
[forcedFilter]="forcedFilter"
|
||||
[backUrl]="'/'"
|
||||
></stapps-search-page>
|
||||
@@ -20,7 +20,7 @@
|
||||
</a>
|
||||
|
||||
<ng-template #titleTemplate>
|
||||
<ion-label class="section-headline">{{ title }} </ion-label>
|
||||
<ion-label class="section-headline">{{ title }}</ion-label>
|
||||
<ng-content select="[slot=subtitle]"></ng-content>
|
||||
</ng-template>
|
||||
</ion-col>
|
||||
|
||||
@@ -98,6 +98,10 @@
|
||||
"title": "Aktuelles",
|
||||
"moreNews": "Mehr Nachrichten"
|
||||
},
|
||||
"jobs": {
|
||||
"title": "Jobangebote",
|
||||
"noJobs": "Es sind momentan keine Jobangebote verfügbar."
|
||||
},
|
||||
"schedule": {
|
||||
"title": "Nächste Einheit",
|
||||
"noEvent": "Kein Eintrag gefunden",
|
||||
@@ -390,6 +394,11 @@
|
||||
"news": {
|
||||
"title": "Aktuelles"
|
||||
},
|
||||
"jobs": {
|
||||
"title": "Jobangebote",
|
||||
"placeholder": "Jobangebote",
|
||||
"employer": "Arbeitgeber"
|
||||
},
|
||||
"canteens": {
|
||||
"title": "Mensa"
|
||||
},
|
||||
|
||||
@@ -98,6 +98,10 @@
|
||||
"title": "News",
|
||||
"moreNews": "More News"
|
||||
},
|
||||
"jobs": {
|
||||
"title": "Job postings",
|
||||
"noJobs": "At the moment, there are not job postings available."
|
||||
},
|
||||
"schedule": {
|
||||
"title": "Next Unit",
|
||||
"noEvent": "No entry found",
|
||||
@@ -390,6 +394,11 @@
|
||||
"news": {
|
||||
"title": "News"
|
||||
},
|
||||
"jobs": {
|
||||
"title": "Job postings",
|
||||
"placeholder": "Job Postings",
|
||||
"employer": "Employer"
|
||||
},
|
||||
"canteens": {
|
||||
"title": "Canteens"
|
||||
},
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user